Clean up gdtoa code

This commit is contained in:
Justine Tunney 2021-08-19 06:07:37 -07:00
parent 7341336b1a
commit da45c7c80b
48 changed files with 2808 additions and 4721 deletions

View file

@ -22,13 +22,6 @@
#include "libc/x/x.h" #include "libc/x/x.h"
#include "third_party/gdtoa/gdtoa.h" #include "third_party/gdtoa/gdtoa.h"
TEST(strtod, testNearest) {
EXPECT_STREQ("-1.79769313486231e+308",
gc(xasprintf("%.15g", strtod("-1.79769313486231e+308", NULL))));
}
#if 0 /* TODO(jart): Why doesn't this work on Travis CI? */
int oldround; int oldround;
void SetUp(void) { void SetUp(void) {
@ -68,5 +61,3 @@ TEST(strtod, testTowardzero) {
free(p); free(p);
} }
} }
#endif

View file

@ -1,112 +1,81 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#ifndef MULTIPLE_THREADS
char *dtoa_result;
#endif
char * char *
rv_alloc(int i MTd) rv_alloc(int i)
{ {
int j, k, *r; int j, k, *r;
j = sizeof(ULong); j = sizeof(ULong);
for(k = 0; for(k = 0;
(int)(sizeof(Bigint) - sizeof(ULong) - sizeof(int)) + j <= i; (int)(sizeof(Bigint) - sizeof(ULong) - sizeof(int)) + j <= i;
j <<= 1) j <<= 1)
k++; k++;
r = (int*)Balloc(k MTa); r = (int*)Balloc(k);
*r = k; *r = k;
return return (char *)(r+1);
#ifndef MULTIPLE_THREADS }
dtoa_result =
#endif
(char *)(r+1);
}
char * char *
nrv_alloc(char *s, char **rve, int n MTd) nrv_alloc(char *s, char **rve, int n)
{ {
char *rv, *t; char *rv, *t;
t = rv = rv_alloc(n);
t = rv = rv_alloc(n MTa);
while((*t = *s++) !=0) while((*t = *s++) !=0)
t++; t++;
if (rve) if (rve)
*rve = t; *rve = t;
return rv; return rv;
} }
/* freedtoa(s) must be used to free values s returned by dtoa
* when MULTIPLE_THREADS is #defined. It should be used in all cases,
* but for consistency with earlier versions of dtoa, it is optional
* when MULTIPLE_THREADS is not defined.
*/
void void
freedtoa(char *s) freedtoa(char *s)
{ {
#ifdef MULTIPLE_THREADS
ThInfo *TI = 0;
#endif
Bigint *b = (Bigint *)((int *)s - 1); Bigint *b = (Bigint *)((int *)s - 1);
b->maxwds = 1 << (b->k = *(int*)b); b->maxwds = 1 << (b->k = *(int*)b);
Bfree(b MTb); Bfree(b);
#ifndef MULTIPLE_THREADS }
if (s == dtoa_result)
dtoa_result = 0;
#endif
}
int int
quorem(Bigint *b, Bigint *S) quorem(Bigint *b, Bigint *S)
{ {
int n; int n;
ULong *bx, *bxe, q, *sx, *sxe; ULong *bx, *bxe, q, *sx, *sxe;
#ifdef ULLong
ULLong borrow, carry, y, ys; ULLong borrow, carry, y, ys;
#else
ULong borrow, carry, y, ys;
#ifdef Pack_32
ULong si, z, zs;
#endif
#endif
n = S->wds; n = S->wds;
#ifdef DEBUG #ifdef DEBUG
/*debug*/ if (b->wds > n) if (b->wds > n)
/*debug*/ Bug("oversize b in quorem"); Bug("oversize b in quorem");
#endif #endif
if (b->wds < n) if (b->wds < n)
return 0; return 0;
@ -116,47 +85,27 @@ quorem(Bigint *b, Bigint *S)
bxe = bx + n; bxe = bx + n;
q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
#ifdef DEBUG #ifdef DEBUG
/*debug*/ if (q > 9) if (q > 9)
/*debug*/ Bug("oversized quotient in quorem"); Bug("oversized quotient in quorem");
#endif #endif
if (q) { if (q) {
borrow = 0; borrow = 0;
carry = 0; carry = 0;
do { do {
#ifdef ULLong
ys = *sx++ * (ULLong)q + carry; ys = *sx++ * (ULLong)q + carry;
carry = ys >> 32; carry = ys >> 32;
y = *bx - (ys & 0xffffffffUL) - borrow; y = *bx - (ys & 0xffffffffUL) - borrow;
borrow = y >> 32 & 1UL; borrow = y >> 32 & 1UL;
*bx++ = y & 0xffffffffUL; *bx++ = y & 0xffffffffUL;
#else }
#ifdef Pack_32 while(sx <= sxe);
si = *sx++;
ys = (si & 0xffff) * q + carry;
zs = (si >> 16) * q + (ys >> 16);
carry = zs >> 16;
y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
z = (*bx >> 16) - (zs & 0xffff) - borrow;
borrow = (z & 0x10000) >> 16;
Storeinc(bx, z, y);
#else
ys = *sx++ * q + carry;
carry = ys >> 16;
y = *bx - (ys & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
*bx++ = y & 0xffff;
#endif
#endif
}
while(sx <= sxe);
if (!*bxe) { if (!*bxe) {
bx = b->x; bx = b->x;
while(--bxe > bx && !*bxe) while(--bxe > bx && !*bxe)
--n; --n;
b->wds = n; b->wds = n;
}
} }
}
if (cmp(b, S) >= 0) { if (cmp(b, S) >= 0) {
q++; q++;
borrow = 0; borrow = 0;
@ -164,40 +113,20 @@ quorem(Bigint *b, Bigint *S)
bx = b->x; bx = b->x;
sx = S->x; sx = S->x;
do { do {
#ifdef ULLong
ys = *sx++ + carry; ys = *sx++ + carry;
carry = ys >> 32; carry = ys >> 32;
y = *bx - (ys & 0xffffffffUL) - borrow; y = *bx - (ys & 0xffffffffUL) - borrow;
borrow = y >> 32 & 1UL; borrow = y >> 32 & 1UL;
*bx++ = y & 0xffffffffUL; *bx++ = y & 0xffffffffUL;
#else }
#ifdef Pack_32 while(sx <= sxe);
si = *sx++;
ys = (si & 0xffff) + carry;
zs = (si >> 16) + (ys >> 16);
carry = zs >> 16;
y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
z = (*bx >> 16) - (zs & 0xffff) - borrow;
borrow = (z & 0x10000) >> 16;
Storeinc(bx, z, y);
#else
ys = *sx++ + carry;
carry = ys >> 16;
y = *bx - (ys & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
*bx++ = y & 0xffff;
#endif
#endif
}
while(sx <= sxe);
bx = b->x; bx = b->x;
bxe = bx + n; bxe = bx + n;
if (!*bxe) { if (!*bxe) {
while(--bxe > bx && !*bxe) while(--bxe > bx && !*bxe)
--n; --n;
b->wds = n; b->wds = n;
}
} }
return q;
} }
return q;
}

View file

@ -1,36 +1,37 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "libc/runtime/fenv.h"
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
* *
@ -66,149 +67,86 @@ THIS SOFTWARE.
* calculation. * calculation.
*/ */
#ifdef Honor_FLT_ROUNDS
#undef Check_FLT_ROUNDS
#define Check_FLT_ROUNDS
#else
#define Rounding Flt_Rounds
#endif
char * char *
dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve) dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
{ {
/* Arguments ndigits, decpt, sign are similar to those /* Arguments ndigits, decpt, sign are similar to those
of ecvt and fcvt; trailing zeros are suppressed from of ecvt and fcvt; trailing zeros are suppressed from
the returned string. If not null, *rve is set to point the returned string. If not null, *rve is set to point
to the end of the return value. If d is +-Infinity or NaN, to the end of the return value. If d is +-Infinity or NaN,
then *decpt is set to 9999. then *decpt is set to 9999.
mode: mode:
0 ==> shortest string that yields d when read in 0 ==> shortest string that yields d when read in
and rounded to nearest. and rounded to nearest.
1 ==> like 0, but with Steele & White stopping rule; 1 ==> like 0, but with Steele & White stopping rule;
e.g. with IEEE P754 arithmetic , mode 0 gives e.g. with IEEE P754 arithmetic , mode 0 gives
1e23 whereas mode 1 gives 9.999999999999999e22. 1e23 whereas mode 1 gives 9.999999999999999e22.
2 ==> max(1,ndigits) significant digits. This gives a 2 ==> max(1,ndigits) significant digits. This gives a
return value similar to that of ecvt, except return value similar to that of ecvt, except
that trailing zeros are suppressed. that trailing zeros are suppressed.
3 ==> through ndigits past the decimal point. This 3 ==> through ndigits past the decimal point. This
gives a return value similar to that from fcvt, gives a return value similar to that from fcvt,
except that trailing zeros are suppressed, and except that trailing zeros are suppressed, and
ndigits can be negative. ndigits can be negative.
4,5 ==> similar to 2 and 3, respectively, but (in 4,5 ==> similar to 2 and 3, respectively, but (in
round-nearest mode) with the tests of mode 0 to round-nearest mode) with the tests of mode 0 to
possibly return a shorter string that rounds to d. possibly return a shorter string that rounds to d.
With IEEE arithmetic and compilation with With IEEE arithmetic and compilation with
-DHonor_FLT_ROUNDS, modes 4 and 5 behave the same -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
as modes 2 and 3 when FLT_ROUNDS != 1. as modes 2 and 3 when FLT_ROUNDS != 1.
6-9 ==> Debugging modes similar to mode - 4: don't try 6-9 ==> Debugging modes similar to mode - 4: don't try
fast floating-point estimate (if applicable). fast floating-point estimate (if applicable).
Values of mode other than 0-9 are treated as mode 0. Values of mode other than 0-9 are treated as mode 0.
Sufficient space is allocated to the return value Sufficient space is allocated to the return value
to hold the suppressed trailing zeros. to hold the suppressed trailing zeros.
*/ */
#ifdef MULTIPLE_THREADS
ThInfo *TI = 0;
#endif
int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
spec_case, try_quick; spec_case, try_quick;
Long L; Long L;
#ifndef Sudden_Underflow
int denorm; int denorm;
ULong x; ULong x;
#endif
Bigint *b, *b1, *delta, *mlo, *mhi, *S; Bigint *b, *b1, *delta, *mlo, *mhi, *S;
U d, d2, eps, eps1; U d, d2, eps, eps1;
double ds; double ds;
char *s, *s0; char *s, *s0;
#ifdef SET_INEXACT
int inexact, oldinexact;
#endif
#ifdef Honor_FLT_ROUNDS /*{*/
int Rounding; int Rounding;
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ Rounding = FLT_ROUNDS;
Rounding = Flt_Rounds;
#else /*}{*/
Rounding = 1;
switch(fegetround()) {
case FE_TOWARDZERO: Rounding = 0; break;
case FE_UPWARD: Rounding = 2; break;
case FE_DOWNWARD: Rounding = 3;
}
#endif /*}}*/
#endif /*}*/
#ifndef MULTIPLE_THREADS
if (dtoa_result) {
freedtoa(dtoa_result);
dtoa_result = 0;
}
#endif
d.d = d0; d.d = d0;
if (word0(&d) & Sign_bit) { if (word0(&d) & Sign_bit) {
/* set sign for everything, including 0's and NaNs */ /* set sign for everything, including 0's and NaNs */
*sign = 1; *sign = 1;
word0(&d) &= ~Sign_bit; /* clear sign bit */ word0(&d) &= ~Sign_bit; /* clear sign bit */
} }
else else
*sign = 0; *sign = 0;
#if defined(IEEE_Arith) + defined(VAX)
#ifdef IEEE_Arith
if ((word0(&d) & Exp_mask) == Exp_mask) if ((word0(&d) & Exp_mask) == Exp_mask)
#else {
if (word0(&d) == 0x8000)
#endif
{
/* Infinity or NaN */ /* Infinity or NaN */
*decpt = 9999; *decpt = 9999;
#ifdef IEEE_Arith
if (!word1(&d) && !(word0(&d) & 0xfffff)) if (!word1(&d) && !(word0(&d) & 0xfffff))
return nrv_alloc("Infinity", rve, 8 MTb); return nrv_alloc("Infinity", rve, 8);
#endif return nrv_alloc("NaN", rve, 3);
return nrv_alloc("NaN", rve, 3 MTb); }
}
#endif
#ifdef IBM
dval(&d) += 0; /* normalize */
#endif
if (!dval(&d)) { if (!dval(&d)) {
*decpt = 1; *decpt = 1;
return nrv_alloc("0", rve, 1 MTb); return nrv_alloc("0", rve, 1);
} }
#ifdef SET_INEXACT
try_quick = oldinexact = get_inexact();
inexact = 1;
#endif
#ifdef Honor_FLT_ROUNDS
if (Rounding >= 2) { if (Rounding >= 2) {
if (*sign) if (*sign)
Rounding = Rounding == 2 ? 0 : 2; Rounding = Rounding == 2 ? 0 : 2;
else else
if (Rounding != 2) if (Rounding != 2)
Rounding = 0; Rounding = 0;
} }
#endif b = d2b(dval(&d), &be, &bbits);
b = d2b(dval(&d), &be, &bbits MTb);
#ifdef Sudden_Underflow
i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
#else
if (( i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) { if (( i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) {
#endif
dval(&d2) = dval(&d); dval(&d2) = dval(&d);
word0(&d2) &= Frac_mask1; word0(&d2) &= Frac_mask1;
word0(&d2) |= Exp_11; word0(&d2) |= Exp_11;
#ifdef IBM
if (( j = 11 - hi0bits(word0(&d2) & Frac_mask) )!=0)
dval(&d2) /= 1 << j;
#endif
/* log(x) ~=~ log(1.5) + (x-1.5)/1.5 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
* log10(x) = log(x) / log(10) * log10(x) = log(x) / log(10)
* ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
@ -230,27 +168,19 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
* (We could get a more accurate k by invoking log10, * (We could get a more accurate k by invoking log10,
* but this is probably not worthwhile.) * but this is probably not worthwhile.)
*/ */
i -= Bias; i -= Bias;
#ifdef IBM
i <<= 2;
i += j;
#endif
#ifndef Sudden_Underflow
denorm = 0; denorm = 0;
} }
else { else {
/* d is denormalized */ /* d is denormalized */
i = bbits + be + (Bias + (P-1) - 1); i = bbits + be + (Bias + (P-1) - 1);
x = i > 32 ? word0(&d) << (64 - i) | word1(&d) >> (i - 32) x = i > 32 ? word0(&d) << (64 - i) | word1(&d) >> (i - 32)
: word1(&d) << (32 - i); : word1(&d) << (32 - i);
dval(&d2) = x; dval(&d2) = x;
word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
i -= (Bias + (P-1) - 1) + 1; i -= (Bias + (P-1) - 1) + 1;
denorm = 1; denorm = 1;
} }
#endif
ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
k = (int)ds; k = (int)ds;
if (ds < 0. && ds != k) if (ds < 0. && ds != k)
@ -260,79 +190,66 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
if (dval(&d) < tens[k]) if (dval(&d) < tens[k])
k--; k--;
k_check = 0; k_check = 0;
} }
j = bbits - i - 1; j = bbits - i - 1;
if (j >= 0) { if (j >= 0) {
b2 = 0; b2 = 0;
s2 = j; s2 = j;
} }
else { else {
b2 = -j; b2 = -j;
s2 = 0; s2 = 0;
} }
if (k >= 0) { if (k >= 0) {
b5 = 0; b5 = 0;
s5 = k; s5 = k;
s2 += k; s2 += k;
} }
else { else {
b2 -= k; b2 -= k;
b5 = -k; b5 = -k;
s5 = 0; s5 = 0;
} }
if (mode < 0 || mode > 9) if (mode < 0 || mode > 9)
mode = 0; mode = 0;
#ifndef SET_INEXACT
#ifdef Check_FLT_ROUNDS
try_quick = Rounding == 1; try_quick = Rounding == 1;
#else
try_quick = 1;
#endif
#endif /*SET_INEXACT*/
if (mode > 5) { if (mode > 5) {
mode -= 4; mode -= 4;
try_quick = 0; try_quick = 0;
} }
leftright = 1; leftright = 1;
ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */
/* silence erroneous "gcc -Wall" warning. */ /* silence erroneous "gcc -Wall" warning. */
switch(mode) { switch(mode) {
case 0: case 0:
case 1: case 1:
i = 18; i = 18;
ndigits = 0; ndigits = 0;
break; break;
case 2: case 2:
leftright = 0; leftright = 0;
/* no break */ /* no break */
case 4: case 4:
if (ndigits <= 0) if (ndigits <= 0)
ndigits = 1; ndigits = 1;
ilim = ilim1 = i = ndigits; ilim = ilim1 = i = ndigits;
break; break;
case 3: case 3:
leftright = 0; leftright = 0;
/* no break */ /* no break */
case 5: case 5:
i = ndigits + k + 1; i = ndigits + k + 1;
ilim = i; ilim = i;
ilim1 = i - 1; ilim1 = i - 1;
if (i <= 0) if (i <= 0)
i = 1; i = 1;
} }
s = s0 = rv_alloc(i MTb); s = s0 = rv_alloc(i);
#ifdef Honor_FLT_ROUNDS
if (mode > 1 && Rounding != 1) if (mode > 1 && Rounding != 1)
leftright = 0; leftright = 0;
#endif
if (ilim >= 0 && ilim <= Quick_max && try_quick) { if (ilim >= 0 && ilim <= Quick_max && try_quick) {
/* Try to get by with floating-point arithmetic. */ /* Try to get by with floating-point arithmetic. */
i = 0; i = 0;
j1 = 0; j1 = 0;
dval(&d2) = dval(&d); dval(&d2) = dval(&d);
@ -347,22 +264,22 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
j &= Bletch - 1; j &= Bletch - 1;
dval(&d) /= bigtens[n_bigtens-1]; dval(&d) /= bigtens[n_bigtens-1];
ieps++; ieps++;
} }
for(; j; j >>= 1, i++) for(; j; j >>= 1, i++)
if (j & 1) { if (j & 1) {
ieps++; ieps++;
ds *= bigtens[i]; ds *= bigtens[i];
} }
dval(&d) /= ds; dval(&d) /= ds;
} }
else if (( j1 = -k )!=0) { else if (( j1 = -k )!=0) {
dval(&d) *= tens[j1 & 0xf]; dval(&d) *= tens[j1 & 0xf];
for(j = j1 >> 4; j; j >>= 1, i++) for(j = j1 >> 4; j; j >>= 1, i++)
if (j & 1) { if (j & 1) {
ieps++; ieps++;
dval(&d) *= bigtens[i]; dval(&d) *= bigtens[i];
} }
} }
if (k_check && dval(&d) < 1. && ilim > 0) { if (k_check && dval(&d) < 1. && ilim > 0) {
if (ilim1 <= 0) if (ilim1 <= 0)
goto fast_failed; goto fast_failed;
@ -370,7 +287,7 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
k--; k--;
dval(&d) *= 10.; dval(&d) *= 10.;
ieps++; ieps++;
} }
dval(&eps) = ieps*dval(&d) + 7.; dval(&eps) = ieps*dval(&d) + 7.;
word0(&eps) -= (P-1)*Exp_msk1; word0(&eps) -= (P-1)*Exp_msk1;
if (ilim == 0) { if (ilim == 0) {
@ -381,8 +298,7 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
if (dval(&d) < -dval(&eps)) if (dval(&d) < -dval(&eps))
goto no_digits; goto no_digits;
goto fast_failed; goto fast_failed;
} }
#ifndef No_leftright
if (leftright) { if (leftright) {
/* Use Steele & White method of only /* Use Steele & White method of only
* generating digits needed. * generating digits needed.
@ -402,8 +318,8 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
*s++ = '1'; *s++ = '1';
++k; ++k;
goto ret1; goto ret1;
}
} }
}
for(i = 0;;) { for(i = 0;;) {
L = dval(&d); L = dval(&d);
dval(&d) -= L; dval(&d) -= L;
@ -416,10 +332,9 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
break; break;
dval(&eps) *= 10.; dval(&eps) *= 10.;
dval(&d) *= 10.; dval(&d) *= 10.;
}
} }
}
else { else {
#endif
/* Generate ilim digits, then fix them up. */ /* Generate ilim digits, then fix them up. */
dval(&eps) *= tens[ilim-1]; dval(&eps) *= tens[ilim-1];
for(i = 1;; i++, dval(&d) *= 10.) { for(i = 1;; i++, dval(&d) *= 10.) {
@ -433,20 +348,17 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
else if (dval(&d) < 0.5 - dval(&eps)) else if (dval(&d) < 0.5 - dval(&eps))
goto retc; goto retc;
break; break;
}
} }
#ifndef No_leftright
} }
#endif }
fast_failed: fast_failed:
s = s0; s = s0;
dval(&d) = dval(&d2); dval(&d) = dval(&d2);
k = k0; k = k0;
ilim = ilim0; ilim = ilim0;
} }
/* Do we have a "small" integer? */ /* Do we have a "small" integer? */
if (be >= 0 && k <= Int_max) { if (be >= 0 && k <= Int_max) {
/* Yes. */ /* Yes. */
ds = tens[k]; ds = tens[k];
@ -455,114 +367,85 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
if (ilim < 0 || dval(&d) <= 5*ds) if (ilim < 0 || dval(&d) <= 5*ds)
goto no_digits; goto no_digits;
goto one_digit; goto one_digit;
} }
for(i = 1;; i++, dval(&d) *= 10.) { for(i = 1;; i++, dval(&d) *= 10.) {
L = (Long)(dval(&d) / ds); L = (Long)(dval(&d) / ds);
dval(&d) -= L*ds; dval(&d) -= L*ds;
#ifdef Check_FLT_ROUNDS
/* If FLT_ROUNDS == 2, L will usually be high by 1 */ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
if (dval(&d) < 0) { if (dval(&d) < 0) {
L--; L--;
dval(&d) += ds; dval(&d) += ds;
} }
#endif
*s++ = '0' + (int)L; *s++ = '0' + (int)L;
if (!dval(&d)) { if (!dval(&d)) {
#ifdef SET_INEXACT
inexact = 0;
#endif
break; break;
} }
if (i == ilim) { if (i == ilim) {
#ifdef Honor_FLT_ROUNDS
if (mode > 1) if (mode > 1)
switch(Rounding) { switch(Rounding) {
case 0: goto retc; case 0: goto retc;
case 2: goto bump_up; case 2: goto bump_up;
} }
#endif
dval(&d) += dval(&d); dval(&d) += dval(&d);
#ifdef ROUND_BIASED if (dval(&d) > ds || (dval(&d) == ds && L & 1)) {
if (dval(&d) >= ds) bump_up:
#else
if (dval(&d) > ds || (dval(&d) == ds && L & 1))
#endif
{
bump_up:
while(*--s == '9') while(*--s == '9')
if (s == s0) { if (s == s0) {
k++; k++;
*s = '0'; *s = '0';
break; break;
} }
++*s++; ++*s++;
}
break;
} }
break;
} }
goto retc;
} }
goto retc;
}
m2 = b2; m2 = b2;
m5 = b5; m5 = b5;
mhi = mlo = 0; mhi = mlo = 0;
if (leftright) { if (leftright) {
i = i = denorm ? be + (Bias + (P-1) - 1 + 1) : 1 + P - bbits;
#ifndef Sudden_Underflow
denorm ? be + (Bias + (P-1) - 1 + 1) :
#endif
#ifdef IBM
1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
#else
1 + P - bbits;
#endif
b2 += i; b2 += i;
s2 += i; s2 += i;
mhi = i2b(1 MTb); mhi = i2b(1);
} }
if (m2 > 0 && s2 > 0) { if (m2 > 0 && s2 > 0) {
i = m2 < s2 ? m2 : s2; i = m2 < s2 ? m2 : s2;
b2 -= i; b2 -= i;
m2 -= i; m2 -= i;
s2 -= i; s2 -= i;
} }
if (b5 > 0) { if (b5 > 0) {
if (leftright) { if (leftright) {
if (m5 > 0) { if (m5 > 0) {
mhi = pow5mult(mhi, m5 MTb); mhi = pow5mult(mhi, m5);
b1 = mult(mhi, b MTb); b1 = mult(mhi, b);
Bfree(b MTb); Bfree(b);
b = b1; b = b1;
}
if (( j = b5 - m5 )!=0)
b = pow5mult(b, j MTb);
} }
else if (( j = b5 - m5 )!=0)
b = pow5mult(b, b5 MTb); b = pow5mult(b, j);
} }
S = i2b(1 MTb); else
b = pow5mult(b, b5);
}
S = i2b(1);
if (s5 > 0) if (s5 > 0)
S = pow5mult(S, s5 MTb); S = pow5mult(S, s5);
/* Check for special case that d is a normalized power of 2. */ /* Check for special case that d is a normalized power of 2. */
spec_case = 0; spec_case = 0;
if ((mode < 2 || leftright) if ((mode < 2 || leftright) && Rounding == 1) {
#ifdef Honor_FLT_ROUNDS if (!word1(&d) && !(word0(&d) & Bndry_mask) &&
&& Rounding == 1 word0(&d) & (Exp_mask & ~Exp_msk1)) {
#endif
) {
if (!word1(&d) && !(word0(&d) & Bndry_mask)
#ifndef Sudden_Underflow
&& word0(&d) & (Exp_mask & ~Exp_msk1)
#endif
) {
/* The special case */ /* The special case */
b2 += Log2P; b2 += Log2P;
s2 += Log2P; s2 += Log2P;
spec_case = 1; spec_case = 1;
}
} }
}
/* Arrange for convenient computation of quotients: /* Arrange for convenient computation of quotients:
* shift left if necessary so divisor has 4 leading 0 bits. * shift left if necessary so divisor has 4 leading 0 bits.
@ -571,225 +454,169 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
* and for all and pass them and a shift to quorem, so it * and for all and pass them and a shift to quorem, so it
* can do shifts and ors to compute the numerator for q. * can do shifts and ors to compute the numerator for q.
*/ */
#ifdef Pack_32
if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0) if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0)
i = 32 - i; i = 32 - i;
#else
if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0)
i = 16 - i;
#endif
if (i > 4) { if (i > 4) {
i -= 4; i -= 4;
b2 += i; b2 += i;
m2 += i; m2 += i;
s2 += i; s2 += i;
} }
else if (i < 4) { else if (i < 4) {
i += 28; i += 28;
b2 += i; b2 += i;
m2 += i; m2 += i;
s2 += i; s2 += i;
} }
if (b2 > 0) if (b2 > 0)
b = lshift(b, b2 MTb); b = lshift(b, b2);
if (s2 > 0) if (s2 > 0)
S = lshift(S, s2 MTb); S = lshift(S, s2);
if (k_check) { if (k_check) {
if (cmp(b,S) < 0) { if (cmp(b,S) < 0) {
k--; k--;
b = multadd(b, 10, 0 MTb); /* we botched the k estimate */ b = multadd(b, 10, 0); /* we botched the k estimate */
if (leftright) if (leftright)
mhi = multadd(mhi, 10, 0 MTb); mhi = multadd(mhi, 10, 0);
ilim = ilim1; ilim = ilim1;
}
} }
}
if (ilim <= 0 && (mode == 3 || mode == 5)) { if (ilim <= 0 && (mode == 3 || mode == 5)) {
if (ilim < 0 || cmp(b,S = multadd(S,5,0 MTb)) <= 0) { if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
/* no digits, fcvt style */ /* no digits, fcvt style */
no_digits: no_digits:
k = -1 - ndigits; k = -1 - ndigits;
goto ret; goto ret;
} }
one_digit: one_digit:
*s++ = '1'; *s++ = '1';
k++; k++;
goto ret; goto ret;
} }
if (leftright) { if (leftright) {
if (m2 > 0) if (m2 > 0)
mhi = lshift(mhi, m2 MTb); mhi = lshift(mhi, m2);
/* Compute mlo -- check for special case /* Compute mlo -- check for special case
* that d is a normalized power of 2. * that d is a normalized power of 2.
*/ */
mlo = mhi; mlo = mhi;
if (spec_case) { if (spec_case) {
mhi = Balloc(mhi->k MTb); mhi = Balloc(mhi->k);
Bcopy(mhi, mlo); Bcopy(mhi, mlo);
mhi = lshift(mhi, Log2P MTb); mhi = lshift(mhi, Log2P);
} }
for(i = 1;;i++) { for(i = 1;;i++) {
dig = quorem(b,S) + '0'; dig = quorem(b,S) + '0';
/* Do we yet have the shortest decimal string /* Do we yet have the shortest decimal string
* that will round to d? * that will round to d?
*/ */
j = cmp(b, mlo); j = cmp(b, mlo);
delta = diff(S, mhi MTb); delta = diff(S, mhi);
j1 = delta->sign ? 1 : cmp(b, delta); j1 = delta->sign ? 1 : cmp(b, delta);
Bfree(delta MTb); Bfree(delta);
#ifndef ROUND_BIASED if (j1 == 0 && mode != 1 && !(word1(&d) & 1) && Rounding >= 1) {
if (j1 == 0 && mode != 1 && !(word1(&d) & 1)
#ifdef Honor_FLT_ROUNDS
&& Rounding >= 1
#endif
) {
if (dig == '9') if (dig == '9')
goto round_9_up; goto round_9_up;
if (j > 0) if (j > 0)
dig++; dig++;
#ifdef SET_INEXACT
else if (!b->x[0] && b->wds <= 1)
inexact = 0;
#endif
*s++ = dig; *s++ = dig;
goto ret; goto ret;
} }
#endif if (j < 0 || (j == 0 && mode != 1 && !(word1(&d) & 1)
if (j < 0 || (j == 0 && mode != 1 )) {
#ifndef ROUND_BIASED
&& !(word1(&d) & 1)
#endif
)) {
if (!b->x[0] && b->wds <= 1) { if (!b->x[0] && b->wds <= 1) {
#ifdef SET_INEXACT
inexact = 0;
#endif
goto accept_dig; goto accept_dig;
} }
#ifdef Honor_FLT_ROUNDS
if (mode > 1) if (mode > 1)
switch(Rounding) { switch(Rounding) {
case 0: goto accept_dig; case 0: goto accept_dig;
case 2: goto keep_dig; case 2: goto keep_dig;
}
#endif /*Honor_FLT_ROUNDS*/
if (j1 > 0) {
b = lshift(b, 1 MTb);
j1 = cmp(b, S);
#ifdef ROUND_BIASED
if (j1 >= 0 /*)*/
#else
if ((j1 > 0 || (j1 == 0 && dig & 1))
#endif
&& dig++ == '9')
goto round_9_up;
} }
accept_dig: if (j1 > 0) {
b = lshift(b, 1);
j1 = cmp(b, S);
if ((j1 > 0 || (j1 == 0 && dig & 1))
&& dig++ == '9')
goto round_9_up;
}
accept_dig:
*s++ = dig; *s++ = dig;
goto ret; goto ret;
} }
if (j1 > 0) { if (j1 > 0) {
#ifdef Honor_FLT_ROUNDS
if (!Rounding && mode > 1) if (!Rounding && mode > 1)
goto accept_dig; goto accept_dig;
#endif
if (dig == '9') { /* possible if i == 1 */ if (dig == '9') { /* possible if i == 1 */
round_9_up: round_9_up:
*s++ = '9'; *s++ = '9';
goto roundoff; goto roundoff;
} }
*s++ = dig + 1; *s++ = dig + 1;
goto ret; goto ret;
} }
#ifdef Honor_FLT_ROUNDS keep_dig:
keep_dig:
#endif
*s++ = dig; *s++ = dig;
if (i == ilim) if (i == ilim)
break; break;
b = multadd(b, 10, 0 MTb); b = multadd(b, 10, 0);
if (mlo == mhi) if (mlo == mhi)
mlo = mhi = multadd(mhi, 10, 0 MTb); mlo = mhi = multadd(mhi, 10, 0);
else { else {
mlo = multadd(mlo, 10, 0 MTb); mlo = multadd(mlo, 10, 0);
mhi = multadd(mhi, 10, 0 MTb); mhi = multadd(mhi, 10, 0);
}
} }
} }
else }
else {
for(i = 1;; i++) { for(i = 1;; i++) {
*s++ = dig = quorem(b,S) + '0'; *s++ = dig = quorem(b,S) + '0';
if (!b->x[0] && b->wds <= 1) { if (!b->x[0] && b->wds <= 1) {
#ifdef SET_INEXACT
inexact = 0;
#endif
goto ret; goto ret;
} }
if (i >= ilim) if (i >= ilim)
break; break;
b = multadd(b, 10, 0 MTb); b = multadd(b, 10, 0);
} }
}
/* Round off last digit */ /* Round off last digit */
#ifdef Honor_FLT_ROUNDS
switch(Rounding) { switch(Rounding) {
case 0: goto trimzeros; case 0: goto trimzeros;
case 2: goto roundoff; case 2: goto roundoff;
} }
#endif b = lshift(b, 1);
b = lshift(b, 1 MTb);
j = cmp(b, S); j = cmp(b, S);
#ifdef ROUND_BIASED
if (j >= 0)
#else
if (j > 0 || (j == 0 && dig & 1)) if (j > 0 || (j == 0 && dig & 1))
#endif {
{ roundoff:
roundoff:
while(*--s == '9') while(*--s == '9')
if (s == s0) { if (s == s0) {
k++; k++;
*s++ = '1'; *s++ = '1';
goto ret; goto ret;
} }
++*s++; ++*s++;
} }
else { else {
#ifdef Honor_FLT_ROUNDS trimzeros:
trimzeros:
#endif
while(*--s == '0'); while(*--s == '0');
s++; s++;
} }
ret: ret:
Bfree(S MTb); Bfree(S);
if (mhi) { if (mhi) {
if (mlo && mlo != mhi) if (mlo && mlo != mhi)
Bfree(mlo MTb); Bfree(mlo);
Bfree(mhi MTb); Bfree(mhi);
} }
retc: retc:
while(s > s0 && s[-1] == '0') while(s > s0 && s[-1] == '0')
--s; --s;
ret1: ret1:
#ifdef SET_INEXACT Bfree(b);
if (inexact) {
if (!oldinexact) {
word0(&d) = Exp_1 + (70 << Exp_shift);
word1(&d) = 0;
dval(&d) += 1.;
}
}
else if (!oldinexact)
clear_inexact();
#endif
Bfree(b MTb);
*s = 0; *s = 0;
*decpt = k + 1; *decpt = k + 1;
if (rve) if (rve)
*rve = s; *rve = s;
return s0; return s0;
} }

View file

@ -1,52 +1,44 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay. #define dlen 0
#define HEXDIG "0123456789abcdef"
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#ifndef ldus_QNAN0
#define ldus_QNAN0 0x7fff #define ldus_QNAN0 0x7fff
#endif
#ifndef ldus_QNAN1
#define ldus_QNAN1 0xc000 #define ldus_QNAN1 0xc000
#endif
#ifndef ldus_QNAN2
#define ldus_QNAN2 0 #define ldus_QNAN2 0
#endif
#ifndef ldus_QNAN3
#define ldus_QNAN3 0 #define ldus_QNAN3 0
#endif
#ifndef ldus_QNAN4
#define ldus_QNAN4 0 #define ldus_QNAN4 0
#endif
const char *const InfName[6] = { "Infinity", "infinity", "INFINITY", "Inf", "inf", "INF" }; const char *const InfName[6] = { "Infinity", "infinity", "INFINITY", "Inf", "inf", "INF" };
const char *const NanName[3] = { "NaN", "nan", "NAN" }; const char *const NanName[3] = { "NaN", "nan", "NAN" };
@ -62,27 +54,6 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
int i, j, k; int i, j, k;
char *be, *s0; char *be, *s0;
size_t len; size_t len;
#ifdef USE_LOCALE
#ifdef NO_LOCALE_CACHE
char *decimalpoint = localeconv()->decimal_point;
size_t dlen = strlen(decimalpoint);
#else
char *decimalpoint;
static char *decimalpoint_cache;
static size_t dlen;
if (!(s0 = decimalpoint_cache)) {
s0 = localeconv()->decimal_point;
dlen = strlen(s0);
if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
strcpy(decimalpoint_cache, s0);
s0 = decimalpoint_cache;
}
}
decimalpoint = s0;
#endif
#else
#define dlen 0
#endif
s0 = s; s0 = s;
len = (se-s) + dlen + 6; /* 6 = sign + e+dd + trailing null */ len = (se-s) + dlen + 6; /* 6 = sign + e+dd + trailing null */
if (blen < len) if (blen < len)
@ -93,21 +64,16 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
if (decpt <= -4 || decpt > se - s + 5) { if (decpt <= -4 || decpt > se - s + 5) {
*b++ = *s++; *b++ = *s++;
if (*s) { if (*s) {
#ifdef USE_LOCALE
while((*b = *decimalpoint++))
++b;
#else
*b++ = '.'; *b++ = '.';
#endif
while((*b = *s++) !=0) while((*b = *s++) !=0)
b++; b++;
} }
*b++ = 'e'; *b++ = 'e';
/* sprintf(b, "%+.2d", decpt - 1); */ /* sprintf(b, "%+.2d", decpt - 1); */
if (--decpt < 0) { if (--decpt < 0) {
*b++ = '-'; *b++ = '-';
decpt = -decpt; decpt = -decpt;
} }
else else
*b++ = '+'; *b++ = '+';
for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){} for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){}
@ -120,58 +86,46 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
break; break;
decpt -= i*k; decpt -= i*k;
decpt *= 10; decpt *= 10;
}
*b = 0;
} }
*b = 0;
}
else if (decpt <= 0) { else if (decpt <= 0) {
#ifdef USE_LOCALE
while((*b = *decimalpoint++))
++b;
#else
*b++ = '.'; *b++ = '.';
#endif
if (be < b - decpt + (se - s)) if (be < b - decpt + (se - s))
goto ret0; goto ret0;
for(; decpt < 0; decpt++) for(; decpt < 0; decpt++)
*b++ = '0'; *b++ = '0';
while((*b = *s++) != 0) while((*b = *s++) != 0)
b++; b++;
} }
else { else {
while((*b = *s++) != 0) { while((*b = *s++) != 0) {
b++; b++;
if (--decpt == 0 && *s) { if (--decpt == 0 && *s) {
#ifdef USE_LOCALE
while(*b = *decimalpoint++)
++b;
#else
*b++ = '.'; *b++ = '.';
#endif
}
} }
}
if (b + decpt > be) { if (b + decpt > be) {
ret0: ret0:
b = 0; b = 0;
goto ret; goto ret;
} }
for(; decpt > 0; decpt--) for(; decpt > 0; decpt--)
*b++ = '0'; *b++ = '0';
*b = 0; *b = 0;
} }
ret: ret:
freedtoa(s0); freedtoa(s0);
return b; return b;
} }
char * char *
__gdtoa_add_nanbits(char *b, size_t blen, ULong *bits, int nb) __gdtoa_add_nanbits(char *b, size_t blen, ULong *bits, int nb)
{ {
ULong t; ULong t;
char *rv; char *rv;
int i, j; int i, j;
size_t L; size_t L;
static char Hexdig[16] = "0123456789abcdef";
while(!bits[--nb]) while(!bits[--nb])
if (!nb) if (!nb)
return b; return b;
@ -183,14 +137,14 @@ __gdtoa_add_nanbits(char *b, size_t blen, ULong *bits, int nb)
b += L; b += L;
*--b = 0; *--b = 0;
rv = b; rv = b;
*--b = /*(*/ ')'; *--b = ')';
for(i = 0; i < nb; ++i) { for(i = 0; i < nb; ++i) {
t = bits[i]; t = bits[i];
for(j = 0; j < 8; ++j, t >>= 4) for(j = 0; j < 8; ++j, t >>= 4)
*--b = Hexdig[t & 0xf]; *--b = HEXDIG[t & 0xf];
}
t = bits[nb];
do *--b = Hexdig[t & 0xf]; while(t >>= 4);
*--b = '('; /*)*/
return rv;
} }
t = bits[nb];
do *--b = HEXDIG[t & 0xf]; while(t >>= 4);
*--b = '(';
return rv;
}

View file

@ -1,35 +1,37 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "libc/runtime/fenv.h"
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg@acm.org). */
char * char *
g_ddfmt(char *buf, double *dd0, int ndig, size_t bufsize) g_ddfmt(char *buf, double *dd0, int ndig, size_t bufsize)
@ -40,96 +42,74 @@ g_ddfmt(char *buf, double *dd0, int ndig, size_t bufsize)
int bx, by, decpt, ex, ey, i, j, mode; int bx, by, decpt, ex, ey, i, j, mode;
Bigint *x, *y, *z; Bigint *x, *y, *z;
U *dd, ddx[2]; U *dd, ddx[2];
#ifdef MULTIPLE_THREADS
ThInfo *TI = 0;
#endif
#ifdef Honor_FLT_ROUNDS /*{{*/
int Rounding;
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
Rounding = Flt_Rounds;
#else /*}{*/
Rounding = 1;
switch(fegetround()) {
case FE_TOWARDZERO: Rounding = 0; break;
case FE_UPWARD: Rounding = 2; break;
case FE_DOWNWARD: Rounding = 3;
}
#endif /*}}*/
#else /*}{*/
#define Rounding FPI_Round_near
#endif /*}}*/
if (bufsize < 10 || bufsize < (size_t)(ndig + 8)) if (bufsize < 10 || bufsize < (size_t)(ndig + 8))
return 0; return 0;
dd = (U*)dd0; dd = (U*)dd0;
L = dd->L; L = dd->L;
if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) { if ((L[1] & 0x7ff00000L) == 0x7ff00000L) {
/* Infinity or NaN */ /* Infinity or NaN */
if (L[_0] & 0xfffff || L[_1]) { if (L[1] & 0xfffff || L[0]) {
nanret: nanret:
return strcp(buf, "NaN"); return stpcpy(buf, "NaN");
}
if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) {
if (L[2+_0] & 0xfffff || L[2+_1])
goto nanret;
if ((L[_0] ^ L[2+_0]) & 0x80000000L)
goto nanret; /* Infinity - Infinity */
}
infret:
b = buf;
if (L[_0] & 0x80000000L)
*b++ = '-';
return strcp(b, "Infinity");
} }
if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { if ((L[2+1] & 0x7ff00000) == 0x7ff00000) {
if (L[2+1] & 0xfffff || L[2+0])
goto nanret;
if ((L[1] ^ L[2+1]) & 0x80000000L)
goto nanret; /* Infinity - Infinity */
}
infret:
b = buf;
if (L[1] & 0x80000000L)
*b++ = '-';
return stpcpy(b, "Infinity");
}
if ((L[2+1] & 0x7ff00000) == 0x7ff00000) {
L += 2; L += 2;
if (L[_0] & 0xfffff || L[_1]) if (L[1] & 0xfffff || L[0])
goto nanret; goto nanret;
goto infret; goto infret;
} }
if (dval(&dd[0]) + dval(&dd[1]) == 0.) { if (dval(&dd[0]) + dval(&dd[1]) == 0.) {
b = buf; b = buf;
#ifndef IGNORE_ZERO_SIGN if (L[1] & L[2+1] & 0x80000000L)
if (L[_0] & L[2+_0] & 0x80000000L)
*b++ = '-'; *b++ = '-';
#endif
*b++ = '0'; *b++ = '0';
*b = 0; *b = 0;
return b; return b;
} }
if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) { if ((L[1] & 0x7ff00000L) < (L[2+1] & 0x7ff00000L)) {
dval(&ddx[1]) = dval(&dd[0]); dval(&ddx[1]) = dval(&dd[0]);
dval(&ddx[0]) = dval(&dd[1]); dval(&ddx[0]) = dval(&dd[1]);
dd = ddx; dd = ddx;
L = dd->L; L = dd->L;
} }
z = d2b(dval(&dd[0]), &ex, &bx MTb); z = d2b(dval(&dd[0]), &ex, &bx);
if (dval(&dd[1]) == 0.) if (dval(&dd[1]) == 0.)
goto no_y; goto no_y;
x = z; x = z;
y = d2b(dval(&dd[1]), &ey, &by MTb); y = d2b(dval(&dd[1]), &ey, &by);
if ( (i = ex - ey) !=0) { if ( (i = ex - ey) !=0) {
if (i > 0) { if (i > 0) {
x = lshift(x, i MTb); x = lshift(x, i);
ex = ey; ex = ey;
} }
else else
y = lshift(y, -i MTb); y = lshift(y, -i);
} }
if ((L[_0] ^ L[2+_0]) & 0x80000000L) { if ((L[1] ^ L[2+1]) & 0x80000000L) {
z = diff(x, y MTb); z = diff(x, y);
if (L[_0] & 0x80000000L) if (L[1] & 0x80000000L)
z->sign = 1 - z->sign; z->sign = 1 - z->sign;
} }
else { else {
z = sum(x, y MTb); z = sum(x, y);
if (L[_0] & 0x80000000L) if (L[1] & 0x80000000L)
z->sign = 1; z->sign = 1;
} }
Bfree(x MTb); Bfree(x);
Bfree(y MTb); Bfree(y);
no_y: no_y:
bits = zx = z->x; bits = zx = z->x;
for(i = 0; !*zx; zx++) for(i = 0; !*zx; zx++)
i += 32; i += 32;
@ -137,7 +117,7 @@ g_ddfmt(char *buf, double *dd0, int ndig, size_t bufsize)
if (i) { if (i) {
rshift(z, i); rshift(z, i);
ex += i; ex += i;
} }
fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]); fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]);
if (fpi.nbits < 106) { if (fpi.nbits < 106) {
fpi.nbits = 106; fpi.nbits = 106;
@ -147,24 +127,24 @@ g_ddfmt(char *buf, double *dd0, int ndig, size_t bufsize)
while(i < 4) while(i < 4)
bits0[i++] = 0; bits0[i++] = 0;
bits = bits0; bits = bits0;
}
} }
}
mode = 2; mode = 2;
if (ndig <= 0) { if (ndig <= 0) {
if (bufsize < (size_t)(fpi.nbits * .301029995664) + 10) { if (bufsize < (size_t)(fpi.nbits * .301029995664) + 10) {
Bfree(z MTb); Bfree(z);
return 0; return 0;
}
mode = 0;
} }
mode = 0;
}
fpi.emin = 1-1023-53+1; fpi.emin = 1-1023-53+1;
fpi.emax = 2046-1023-106+1; fpi.emax = 2046-1023-106+1;
fpi.rounding = Rounding; fpi.rounding = FLT_ROUNDS;
fpi.sudden_underflow = 0; fpi.sudden_underflow = 0;
fpi.int_max = Int_max; fpi.int_max = Int_max;
i = STRTOG_Normal; i = STRTOG_Normal;
s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
b = g__fmt(buf, s, se, decpt, z->sign, bufsize); b = g__fmt(buf, s, se, decpt, z->sign, bufsize);
Bfree(z MTb); Bfree(z);
return b; return b;
} }

View file

@ -1,35 +1,38 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "libc/runtime/fenv.h"
#include "libc/str/str.h"
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg@acm.org). */
extern ULong __gdtoa_NanDflt_d[2]; extern ULong __gdtoa_NanDflt_d[2];
@ -42,114 +45,92 @@ g_ddfmt_p(char *buf, double *dd0, int ndig, size_t bufsize, int nik)
int bx, by, decpt, ex, ey, i, j, mode; int bx, by, decpt, ex, ey, i, j, mode;
Bigint *x, *y, *z; Bigint *x, *y, *z;
U *dd, ddx[2]; U *dd, ddx[2];
#ifdef MULTIPLE_THREADS
ThInfo *TI = 0;
#endif
#ifdef Honor_FLT_ROUNDS /*{{*/
int Rounding;
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
Rounding = Flt_Rounds;
#else /*}{*/
Rounding = 1;
switch(fegetround()) {
case FE_TOWARDZERO: Rounding = 0; break;
case FE_UPWARD: Rounding = 2; break;
case FE_DOWNWARD: Rounding = 3;
}
#endif /*}}*/
#else /*}{*/
#define Rounding FPI_Round_near
#endif /*}}*/
if (bufsize < 10 || bufsize < (size_t)(ndig + 8)) if (bufsize < 10 || bufsize < (size_t)(ndig + 8))
return 0; return 0;
dd = (U*)dd0; dd = (U*)dd0;
L = dd->L; L = dd->L;
sign = L[_0] & L[2+_0] & 0x80000000L; sign = L[1] & L[2+1] & 0x80000000L;
if (nik < 0 || nik > 35) if (nik < 0 || nik > 35)
nik = 0; nik = 0;
if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) { if ((L[1] & 0x7ff00000L) == 0x7ff00000L) {
/* Infinity or NaN */ /* Infinity or NaN */
if (L[_0] & 0xfffff || L[_1]) { if (L[1] & 0xfffff || L[0]) {
nanret: nanret:
b = buf; b = buf;
if (sign && nik < 18) if (sign && nik < 18)
*b++ = '-'; *b++ = '-';
b = strcp(b, NanName[nik%3]); b = stpcpy(b, NanName[nik%3]);
if (nik > 5 && (nik < 12 if (nik > 5 && (nik < 12
|| L[_1] != __gdtoa_NanDflt_d[0] || L[0] != __gdtoa_NanDflt_d[0]
|| (L[_0] ^ __gdtoa_NanDflt_d[1]) & 0xfffff || (L[1] ^ __gdtoa_NanDflt_d[1]) & 0xfffff
|| L[2+_1] != __gdtoa_NanDflt_d[0] || L[2+0] != __gdtoa_NanDflt_d[0]
|| (L[2+_0] ^ __gdtoa_NanDflt_d[1]) & 0xfffff)) { || (L[2+1] ^ __gdtoa_NanDflt_d[1]) & 0xfffff)) {
bits0[0] = L[2+_1]; bits0[0] = L[2+0];
bits0[1] = (L[2+_0] & 0xfffff) | (L[_1] << 20); bits0[1] = (L[2+1] & 0xfffff) | (L[0] << 20);
bits0[2] = (L[_1] >> 12) | (L[_0] << 20); bits0[2] = (L[0] >> 12) | (L[1] << 20);
bits0[3] = (L[_0] >> 12) & 0xff; bits0[3] = (L[1] >> 12) & 0xff;
b = add_nanbits(b, bufsize - (b-buf), bits0, 4); b = add_nanbits(b, bufsize - (b-buf), bits0, 4);
} }
return b; return b;
}
if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) {
if (L[2+_0] & 0xfffff || L[2+_1])
goto nanret;
if ((L[_0] ^ L[2+_0]) & 0x80000000L)
goto nanret; /* Infinity - Infinity */
}
infret:
b = buf;
if (L[_0] & 0x80000000L)
*b++ = '-';
return strcp(b, InfName[nik%6]);
} }
if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { if ((L[2+1] & 0x7ff00000) == 0x7ff00000) {
if (L[2+1] & 0xfffff || L[2+0])
goto nanret;
if ((L[1] ^ L[2+1]) & 0x80000000L)
goto nanret; /* Infinity - Infinity */
}
infret:
b = buf;
if (L[1] & 0x80000000L)
*b++ = '-';
return stpcpy(b, InfName[nik%6]);
}
if ((L[2+1] & 0x7ff00000) == 0x7ff00000) {
L += 2; L += 2;
if (L[_0] & 0xfffff || L[_1]) if (L[1] & 0xfffff || L[0])
goto nanret; goto nanret;
goto infret; goto infret;
} }
if (dval(&dd[0]) + dval(&dd[1]) == 0.) { if (dval(&dd[0]) + dval(&dd[1]) == 0.) {
b = buf; b = buf;
#ifndef IGNORE_ZERO_SIGN
if (sign) if (sign)
*b++ = '-'; *b++ = '-';
#endif
*b++ = '0'; *b++ = '0';
*b = 0; *b = 0;
return b; return b;
} }
if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) { if ((L[1] & 0x7ff00000L) < (L[2+1] & 0x7ff00000L)) {
dval(&ddx[1]) = dval(&dd[0]); dval(&ddx[1]) = dval(&dd[0]);
dval(&ddx[0]) = dval(&dd[1]); dval(&ddx[0]) = dval(&dd[1]);
dd = ddx; dd = ddx;
L = dd->L; L = dd->L;
} }
z = d2b(dval(&dd[0]), &ex, &bx MTb); z = d2b(dval(&dd[0]), &ex, &bx);
if (dval(&dd[1]) == 0.) if (dval(&dd[1]) == 0.)
goto no_y; goto no_y;
x = z; x = z;
y = d2b(dval(&dd[1]), &ey, &by MTb); y = d2b(dval(&dd[1]), &ey, &by);
if ( (i = ex - ey) !=0) { if ( (i = ex - ey) !=0) {
if (i > 0) { if (i > 0) {
x = lshift(x, i MTb); x = lshift(x, i);
ex = ey; ex = ey;
} }
else else
y = lshift(y, -i MTb); y = lshift(y, -i);
} }
if ((L[_0] ^ L[2+_0]) & 0x80000000L) { if ((L[1] ^ L[2+1]) & 0x80000000L) {
z = diff(x, y MTb); z = diff(x, y);
if (L[_0] & 0x80000000L) if (L[1] & 0x80000000L)
z->sign = 1 - z->sign; z->sign = 1 - z->sign;
} }
else { else {
z = sum(x, y MTb); z = sum(x, y);
if (L[_0] & 0x80000000L) if (L[1] & 0x80000000L)
z->sign = 1; z->sign = 1;
} }
Bfree(x MTb); Bfree(x);
Bfree(y MTb); Bfree(y);
no_y: no_y:
bits = zx = z->x; bits = zx = z->x;
for(i = 0; !*zx; zx++) for(i = 0; !*zx; zx++)
i += 32; i += 32;
@ -157,7 +138,7 @@ g_ddfmt_p(char *buf, double *dd0, int ndig, size_t bufsize, int nik)
if (i) { if (i) {
rshift(z, i); rshift(z, i);
ex += i; ex += i;
} }
fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]); fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]);
if (fpi.nbits < 106) { if (fpi.nbits < 106) {
fpi.nbits = 106; fpi.nbits = 106;
@ -167,24 +148,24 @@ g_ddfmt_p(char *buf, double *dd0, int ndig, size_t bufsize, int nik)
while(i < 4) while(i < 4)
bits0[i++] = 0; bits0[i++] = 0;
bits = bits0; bits = bits0;
}
} }
}
mode = 2; mode = 2;
if (ndig <= 0) { if (ndig <= 0) {
if (bufsize < (size_t)(fpi.nbits * .301029995664) + 10) { if (bufsize < (size_t)(fpi.nbits * .301029995664) + 10) {
Bfree(z MTb); Bfree(z);
return 0; return 0;
}
mode = 0;
} }
mode = 0;
}
fpi.emin = 1-1023-53+1; fpi.emin = 1-1023-53+1;
fpi.emax = 2046-1023-106+1; fpi.emax = 2046-1023-106+1;
fpi.rounding = Rounding; fpi.rounding = FLT_ROUNDS;
fpi.sudden_underflow = 0; fpi.sudden_underflow = 0;
fpi.int_max = Int_max; fpi.int_max = Int_max;
i = STRTOG_Normal; i = STRTOG_Normal;
s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
b = g__fmt(buf, s, se, decpt, z->sign, bufsize); b = g__fmt(buf, s, se, decpt, z->sign, bufsize);
Bfree(z MTb); Bfree(z);
return b; return b;
} }

View file

@ -1,36 +1,36 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
char* char*
g_dfmt(char *buf, double *d, int ndig, size_t bufsize) g_dfmt(char *buf, double *d, int ndig, size_t bufsize)
@ -39,44 +39,36 @@ g_dfmt(char *buf, double *d, int ndig, size_t bufsize)
char *b, *s, *se; char *b, *s, *se;
ULong bits[2], *L, sign; ULong bits[2], *L, sign;
int decpt, ex, i, mode; int decpt, ex, i, mode;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc" #include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
if (ndig < 0) if (ndig < 0)
ndig = 0; ndig = 0;
if (bufsize < (size_t)(ndig + 10)) if (bufsize < (size_t)(ndig + 10))
return 0; return 0;
L = (ULong*)d; L = (ULong*)d;
sign = L[_0] & 0x80000000L; sign = L[1] & 0x80000000L;
if ((L[_0] & 0x7ff00000) == 0x7ff00000) { if ((L[1] & 0x7ff00000) == 0x7ff00000) {
/* Infinity or NaN */ /* Infinity or NaN */
if (bufsize < 10) if (bufsize < 10)
return 0; return 0;
if (L[_0] & 0xfffff || L[_1]) { if (L[1] & 0xfffff || L[0]) {
return strcp(buf, "NaN"); return stpcpy(buf, "NaN");
} }
b = buf; b = buf;
if (sign) if (sign)
*b++ = '-'; *b++ = '-';
return strcp(b, "Infinity"); return stpcpy(b, "Infinity");
} }
if (L[_1] == 0 && (L[_0] ^ sign) == 0 /*d == 0.*/) { if (L[0] == 0 && (L[1] ^ sign) == 0 /*d == 0.*/) {
b = buf; b = buf;
#ifndef IGNORE_ZERO_SIGN if (L[1] & 0x80000000L)
if (L[_0] & 0x80000000L)
*b++ = '-'; *b++ = '-';
#endif
*b++ = '0'; *b++ = '0';
*b = 0; *b = 0;
return b; return b;
} }
bits[0] = L[_1]; bits[0] = L[0];
bits[1] = L[_0] & 0xfffff; bits[1] = L[1] & 0xfffff;
if ( (ex = (L[_0] >> 20) & 0x7ff) !=0) if ( (ex = (L[1] >> 20) & 0x7ff) !=0)
bits[1] |= 0x100000; bits[1] |= 0x100000;
else else
ex = 1; ex = 1;
@ -89,4 +81,4 @@ g_dfmt(char *buf, double *d, int ndig, size_t bufsize)
i = STRTOG_Normal | STRTOG_Neg; i = STRTOG_Normal | STRTOG_Neg;
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se); s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign, bufsize); return g__fmt(buf, s, se, decpt, sign, bufsize);
} }

View file

@ -1,36 +1,36 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong __gdtoa_NanDflt_d[2]; extern ULong __gdtoa_NanDflt_d[2];
@ -41,57 +41,49 @@ g_dfmt_p(char *buf, double *d, int ndig, size_t bufsize, int nik)
char *b, *s, *se; char *b, *s, *se;
ULong bits[2], *L, sign; ULong bits[2], *L, sign;
int decpt, ex, i, mode; int decpt, ex, i, mode;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc" #include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
if (ndig < 0) if (ndig < 0)
ndig = 0; ndig = 0;
if (bufsize < (size_t)(ndig + 10)) if (bufsize < (size_t)(ndig + 10))
return 0; return 0;
L = (ULong*)d; L = (ULong*)d;
sign = L[_0] & 0x80000000L; sign = L[1] & 0x80000000L;
if ((L[_0] & 0x7ff00000) == 0x7ff00000) { if ((L[1] & 0x7ff00000) == 0x7ff00000) {
/* Infinity or NaN */ /* Infinity or NaN */
if (nik < 0 || nik > 35) if (nik < 0 || nik > 35)
nik = 0; nik = 0;
if (bufsize < 10) if (bufsize < 10)
return 0; return 0;
if (L[_0] & 0xfffff || L[_1]) { if (L[1] & 0xfffff || L[0]) {
b = buf; b = buf;
if (L[_0] & 0x80000000L && nik < 18) if (L[1] & 0x80000000L && nik < 18)
*b++ = '-'; *b++ = '-';
b = strcp(b, NanName[nik%3]); b = stpcpy(b, NanName[nik%3]);
if (nik > 5 && (nik < 12 if (nik > 5 && (nik < 12
|| bits[0] != __gdtoa_NanDflt_d[0] || bits[0] != __gdtoa_NanDflt_d[0]
|| (bits[1] ^ __gdtoa_NanDflt_d[1]) & 0xfffff)) { || (bits[1] ^ __gdtoa_NanDflt_d[1]) & 0xfffff)) {
bits[0] = L[_1]; bits[0] = L[0];
bits[1] = L[_0] & 0xfffff; bits[1] = L[1] & 0xfffff;
b = add_nanbits(b, bufsize - (b-buf), bits, 2); b = add_nanbits(b, bufsize - (b-buf), bits, 2);
}
return b;
} }
return b;
}
b = buf; b = buf;
if (sign) if (sign)
*b++ = '-'; *b++ = '-';
return strcp(b, InfName[nik%6]); return stpcpy(b, InfName[nik%6]);
} }
if (L[_1] == 0 && (L[_0] ^ sign) == 0 /*d == 0.*/) { if (L[0] == 0 && (L[1] ^ sign) == 0 /*d == 0.*/) {
b = buf; b = buf;
#ifndef IGNORE_ZERO_SIGN if (L[1] & 0x80000000L)
if (L[_0] & 0x80000000L)
*b++ = '-'; *b++ = '-';
#endif
*b++ = '0'; *b++ = '0';
*b = 0; *b = 0;
return b; return b;
} }
bits[0] = L[_1]; bits[0] = L[0];
bits[1] = L[_0] & 0xfffff; bits[1] = L[1] & 0xfffff;
if ( (ex = (L[_0] >> 20) & 0x7ff) !=0) if ( (ex = (L[1] >> 20) & 0x7ff) !=0)
bits[1] |= 0x100000; bits[1] |= 0x100000;
else else
ex = 1; ex = 1;
@ -104,4 +96,4 @@ g_dfmt_p(char *buf, double *d, int ndig, size_t bufsize, int nik)
i = STRTOG_Normal | STRTOG_Neg; i = STRTOG_Normal | STRTOG_Neg;
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se); s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign, bufsize); return g__fmt(buf, s, se, decpt, sign, bufsize);
} }

View file

@ -1,36 +1,36 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
char* char*
g_ffmt(char *buf, float *f, int ndig, size_t bufsize) g_ffmt(char *buf, float *f, int ndig, size_t bufsize)
@ -39,39 +39,31 @@ g_ffmt(char *buf, float *f, int ndig, size_t bufsize)
char *b, *s, *se; char *b, *s, *se;
ULong bits[1], *L, sign; ULong bits[1], *L, sign;
int decpt, ex, i, mode; int decpt, ex, i, mode;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc" #include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
if (ndig < 0) if (ndig < 0)
ndig = 0; ndig = 0;
if (bufsize < (size_t)(ndig + 10)) if (bufsize < (size_t)(ndig + 10))
return 0; return 0;
L = (ULong*)f; L = (ULong*)f;
sign = L[0] & 0x80000000L; sign = L[0] & 0x80000000L;
if ((L[0] & 0x7f800000) == 0x7f800000) { if ((L[0] & 0x7f800000) == 0x7f800000) {
/* Infinity or NaN */ /* Infinity or NaN */
if (L[0] & 0x7fffff) { if (L[0] & 0x7fffff) {
return strcp(buf, "NaN"); return stpcpy(buf, "NaN");
} }
b = buf; b = buf;
if (sign) if (sign)
*b++ = '-'; *b++ = '-';
return strcp(b, "Infinity"); return stpcpy(b, "Infinity");
} }
if (*f == 0.) { if (*f == 0.) {
b = buf; b = buf;
#ifndef IGNORE_ZERO_SIGN
if (L[0] & 0x80000000L) if (L[0] & 0x80000000L)
*b++ = '-'; *b++ = '-';
#endif
*b++ = '0'; *b++ = '0';
*b = 0; *b = 0;
return b; return b;
} }
bits[0] = L[0] & 0x7fffff; bits[0] = L[0] & 0x7fffff;
if ( (ex = (L[0] >> 23) & 0xff) !=0) if ( (ex = (L[0] >> 23) & 0xff) !=0)
bits[0] |= 0x800000; bits[0] |= 0x800000;
@ -83,8 +75,8 @@ g_ffmt(char *buf, float *f, int ndig, size_t bufsize)
if (bufsize < 16) if (bufsize < 16)
return 0; return 0;
mode = 0; mode = 0;
} }
i = STRTOG_Normal; i = STRTOG_Normal;
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se); s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign, bufsize); return g__fmt(buf, s, se, decpt, sign, bufsize);
} }

View file

@ -1,36 +1,36 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong __gdtoa_NanDflt_f[1]; extern ULong __gdtoa_NanDflt_f[1];
@ -41,17 +41,11 @@ g_ffmt_p(char *buf, float *f, int ndig, size_t bufsize, int nik)
char *b, *s, *se; char *b, *s, *se;
ULong bits[1], *L, sign; ULong bits[1], *L, sign;
int decpt, ex, i, mode; int decpt, ex, i, mode;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc" #include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
if (ndig < 0) if (ndig < 0)
ndig = 0; ndig = 0;
if (bufsize < (size_t)(ndig + 10)) if (bufsize < (size_t)(ndig + 10))
return 0; return 0;
L = (ULong*)f; L = (ULong*)f;
sign = L[0] & 0x80000000L; sign = L[0] & 0x80000000L;
if ((L[0] & 0x7f800000) == 0x7f800000) { if ((L[0] & 0x7f800000) == 0x7f800000) {
@ -62,27 +56,25 @@ g_ffmt_p(char *buf, float *f, int ndig, size_t bufsize, int nik)
b = buf; b = buf;
if (sign && nik < 18) if (sign && nik < 18)
*b++ = '-'; *b++ = '-';
b = strcp(b, NanName[nik%3]); b = stpcpy(b, NanName[nik%3]);
if (nik > 5 && (nik < 12 if (nik > 5 && (nik < 12
|| (bits[0] ^ __gdtoa_NanDflt_f[0]) & 0x7fffff)) || (bits[0] ^ __gdtoa_NanDflt_f[0]) & 0x7fffff))
b = add_nanbits(b, bufsize - (b-buf), bits, 1); b = add_nanbits(b, bufsize - (b-buf), bits, 1);
return b; return b;
} }
b = buf; b = buf;
if (sign) if (sign)
*b++ = '-'; *b++ = '-';
return strcp(b, InfName[nik%6]); return stpcpy(b, InfName[nik%6]);
} }
if (*f == 0.) { if (*f == 0.) {
b = buf; b = buf;
#ifndef IGNORE_ZERO_SIGN
if (L[0] & 0x80000000L) if (L[0] & 0x80000000L)
*b++ = '-'; *b++ = '-';
#endif
*b++ = '0'; *b++ = '0';
*b = 0; *b = 0;
return b; return b;
} }
bits[0] = L[0] & 0x7fffff; bits[0] = L[0] & 0x7fffff;
if ( (ex = (L[0] >> 23) & 0xff) !=0) if ( (ex = (L[0] >> 23) & 0xff) !=0)
bits[0] |= 0x800000; bits[0] |= 0x800000;
@ -94,8 +86,8 @@ g_ffmt_p(char *buf, float *f, int ndig, size_t bufsize, int nik)
if (bufsize < 16) if (bufsize < 16)
return 0; return 0;
mode = 0; mode = 0;
} }
i = STRTOG_Normal; i = STRTOG_Normal;
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se); s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign, bufsize); return g__fmt(buf, s, se, decpt, sign, bufsize);
} }

View file

@ -1,56 +1,36 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#define _4 4
#endif
#ifdef IEEE_8087
#define _0 4
#define _1 3
#define _2 2
#define _3 1
#define _4 0
#endif
char* char*
g_xfmt(char *buf, void *V, int ndig, size_t bufsize) g_xfmt(char *buf, void *V, int ndig, size_t bufsize)
@ -60,57 +40,49 @@ g_xfmt(char *buf, void *V, int ndig, size_t bufsize)
ULong bits[2], sign; ULong bits[2], sign;
UShort *L; UShort *L;
int decpt, ex, i, mode; int decpt, ex, i, mode;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc" #include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
if (ndig < 0) if (ndig < 0)
ndig = 0; ndig = 0;
if (bufsize < (size_t)(ndig + 10)) if (bufsize < (size_t)(ndig + 10))
return 0; return 0;
L = (UShort *)V; L = (UShort *)V;
sign = L[_0] & 0x8000; sign = L[4] & 0x8000;
bits[1] = ((ULong)L[_1] << 16) | L[_2]; bits[1] = ((ULong)L[3] << 16) | L[2];
bits[0] = ((ULong)L[_3] << 16) | L[_4]; bits[0] = ((ULong)L[1] << 16) | L[0];
if ( (ex = L[_0] & 0x7fff) !=0) { if ( (ex = L[4] & 0x7fff) !=0) {
if (ex == 0x7fff) { if (ex == 0x7fff) {
/* Infinity or NaN */ /* Infinity or NaN */
if (!bits[0] && bits[1]== 0x80000000) { if (!bits[0] && bits[1]== 0x80000000) {
b = buf; b = buf;
if (sign) if (sign)
*b++ = '-'; *b++ = '-';
b = strcp(b, "Infinity"); b = stpcpy(b, "Infinity");
}
else
b = strcp(buf, "NaN");
return b;
} }
i = STRTOG_Normal; else
b = stpcpy(buf, "NaN");
return b;
} }
i = STRTOG_Normal;
}
else if (bits[0] | bits[1]) { else if (bits[0] | bits[1]) {
i = STRTOG_Denormal; i = STRTOG_Denormal;
ex = 1; ex = 1;
} }
else { else {
b = buf; b = buf;
#ifndef IGNORE_ZERO_SIGN
if (sign) if (sign)
*b++ = '-'; *b++ = '-';
#endif
*b++ = '0'; *b++ = '0';
*b = 0; *b = 0;
return b; return b;
} }
ex -= 0x3fff + 63; ex -= 0x3fff + 63;
mode = 2; mode = 2;
if (ndig <= 0) { if (ndig <= 0) {
if (bufsize < 32) if (bufsize < 32)
return 0; return 0;
mode = 0; mode = 0;
} }
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se); s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign, bufsize); return g__fmt(buf, s, se, decpt, sign, bufsize);
} }

View file

@ -1,59 +1,39 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern UShort __gdtoa_NanDflt_ldus[5]; extern UShort __gdtoa_NanDflt_ldus[5];
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#define _4 4
#endif
#ifdef IEEE_8087
#define _0 4
#define _1 3
#define _2 2
#define _3 1
#define _4 0
#endif
char* char*
g_xfmt_p(char *buf, void *V, int ndig, size_t bufsize, int nik) g_xfmt_p(char *buf, void *V, int ndig, size_t bufsize, int nik)
{ {
@ -62,22 +42,16 @@ g_xfmt_p(char *buf, void *V, int ndig, size_t bufsize, int nik)
ULong bits[2], sign; ULong bits[2], sign;
UShort *L; UShort *L;
int decpt, ex, i, mode; int decpt, ex, i, mode;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc" #include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
if (ndig < 0) if (ndig < 0)
ndig = 0; ndig = 0;
if (bufsize < (size_t)(ndig + 10)) if (bufsize < (size_t)(ndig + 10))
return 0; return 0;
L = (UShort *)V; L = (UShort *)V;
sign = L[_0] & 0x8000; sign = L[4] & 0x8000;
bits[1] = ((ULong)L[_1] << 16) | L[_2]; bits[1] = ((ULong)L[3] << 16) | L[2];
bits[0] = ((ULong)L[_3] << 16) | L[_4]; bits[0] = ((ULong)L[1] << 16) | L[0];
if ( (ex = L[_0] & 0x7fff) !=0) { if ( (ex = L[4] & 0x7fff) !=0) {
if (ex == 0x7fff) { if (ex == 0x7fff) {
/* Infinity or NaN */ /* Infinity or NaN */
if (nik < 0 || nik > 35) if (nik < 0 || nik > 35)
@ -86,47 +60,45 @@ g_xfmt_p(char *buf, void *V, int ndig, size_t bufsize, int nik)
b = buf; b = buf;
if (sign) if (sign)
*b++ = '-'; *b++ = '-';
b = strcp(b, InfName[nik%6]); b = stpcpy(b, InfName[nik%6]);
} }
else { else {
b = buf; b = buf;
if (sign && nik < 18) if (sign && nik < 18)
*b++ = '-'; *b++ = '-';
b = strcp(b, NanName[nik%3]); b = stpcpy(b, NanName[nik%3]);
if (nik > 5 && (nik < 12 if (nik > 5 && (nik < 12
|| L[_1] != __gdtoa_NanDflt_ldus[3] || L[3] != __gdtoa_NanDflt_ldus[3]
|| L[_2] != __gdtoa_NanDflt_ldus[2] || L[2] != __gdtoa_NanDflt_ldus[2]
|| L[_3] != __gdtoa_NanDflt_ldus[1] || L[1] != __gdtoa_NanDflt_ldus[1]
|| L[_4] != __gdtoa_NanDflt_ldus[0])) { || L[0] != __gdtoa_NanDflt_ldus[0])) {
bits[1] &= 0x7fffffff; bits[1] &= 0x7fffffff;
b = add_nanbits(b, bufsize - (b-buf), bits, 2); b = add_nanbits(b, bufsize - (b-buf), bits, 2);
}
} }
return b;
} }
i = STRTOG_Normal; return b;
} }
i = STRTOG_Normal;
}
else if (bits[0] | bits[1]) { else if (bits[0] | bits[1]) {
i = STRTOG_Denormal; i = STRTOG_Denormal;
ex = 1; ex = 1;
} }
else { else {
b = buf; b = buf;
#ifndef IGNORE_ZERO_SIGN
if (sign) if (sign)
*b++ = '-'; *b++ = '-';
#endif
*b++ = '0'; *b++ = '0';
*b = 0; *b = 0;
return b; return b;
} }
ex -= 0x3fff + 63; ex -= 0x3fff + 63;
mode = 2; mode = 2;
if (ndig <= 0) { if (ndig <= 0) {
if (bufsize < 32) if (bufsize < 32)
return 0; return 0;
mode = 0; mode = 0;
} }
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se); s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign, bufsize); return g__fmt(buf, s, se, decpt, sign, bufsize);
} }

View file

@ -1,75 +1,67 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
static Bigint * static Bigint *
bitstob(ULong *bits, int nbits, int *bbits MTd) bitstob(ULong *bits, int nbits, int *bbits)
{ {
int i, k; int i, k;
Bigint *b; Bigint *b;
ULong *be, *x, *x0; ULong *be, *x, *x0;
i = ULbits; i = ULbits;
k = 0; k = 0;
while(i < nbits) { while(i < nbits) {
i <<= 1; i <<= 1;
k++; k++;
} }
#ifndef Pack_32 b = Balloc(k);
if (!k)
k = 1;
#endif
b = Balloc(k MTa);
be = bits + ((nbits - 1) >> kshift); be = bits + ((nbits - 1) >> kshift);
x = x0 = b->x; x = x0 = b->x;
do { do {
*x++ = *bits & ALL_ON; *x++ = *bits & ALL_ON;
#ifdef Pack_16 } while(++bits <= be);
*x++ = (*bits >> 16) & ALL_ON;
#endif
} while(++bits <= be);
i = x - x0; i = x - x0;
while(!x0[--i]) while(!x0[--i])
if (!i) { if (!i) {
b->wds = 0; b->wds = 0;
*bbits = 0; *bbits = 0;
goto ret; goto ret;
} }
b->wds = i + 1; b->wds = i + 1;
*bbits = i*ULbits + 32 - hi0bits(b->x[i]); *bbits = i*ULbits + 32 - hi0bits(b->x[i]);
ret: ret:
return b; return b;
} }
/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
* *
@ -106,7 +98,7 @@ bitstob(ULong *bits, int nbits, int *bbits MTd)
*/ */
char * char *
gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve) gdtoa(const FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)
{ {
/* Arguments ndigits and decpt are similar to the second and third /* Arguments ndigits and decpt are similar to the second and third
arguments of ecvt and fcvt; trailing zeros are suppressed from arguments of ecvt and fcvt; trailing zeros are suppressed from
@ -143,9 +135,6 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
to hold the suppressed trailing zeros. to hold the suppressed trailing zeros.
*/ */
#ifdef MULTIPLE_THREADS
ThInfo *TI = 0;
#endif
int bbits, b2, b5, be0, dig, i, ieps, ilim, ilim0, ilim1, inex; int bbits, b2, b5, be0, dig, i, ieps, ilim, ilim0, ilim1, inex;
int j, j1, k, k0, k_check, kind, leftright, m2, m5, nbits; int j, j1, k, k0, k_check, kind, leftright, m2, m5, nbits;
int rdir, s2, s5, spec_case, try_quick; int rdir, s2, s5, spec_case, try_quick;
@ -154,53 +143,40 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
double d2, ds; double d2, ds;
char *s, *s0; char *s, *s0;
U d, eps; U d, eps;
#ifndef MULTIPLE_THREADS
if (dtoa_result) {
freedtoa(dtoa_result);
dtoa_result = 0;
}
#endif
inex = 0; inex = 0;
kind = *kindp &= ~STRTOG_Inexact; kind = *kindp &= ~STRTOG_Inexact;
switch(kind & STRTOG_Retmask) { switch(kind & STRTOG_Retmask) {
case STRTOG_Zero: case STRTOG_Zero:
goto ret_zero; goto ret_zero;
case STRTOG_Normal: case STRTOG_Normal:
case STRTOG_Denormal: case STRTOG_Denormal:
break; break;
case STRTOG_Infinite: case STRTOG_Infinite:
*decpt = -32768; *decpt = -32768;
return nrv_alloc("Infinity", rve, 8 MTb); return nrv_alloc("Infinity", rve, 8);
case STRTOG_NaN: case STRTOG_NaN:
*decpt = -32768; *decpt = -32768;
return nrv_alloc("NaN", rve, 3 MTb); return nrv_alloc("NaN", rve, 3);
default: default:
return 0; return 0;
} }
b = bitstob(bits, nbits = fpi->nbits, &bbits MTb); b = bitstob(bits, nbits = fpi->nbits, &bbits);
be0 = be; be0 = be;
if ( (i = trailz(b)) !=0) { if ( (i = trailz(b)) !=0) {
rshift(b, i); rshift(b, i);
be += i; be += i;
bbits -= i; bbits -= i;
} }
if (!b->wds) { if (!b->wds) {
Bfree(b MTb); Bfree(b);
ret_zero: ret_zero:
*decpt = 1; *decpt = 1;
return nrv_alloc("0", rve, 1 MTb); return nrv_alloc("0", rve, 1);
} }
dval(&d) = b2d(b, &i); dval(&d) = b2d(b, &i);
i = be + bbits - 1; i = be + bbits - 1;
word0(&d) &= Frac_mask1; word0(&d) &= Frac_mask1;
word0(&d) |= Exp_11; word0(&d) |= Exp_11;
#ifdef IBM
if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0)
dval(&d) /= 1 << j;
#endif
/* log(x) ~=~ log(1.5) + (x-1.5)/1.5 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
* log10(x) = log(x) / log(10) * log10(x) = log(x) / log(10)
* ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
@ -222,25 +198,16 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
* (We could get a more accurate k by invoking log10, * (We could get a more accurate k by invoking log10,
* but this is probably not worthwhile.) * but this is probably not worthwhile.)
*/ */
ds = (dval(&d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; ds = (dval(&d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
/* correct assumption about exponent range */ /* correct assumption about exponent range */
if ((j = i) < 0) if ((j = i) < 0)
j = -j; j = -j;
if ((j -= 1077) > 0) if ((j -= 1077) > 0)
ds += j * 7e-17; ds += j * 7e-17;
k = (int)ds; k = (int)ds;
if (ds < 0. && ds != k) if (ds < 0. && ds != k)
k--; /* want k = floor(ds) */ k--; /* want k = floor(ds) */
k_check = 1; k_check = 1;
#ifdef IBM
j = be + bbits - 1;
if ( (j1 = j & 3) !=0)
dval(&d) *= 1 << j1;
word0(&d) += j << Exp_shift - 2 & Exp_mask;
#else
// TODO: word0(&d) += (be + bbits - 1) << Exp_shift; // TODO: word0(&d) += (be + bbits - 1) << Exp_shift;
// error: third_party/gdtoa/gdtoa.c:244: left shift of negative value -6 'int' 20 'int' // error: third_party/gdtoa/gdtoa.c:244: left shift of negative value -6 'int' 20 'int'
// 4161d8: __die at libc/log/die.c:33 // 4161d8: __die at libc/log/die.c:33
@ -258,69 +225,67 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
// 401d30: cosmo at libc/runtime/cosmo.S:65 // 401d30: cosmo at libc/runtime/cosmo.S:65
// 401173: _start at libc/crt/crt.S:67 // 401173: _start at libc/crt/crt.S:67
word0(&d) += (unsigned)(be + bbits - 1) << Exp_shift; word0(&d) += (unsigned)(be + bbits - 1) << Exp_shift;
#endif
if (k >= 0 && k <= Ten_pmax) { if (k >= 0 && k <= Ten_pmax) {
if (dval(&d) < tens[k]) if (dval(&d) < tens[k])
k--; k--;
k_check = 0; k_check = 0;
} }
j = bbits - i - 1; j = bbits - i - 1;
if (j >= 0) { if (j >= 0) {
b2 = 0; b2 = 0;
s2 = j; s2 = j;
} }
else { else {
b2 = -j; b2 = -j;
s2 = 0; s2 = 0;
} }
if (k >= 0) { if (k >= 0) {
b5 = 0; b5 = 0;
s5 = k; s5 = k;
s2 += k; s2 += k;
} }
else { else {
b2 -= k; b2 -= k;
b5 = -k; b5 = -k;
s5 = 0; s5 = 0;
} }
if (mode < 0 || mode > 9) if (mode < 0 || mode > 9)
mode = 0; mode = 0;
try_quick = 1; try_quick = 1;
if (mode > 5) { if (mode > 5) {
mode -= 4; mode -= 4;
try_quick = 0; try_quick = 0;
} }
else if (i >= -4 - Emin || i < Emin) else if (i >= -4 - Emin || i < Emin)
try_quick = 0; try_quick = 0;
leftright = 1; leftright = 1;
ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */
/* silence erroneous "gcc -Wall" warning. */ /* silence erroneous "gcc -Wall" warning. */
switch(mode) { switch(mode) {
case 0: case 0:
case 1: case 1:
i = (int)(nbits * .30103) + 3; i = (int)(nbits * .30103) + 3;
ndigits = 0; ndigits = 0;
break; break;
case 2: case 2:
leftright = 0; leftright = 0;
/* no break */ /* no break */
case 4: case 4:
if (ndigits <= 0) if (ndigits <= 0)
ndigits = 1; ndigits = 1;
ilim = ilim1 = i = ndigits; ilim = ilim1 = i = ndigits;
break; break;
case 3: case 3:
leftright = 0; leftright = 0;
/* no break */ /* no break */
case 5: case 5:
i = ndigits + k + 1; i = ndigits + k + 1;
ilim = i; ilim = i;
ilim1 = i - 1; ilim1 = i - 1;
if (i <= 0) if (i <= 0)
i = 1; i = 1;
} }
s = s0 = rv_alloc(i MTb); s = s0 = rv_alloc(i);
if (mode <= 1) if (mode <= 1)
rdir = 0; rdir = 0;
else if ( (rdir = fpi->rounding - 1) !=0) { else if ( (rdir = fpi->rounding - 1) !=0) {
@ -328,18 +293,10 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
rdir = 2; rdir = 2;
if (kind & STRTOG_Neg) if (kind & STRTOG_Neg)
rdir = 3 - rdir; rdir = 3 - rdir;
} }
/* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */ /* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */
if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir && k == 0) {
if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir
#ifndef IMPRECISE_INEXACT
&& k == 0
#endif
) {
/* Try to get by with floating-point arithmetic. */ /* Try to get by with floating-point arithmetic. */
i = 0; i = 0;
d2 = dval(&d); d2 = dval(&d);
k0 = k; k0 = k;
@ -353,13 +310,13 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
j &= Bletch - 1; j &= Bletch - 1;
dval(&d) /= bigtens[n_bigtens-1]; dval(&d) /= bigtens[n_bigtens-1];
ieps++; ieps++;
} }
for(; j; j >>= 1, i++) for(; j; j >>= 1, i++)
if (j & 1) { if (j & 1) {
ieps++; ieps++;
ds *= bigtens[i]; ds *= bigtens[i];
} }
} }
else { else {
ds = 1.; ds = 1.;
if ( (j1 = -k) !=0) { if ( (j1 = -k) !=0) {
@ -368,9 +325,9 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
if (j & 1) { if (j & 1) {
ieps++; ieps++;
dval(&d) *= bigtens[i]; dval(&d) *= bigtens[i];
} }
}
} }
}
if (k_check && dval(&d) < 1. && ilim > 0) { if (k_check && dval(&d) < 1. && ilim > 0) {
if (ilim1 <= 0) if (ilim1 <= 0)
goto fast_failed; goto fast_failed;
@ -378,7 +335,7 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
k--; k--;
dval(&d) *= 10.; dval(&d) *= 10.;
ieps++; ieps++;
} }
dval(&eps) = ieps*dval(&d) + 7.; dval(&eps) = ieps*dval(&d) + 7.;
word0(&eps) -= (P-1)*Exp_msk1; word0(&eps) -= (P-1)*Exp_msk1;
if (ilim == 0) { if (ilim == 0) {
@ -389,8 +346,7 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
if (dval(&d) < -dval(&eps)) if (dval(&d) < -dval(&eps))
goto no_digits; goto no_digits;
goto fast_failed; goto fast_failed;
} }
#ifndef No_leftright
if (leftright) { if (leftright) {
/* Use Steele & White method of only /* Use Steele & White method of only
* generating digits needed. * generating digits needed.
@ -404,17 +360,16 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
if (dval(&d)) if (dval(&d))
inex = STRTOG_Inexlo; inex = STRTOG_Inexlo;
goto ret1; goto ret1;
} }
if (ds - dval(&d) < dval(&eps)) if (ds - dval(&d) < dval(&eps))
goto bump_up; goto bump_up;
if (++i >= ilim) if (++i >= ilim)
break; break;
dval(&eps) *= 10.; dval(&eps) *= 10.;
dval(&d) *= 10.; dval(&d) *= 10.;
}
} }
}
else { else {
#endif
/* Generate ilim digits, then fix them up. */ /* Generate ilim digits, then fix them up. */
dval(&eps) *= tens[ilim-1]; dval(&eps) *= tens[ilim-1];
for(i = 1;; i++, dval(&d) *= 10.) { for(i = 1;; i++, dval(&d) *= 10.) {
@ -429,22 +384,18 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
if (dval(&d)) if (dval(&d))
inex = STRTOG_Inexlo; inex = STRTOG_Inexlo;
goto ret1; goto ret1;
}
break;
} }
break;
} }
#ifndef No_leftright
} }
#endif }
fast_failed: fast_failed:
s = s0; s = s0;
dval(&d) = d2; dval(&d) = d2;
k = k0; k = k0;
ilim = ilim0; ilim = ilim0;
} }
/* Do we have a "small" integer? */ /* Do we have a "small" integer? */
if (be >= 0 && k <= fpi->int_max) { if (be >= 0 && k <= fpi->int_max) {
/* Yes. */ /* Yes. */
ds = tens[k]; ds = tens[k];
@ -453,17 +404,15 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
if (ilim < 0 || dval(&d) <= 5*ds) if (ilim < 0 || dval(&d) <= 5*ds)
goto no_digits; goto no_digits;
goto one_digit; goto one_digit;
} }
for(i = 1;; i++, dval(&d) *= 10.) { for(i = 1;; i++, dval(&d) *= 10.) {
L = dval(&d) / ds; L = dval(&d) / ds;
dval(&d) -= L*ds; dval(&d) -= L*ds;
#ifdef Check_FLT_ROUNDS
/* If FLT_ROUNDS == 2, L will usually be high by 1 */ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
if (dval(&d) < 0) { if (dval(&d) < 0) {
L--; L--;
dval(&d) += ds; dval(&d) += ds;
} }
#endif
*s++ = '0' + (int)L; *s++ = '0' + (int)L;
if (dval(&d) == 0.) if (dval(&d) == 0.)
break; break;
@ -473,32 +422,27 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
goto bump_up; goto bump_up;
inex = STRTOG_Inexlo; inex = STRTOG_Inexlo;
goto ret1; goto ret1;
} }
dval(&d) += dval(&d); dval(&d) += dval(&d);
#ifdef ROUND_BIASED
if (dval(&d) >= ds)
#else
if (dval(&d) > ds || (dval(&d) == ds && L & 1)) if (dval(&d) > ds || (dval(&d) == ds && L & 1))
#endif {
{ bump_up:
bump_up:
inex = STRTOG_Inexhi; inex = STRTOG_Inexhi;
while(*--s == '9') while(*--s == '9')
if (s == s0) { if (s == s0) {
k++; k++;
*s = '0'; *s = '0';
break; break;
} }
++*s++; ++*s++;
} }
else else
inex = STRTOG_Inexlo; inex = STRTOG_Inexlo;
break; break;
}
} }
goto ret1;
} }
goto ret1;
}
m2 = b2; m2 = b2;
m5 = b5; m5 = b5;
mhi = mlo = 0; mhi = mlo = 0;
@ -509,9 +453,9 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
i = be - fpi->emin + 1; i = be - fpi->emin + 1;
if (mode >= 2 && ilim > 0 && ilim < i) if (mode >= 2 && ilim > 0 && ilim < i)
goto small_ilim; goto small_ilim;
} }
else if (mode >= 2) { else if (mode >= 2) {
small_ilim: small_ilim:
j = ilim - 1; j = ilim - 1;
if (m5 >= j) if (m5 >= j)
m5 -= j; m5 -= j;
@ -519,42 +463,40 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
s5 += j -= m5; s5 += j -= m5;
b5 += j; b5 += j;
m5 = 0; m5 = 0;
} }
if ((i = ilim) < 0) { if ((i = ilim) < 0) {
m2 -= i; m2 -= i;
i = 0; i = 0;
}
} }
}
b2 += i; b2 += i;
s2 += i; s2 += i;
mhi = i2b(1 MTb); mhi = i2b(1);
} }
if (m2 > 0 && s2 > 0) { if (m2 > 0 && s2 > 0) {
i = m2 < s2 ? m2 : s2; i = m2 < s2 ? m2 : s2;
b2 -= i; b2 -= i;
m2 -= i; m2 -= i;
s2 -= i; s2 -= i;
} }
if (b5 > 0) { if (b5 > 0) {
if (leftright) { if (leftright) {
if (m5 > 0) { if (m5 > 0) {
mhi = pow5mult(mhi, m5 MTb); mhi = pow5mult(mhi, m5);
b1 = mult(mhi, b MTb); b1 = mult(mhi, b);
Bfree(b MTb); Bfree(b);
b = b1; b = b1;
}
if ( (j = b5 - m5) !=0)
b = pow5mult(b, j MTb);
} }
else if ( (j = b5 - m5) !=0)
b = pow5mult(b, b5 MTb); b = pow5mult(b, j);
} }
S = i2b(1 MTb); else
b = pow5mult(b, b5);
}
S = i2b(1);
if (s5 > 0) if (s5 > 0)
S = pow5mult(S, s5 MTb); S = pow5mult(S, s5);
/* Check for special case that d is a normalized power of 2. */ /* Check for special case that d is a normalized power of 2. */
spec_case = 0; spec_case = 0;
if (mode < 2) { if (mode < 2) {
if (bbits == 1 && be0 > fpi->emin + 1) { if (bbits == 1 && be0 > fpi->emin + 1) {
@ -562,9 +504,8 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
b2++; b2++;
s2++; s2++;
spec_case = 1; spec_case = 1;
}
} }
}
/* Arrange for convenient computation of quotients: /* Arrange for convenient computation of quotients:
* shift left if necessary so divisor has 4 leading 0 bits. * shift left if necessary so divisor has 4 leading 0 bits.
* *
@ -575,190 +516,170 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
i = ((s5 ? hi0bits(S->x[S->wds-1]) : ULbits - 1) - s2 - 4) & kmask; i = ((s5 ? hi0bits(S->x[S->wds-1]) : ULbits - 1) - s2 - 4) & kmask;
m2 += i; m2 += i;
if ((b2 += i) > 0) if ((b2 += i) > 0)
b = lshift(b, b2 MTb); b = lshift(b, b2);
if ((s2 += i) > 0) if ((s2 += i) > 0)
S = lshift(S, s2 MTb); S = lshift(S, s2);
if (k_check) { if (k_check) {
if (cmp(b,S) < 0) { if (cmp(b,S) < 0) {
k--; k--;
b = multadd(b, 10, 0 MTb); /* we botched the k estimate */ b = multadd(b, 10, 0); /* we botched the k estimate */
if (leftright) if (leftright)
mhi = multadd(mhi, 10, 0 MTb); mhi = multadd(mhi, 10, 0);
ilim = ilim1; ilim = ilim1;
}
} }
}
if (ilim <= 0 && mode > 2) { if (ilim <= 0 && mode > 2) {
if (ilim < 0 || cmp(b,S = multadd(S,5,0 MTb)) <= 0) { if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
/* no digits, fcvt style */ /* no digits, fcvt style */
no_digits: no_digits:
k = -1 - ndigits; k = -1 - ndigits;
inex = STRTOG_Inexlo; inex = STRTOG_Inexlo;
goto ret; goto ret;
} }
one_digit: one_digit:
inex = STRTOG_Inexhi; inex = STRTOG_Inexhi;
*s++ = '1'; *s++ = '1';
k++; k++;
goto ret; goto ret;
} }
if (leftright) { if (leftright) {
if (m2 > 0) if (m2 > 0)
mhi = lshift(mhi, m2 MTb); mhi = lshift(mhi, m2);
/* Compute mlo -- check for special case /* Compute mlo -- check for special case
* that d is a normalized power of 2. * that d is a normalized power of 2.
*/ */
mlo = mhi; mlo = mhi;
if (spec_case) { if (spec_case) {
mhi = Balloc(mhi->k MTb); mhi = Balloc(mhi->k);
Bcopy(mhi, mlo); Bcopy(mhi, mlo);
mhi = lshift(mhi, 1 MTb); mhi = lshift(mhi, 1);
} }
for(i = 1;;i++) { for(i = 1;;i++) {
dig = quorem(b,S) + '0'; dig = quorem(b,S) + '0';
/* Do we yet have the shortest decimal string /* Do we yet have the shortest decimal string
* that will round to d? * that will round to d?
*/ */
j = cmp(b, mlo); j = cmp(b, mlo);
delta = diff(S, mhi MTb); delta = diff(S, mhi);
j1 = delta->sign ? 1 : cmp(b, delta); j1 = delta->sign ? 1 : cmp(b, delta);
Bfree(delta MTb); Bfree(delta);
#ifndef ROUND_BIASED
if (j1 == 0 && !mode && !(bits[0] & 1) && !rdir) { if (j1 == 0 && !mode && !(bits[0] & 1) && !rdir) {
if (dig == '9') if (dig == '9')
goto round_9_up; goto round_9_up;
if (j <= 0) { if (j <= 0) {
if (b->wds > 1 || b->x[0]) if (b->wds > 1 || b->x[0])
inex = STRTOG_Inexlo; inex = STRTOG_Inexlo;
} }
else { else {
dig++; dig++;
inex = STRTOG_Inexhi; inex = STRTOG_Inexhi;
} }
*s++ = dig; *s++ = dig;
goto ret; goto ret;
} }
#endif if (j < 0 || (j == 0 && !mode && !(bits[0] & 1))) {
if (j < 0 || (j == 0 && !mode
#ifndef ROUND_BIASED
&& !(bits[0] & 1)
#endif
)) {
if (rdir && (b->wds > 1 || b->x[0])) { if (rdir && (b->wds > 1 || b->x[0])) {
if (rdir == 2) { if (rdir == 2) {
inex = STRTOG_Inexlo; inex = STRTOG_Inexlo;
goto accept; goto accept;
} }
while (cmp(S,mhi) > 0) { while (cmp(S,mhi) > 0) {
*s++ = dig; *s++ = dig;
mhi1 = multadd(mhi, 10, 0 MTb); mhi1 = multadd(mhi, 10, 0);
if (mlo == mhi) if (mlo == mhi)
mlo = mhi1; mlo = mhi1;
mhi = mhi1; mhi = mhi1;
b = multadd(b, 10, 0 MTb); b = multadd(b, 10, 0);
dig = quorem(b,S) + '0'; dig = quorem(b,S) + '0';
} }
if (dig++ == '9') if (dig++ == '9')
goto round_9_up; goto round_9_up;
inex = STRTOG_Inexhi; inex = STRTOG_Inexhi;
goto accept; goto accept;
} }
if (j1 > 0) { if (j1 > 0) {
b = lshift(b, 1 MTb); b = lshift(b, 1);
j1 = cmp(b, S); j1 = cmp(b, S);
#ifdef ROUND_BIASED if ((j1 > 0 || (j1 == 0 && dig & 1)) && dig++ == '9')
if (j1 >= 0 /*)*/
#else
if ((j1 > 0 || (j1 == 0 && dig & 1))
#endif
&& dig++ == '9')
goto round_9_up; goto round_9_up;
inex = STRTOG_Inexhi; inex = STRTOG_Inexhi;
} }
if (b->wds > 1 || b->x[0]) if (b->wds > 1 || b->x[0])
inex = STRTOG_Inexlo; inex = STRTOG_Inexlo;
accept: accept:
*s++ = dig; *s++ = dig;
goto ret; goto ret;
} }
if (j1 > 0 && rdir != 2) { if (j1 > 0 && rdir != 2) {
if (dig == '9') { /* possible if i == 1 */ if (dig == '9') { /* possible if i == 1 */
round_9_up: round_9_up:
*s++ = '9'; *s++ = '9';
inex = STRTOG_Inexhi; inex = STRTOG_Inexhi;
goto roundoff; goto roundoff;
} }
inex = STRTOG_Inexhi; inex = STRTOG_Inexhi;
*s++ = dig + 1; *s++ = dig + 1;
goto ret; goto ret;
} }
*s++ = dig; *s++ = dig;
if (i == ilim) if (i == ilim)
break; break;
b = multadd(b, 10, 0 MTb); b = multadd(b, 10, 0);
if (mlo == mhi) if (mlo == mhi)
mlo = mhi = multadd(mhi, 10, 0 MTb); mlo = mhi = multadd(mhi, 10, 0);
else { else {
mlo = multadd(mlo, 10, 0 MTb); mlo = multadd(mlo, 10, 0);
mhi = multadd(mhi, 10, 0 MTb); mhi = multadd(mhi, 10, 0);
}
} }
} }
}
else else
for(i = 1;; i++) { for(i = 1;; i++) {
*s++ = dig = quorem(b,S) + '0'; *s++ = dig = quorem(b,S) + '0';
if (i >= ilim) if (i >= ilim)
break; break;
b = multadd(b, 10, 0 MTb); b = multadd(b, 10, 0);
} }
/* Round off last digit */ /* Round off last digit */
if (rdir) { if (rdir) {
if (rdir == 2 || (b->wds <= 1 && !b->x[0])) if (rdir == 2 || (b->wds <= 1 && !b->x[0]))
goto chopzeros; goto chopzeros;
goto roundoff; goto roundoff;
} }
b = lshift(b, 1 MTb); b = lshift(b, 1);
j = cmp(b, S); j = cmp(b, S);
#ifdef ROUND_BIASED
if (j >= 0)
#else
if (j > 0 || (j == 0 && dig & 1)) if (j > 0 || (j == 0 && dig & 1))
#endif {
{ roundoff:
roundoff:
inex = STRTOG_Inexhi; inex = STRTOG_Inexhi;
while(*--s == '9') while(*--s == '9')
if (s == s0) { if (s == s0) {
k++; k++;
*s++ = '1'; *s++ = '1';
goto ret; goto ret;
} }
++*s++; ++*s++;
} }
else { else {
chopzeros: chopzeros:
if (b->wds > 1 || b->x[0]) if (b->wds > 1 || b->x[0])
inex = STRTOG_Inexlo; inex = STRTOG_Inexlo;
} }
ret: ret:
Bfree(S MTb); Bfree(S);
if (mhi) { if (mhi) {
if (mlo && mlo != mhi) if (mlo && mlo != mhi)
Bfree(mlo MTb); Bfree(mlo);
Bfree(mhi MTb); Bfree(mhi);
} }
ret1: ret1:
while(s > s0 && s[-1] == '0') while(s > s0 && s[-1] == '0')
--s; --s;
Bfree(b MTb); Bfree(b);
*s = 0; *s = 0;
*decpt = k + 1; *decpt = k + 1;
if (rve) if (rve)
*rve = s; *rve = s;
*kindp |= inex; *kindp |= inex;
return s0; return s0;
} }

View file

@ -13,7 +13,6 @@ enum {
STRTOG_NaNbits = 5, STRTOG_NaNbits = 5,
STRTOG_NoNumber = 6, STRTOG_NoNumber = 6,
STRTOG_Retmask = 7, STRTOG_Retmask = 7,
/* The following may be or-ed into one of the above values. */ /* The following may be or-ed into one of the above values. */
STRTOG_Neg = 0x08, /* does not affect STRTOG_Inexlo or STRTOG_Inexhi */ STRTOG_Neg = 0x08, /* does not affect STRTOG_Inexlo or STRTOG_Inexhi */
STRTOG_Inexlo = 0x10, /* returned result rounded toward zero */ STRTOG_Inexlo = 0x10, /* returned result rounded toward zero */
@ -40,9 +39,8 @@ enum {
FPI_Round_down = 3 FPI_Round_down = 3
}; };
char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve); char *dtoa(double, int, int, int *, int *, char **);
char *gdtoa(const FPI *fpi, int be, unsigned *bits, int *kindp, int mode, char *gdtoa(const FPI *, int, unsigned *, int *, int, int, int *, char **);
int ndigits, int *decpt, char **rve);
void freedtoa(char *); void freedtoa(char *);
double atof(const char *); double atof(const char *);

View file

@ -11,54 +11,14 @@ Kudos go to Guy L. Steele, Jr. and Jon L. White\\n\
Copyright (C) 1997, 1998, 2000 by Lucent Technologies\""); Copyright (C) 1997, 1998, 2000 by Lucent Technologies\"");
asm(".include \"libc/disclaimer.inc\""); asm(".include \"libc/disclaimer.inc\"");
#define IEEE_Arith 1 #define IEEE_Arith 1
#define IEEE_8087 1 #define IEEE_8087 1
#define Honor_FLT_ROUNDS 1 #define Honor_FLT_ROUNDS 1
#define f_QNAN 0x7fc00000 #define f_QNAN 0x7fc00000
#define d_QNAN0 0x7ff80000 #define d_QNAN0 0x7ff80000
#define d_QNAN1 0x0 #define d_QNAN1 0x0
#define Omit_Private_Memory 1
#define Check_FLT_ROUNDS 1 #define Check_FLT_ROUNDS 1
#define Trust_FLT_ROUNDS 1
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998-2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* This is a variation on dtoa.c that converts arbitary binary
floating-point formats to and from decimal notation. It uses
double-precision arithmetic internally, so there are still
various #ifdefs that adapt the calculations to the native
double-precision arithmetic (any of IEEE, VAX D_floating,
or IBM mainframe arithmetic).
Please send bug reports to David M. Gay (dmg at acm dot org,
with " at " changed at "@" and " dot " changed to ".").
*/
/* On a machine with IEEE extended-precision registers, it is /* On a machine with IEEE extended-precision registers, it is
* necessary to specify double-precision (53-bit) rounding precision * necessary to specify double-precision (53-bit) rounding precision
@ -184,7 +144,6 @@ THIS SOFTWARE.
* probability of wasting memory, but would otherwise be harmless.) * probability of wasting memory, but would otherwise be harmless.)
* You must also invoke freedtoa(s) to free the value s returned by * You must also invoke freedtoa(s) to free the value s returned by
* dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined.
* When MULTIPLE_THREADS is #defined, source file misc.c provides * When MULTIPLE_THREADS is #defined, source file misc.c provides
* void set_max_gdtoa_threads(unsigned int n); * void set_max_gdtoa_threads(unsigned int n);
* and expects * and expects
@ -202,7 +161,6 @@ THIS SOFTWARE.
* with m <= n has has no effect, but a call with m > n is honored. * with m <= n has has no effect, but a call with m > n is honored.
* Such a call invokes REALLOC (assumed to be "realloc" if REALLOC * Such a call invokes REALLOC (assumed to be "realloc" if REALLOC
* is not #defined) to extend the size of the relevant array. * is not #defined) to extend the size of the relevant array.
* #define IMPRECISE_INEXACT if you do not care about the setting of * #define IMPRECISE_INEXACT if you do not care about the setting of
* the STRTOG_Inexact bits in the special case of doing IEEE double * the STRTOG_Inexact bits in the special case of doing IEEE double
* precision conversions (which could also be done by the strtod in * precision conversions (which could also be done by the strtod in
@ -227,9 +185,9 @@ typedef unsigned Long ULong;
typedef unsigned short UShort; typedef unsigned short UShort;
#endif #endif
#ifndef CONST #ifndef const
#define CONST const #define const const
#endif /* CONST */ #endif /* const */
#ifdef DEBUG #ifdef DEBUG
#define Bug(x) \ #define Bug(x) \
@ -284,10 +242,6 @@ extern Char *REALLOC(Char *, size_t);
#define n_bigtens 2 #define n_bigtens 2
#endif #endif
#ifdef __cplusplus
extern "C" {
#endif
typedef union { typedef union {
double d; double d;
ULong L[2]; ULong L[2];
@ -322,7 +276,6 @@ typedef union {
/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
#ifdef IEEE_Arith
#define Exp_shift 20 #define Exp_shift 20
#define Exp_shift1 20 #define Exp_shift1 20
#define Exp_msk1 0x100000 #define Exp_msk1 0x100000
@ -348,72 +301,6 @@ typedef union {
#define Quick_max 14 #define Quick_max 14
#define Int_max 14 #define Int_max 14
#ifndef Flt_Rounds
#ifdef FLT_ROUNDS
#define Flt_Rounds FLT_ROUNDS
#else
#define Flt_Rounds 1
#endif
#endif /*Flt_Rounds*/
#else /* ifndef IEEE_Arith */
#undef Sudden_Underflow
#define Sudden_Underflow
#ifdef IBM
#undef Flt_Rounds
#define Flt_Rounds 0
#define Exp_shift 24
#define Exp_shift1 24
#define Exp_msk1 0x1000000
#define Exp_msk11 0x1000000
#define Exp_mask 0x7f000000
#define P 14
#define Bias 65
#define Exp_1 0x41000000
#define Exp_11 0x41000000
#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
#define Frac_mask 0xffffff
#define Frac_mask1 0xffffff
#define Bletch 4
#define Ten_pmax 22
#define Bndry_mask 0xefffff
#define Bndry_mask1 0xffffff
#define LSB 1
#define Sign_bit 0x80000000
#define Log2P 4
#define Tiny0 0x100000
#define Tiny1 0
#define Quick_max 14
#define Int_max 15
#else /* VAX */
#undef Flt_Rounds
#define Flt_Rounds 1
#define Exp_shift 23
#define Exp_shift1 7
#define Exp_msk1 0x80
#define Exp_msk11 0x800000
#define Exp_mask 0x7f80
#define P 56
#define Bias 129
#define Exp_1 0x40800000
#define Exp_11 0x4080
#define Ebits 8
#define Frac_mask 0x7fffff
#define Frac_mask1 0xffff007f
#define Ten_pmax 24
#define Bletch 2
#define Bndry_mask 0xffff007f
#define Bndry_mask1 0xffff007f
#define LSB 0x10000
#define Sign_bit 0x8000
#define Log2P 1
#define Tiny0 0x80
#define Tiny1 0
#define Quick_max 15
#define Int_max 15
#endif /* IBM, VAX */
#endif /* IEEE_Arith */
#ifndef IEEE_Arith #ifndef IEEE_Arith
#define ROUND_BIASED #define ROUND_BIASED
#else #else
@ -472,23 +359,6 @@ extern double rnd_prod(double, double), rnd_quot(double, double);
#define ALL_ON 0xffff #define ALL_ON 0xffff
#endif #endif
#ifdef MULTIPLE_THREADS /*{{*/
#define MTa , PTI
#define MTb , &TI
#define MTd , ThInfo **PTI
#define MTk ThInfo **PTI;
extern void ACQUIRE_DTOA_LOCK(unsigned int);
extern void FREE_DTOA_LOCK(unsigned int);
extern unsigned int dtoa_get_threadno(void);
#else /*}{*/
#define ACQUIRE_DTOA_LOCK(n) /*nothing*/
#define FREE_DTOA_LOCK(n) /*nothing*/
#define MTa /*nothing*/
#define MTb /*nothing*/
#define MTd /*nothing*/
#define MTk /*nothing*/
#endif /*}}*/
#define Kmax 9 #define Kmax 9
struct Bigint { struct Bigint {
@ -554,7 +424,6 @@ extern void __gdtoa_memcpy(void *, const void *, size_t);
#define rv_alloc __gdtoa_rv_alloc #define rv_alloc __gdtoa_rv_alloc
#define s2b __gdtoa_s2b #define s2b __gdtoa_s2b
#define set_ones __gdtoa_set_ones #define set_ones __gdtoa_set_ones
#define strcp __gdtoa_strcp
#define strtoIg __gdtoa_strtoIg #define strtoIg __gdtoa_strtoIg
#define sum __gdtoa_sum #define sum __gdtoa_sum
#define tens __gdtoa_tens #define tens __gdtoa_tens
@ -566,52 +435,50 @@ extern void __gdtoa_memcpy(void *, const void *, size_t);
extern char *add_nanbits(char *, size_t, ULong *, int); extern char *add_nanbits(char *, size_t, ULong *, int);
hidden extern char *dtoa_result; hidden extern char *dtoa_result;
hidden extern CONST double bigtens[]; hidden extern const double bigtens[];
hidden extern CONST double tens[]; hidden extern const double tens[];
hidden extern CONST double tinytens[]; hidden extern const double tinytens[];
hidden extern const unsigned char hexdig[]; hidden extern const unsigned char hexdig[];
hidden extern const char *const InfName[6]; hidden extern const char *const InfName[6];
hidden extern const char *const NanName[3]; hidden extern const char *const NanName[3];
extern Bigint *Balloc(int MTd); Bigint *Balloc(int);
extern void Bfree(Bigint *MTd); void Bfree(Bigint *);
extern void ULtof(ULong *, ULong *, Long, int); void ULtof(ULong *, ULong *, Long, int);
extern void ULtod(ULong *, ULong *, Long, int); void ULtod(ULong *, ULong *, Long, int);
extern void ULtodd(ULong *, ULong *, Long, int); void ULtodd(ULong *, ULong *, Long, int);
extern void ULtoQ(ULong *, ULong *, Long, int); void ULtoQ(ULong *, ULong *, Long, int);
extern void ULtox(UShort *, ULong *, Long, int); void ULtox(UShort *, ULong *, Long, int);
extern void ULtoxL(ULong *, ULong *, Long, int); void ULtoxL(ULong *, ULong *, Long, int);
extern ULong any_on(Bigint *, int); ULong any_on(Bigint *, int);
extern double b2d(Bigint *, int *); double b2d(Bigint *, int *);
extern int cmp(Bigint *, Bigint *); int cmp(Bigint *, Bigint *);
extern void copybits(ULong *, int, Bigint *); void copybits(ULong *, int, Bigint *);
extern Bigint *d2b(double, int *, int *MTd); Bigint *d2b(double, int *, int *);
extern void decrement(Bigint *); void decrement(Bigint *);
extern Bigint *diff(Bigint *, Bigint *MTd); Bigint *diff(Bigint *, Bigint *);
extern char *g__fmt(char *, char *, char *, int, ULong, size_t); char *g__fmt(char *, char *, char *, int, ULong, size_t);
extern int gethex(CONST char **, CONST FPI *, Long *, Bigint **, int MTd); int gethex(const char **, const FPI *, Long *, Bigint **, int);
extern void __gdtoa_hexdig_init(void); void __gdtoa_hexdig_init(void);
extern int hexnan(CONST char **, CONST FPI *, ULong *); int hexnan(const char **, const FPI *, ULong *);
extern Bigint *i2b(int MTd); Bigint *i2b(int);
extern Bigint *increment(Bigint *MTd); Bigint *increment(Bigint *);
extern Bigint *lshift(Bigint *, int MTd); Bigint *lshift(Bigint *, int);
extern int match(CONST char **, char *); int match(const char **, char *);
extern Bigint *mult(Bigint *, Bigint *MTd); Bigint *mult(Bigint *, Bigint *);
extern Bigint *multadd(Bigint *, int, int MTd); Bigint *multadd(Bigint *, int, int);
extern char *nrv_alloc(char *, char **, int MTd); char *nrv_alloc(char *, char **, int);
extern Bigint *pow5mult(Bigint *, int MTd); Bigint *pow5mult(Bigint *, int);
extern int quorem(Bigint *, Bigint *); int quorem(Bigint *, Bigint *);
extern double ratio(Bigint *, Bigint *); double ratio(Bigint *, Bigint *);
extern void rshift(Bigint *, int); void rshift(Bigint *, int);
extern char *rv_alloc(int MTd); char *rv_alloc(int);
extern Bigint *s2b(CONST char *, int, int, ULong, int MTd); Bigint *s2b(const char *, int, int, ULong, int);
extern Bigint *set_ones(Bigint *, int MTd); Bigint *set_ones(Bigint *, int);
extern char *strcp(char *, const char *); int strtoIg(const char *, char **, const FPI *, Long *, Bigint **, int *);
extern int strtoIg(CONST char *, char **, CONST FPI *, Long *, Bigint **, Bigint *sum(Bigint *, Bigint *);
int *); int trailz(Bigint *);
extern Bigint *sum(Bigint *, Bigint *MTd); double ulp(U *);
extern int trailz(Bigint *);
extern double ulp(U *);
forceinline int lo0bits(ULong *y) { forceinline int lo0bits(ULong *y) {
int k; int k;
@ -628,9 +495,6 @@ forceinline int hi0bits(ULong x) {
return x ? __builtin_clz(x) : 32; return x ? __builtin_clz(x) : 32;
} }
#ifdef __cplusplus
}
#endif
/* /*
* NAN_WORD0 and NAN_WORD1 are only referenced in strtod.c. Prior to * NAN_WORD0 and NAN_WORD1 are only referenced in strtod.c. Prior to
* 20050115, they used to be hard-wired here (to 0x7ff80000 and 0, * 20050115, they used to be hard-wired here (to 0x7ff80000 and 0,
@ -645,25 +509,12 @@ forceinline int hi0bits(ULong x) {
#undef INFNAN_CHECK #undef INFNAN_CHECK
#define INFNAN_CHECK #define INFNAN_CHECK
#endif #endif
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#ifndef NAN_WORD0
#define NAN_WORD0 d_QNAN0
#endif
#ifndef NAN_WORD1
#define NAN_WORD1 d_QNAN1
#endif
#else
#define _0 1
#define _1 0
#ifndef NAN_WORD0 #ifndef NAN_WORD0
#define NAN_WORD0 d_QNAN1 #define NAN_WORD0 d_QNAN1
#endif #endif
#ifndef NAN_WORD1 #ifndef NAN_WORD1
#define NAN_WORD1 d_QNAN0 #define NAN_WORD1 d_QNAN0
#endif #endif
#endif
#else #else
#undef INFNAN_CHECK #undef INFNAN_CHECK
#endif #endif

View file

@ -1,18 +1,11 @@
/* clang-format off */
FPI *fpi, fpi1; FPI *fpi, fpi1;
int Rounding; int Rounding;
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ Rounding = FLT_ROUNDS;
Rounding = Flt_Rounds;
#else /*}{*/
Rounding = 1;
switch(fegetround()) {
case FE_TOWARDZERO: Rounding = 0; break;
case FE_UPWARD: Rounding = 2; break;
case FE_DOWNWARD: Rounding = 3;
}
#endif /*}}*/
fpi = &fpi0; fpi = &fpi0;
if (Rounding != 1) { if (Rounding != FPI_Round_near) {
fpi1 = fpi0; fpi1 = fpi0;
fpi = &fpi1; fpi = &fpi1;
fpi1.rounding = Rounding; fpi1.rounding = Rounding;
} }

View file

@ -1,68 +1,50 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "libc/errno.h" #include "libc/errno.h"
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int int
gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd) gethex( const char **sp, const FPI *fpi, Long *exp, Bigint **bp, int sign)
{ {
Bigint *b; Bigint *b;
CONST unsigned char *decpt, *s0, *s, *s1; const unsigned char *decpt, *s0, *s, *s1;
int big, esign, havedig, irv, j, k, n, n0, nbits, up, zret; int big, esign, havedig, irv, j, k, n, n0, nbits, up, zret;
ULong L, lostbits, *x; ULong L, lostbits, *x;
Long e, e1; Long e, e1;
#ifdef USE_LOCALE
int i;
#ifdef NO_LOCALE_CACHE
const unsigned char *decimalpoint = (unsigned char*)localeconv()->decimal_point;
#else
const unsigned char *decimalpoint;
static unsigned char *decimalpoint_cache;
if (!(s0 = decimalpoint_cache)) {
s0 = (unsigned char*)localeconv()->decimal_point;
if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
strcpy(decimalpoint_cache, s0);
s0 = decimalpoint_cache;
}
}
decimalpoint = s0;
#endif
#endif
/**** if (!hexdig['0']) __gdtoa_hexdig_init(); ****/ /**** if (!hexdig['0']) __gdtoa_hexdig_init(); ****/
*bp = 0; *bp = 0;
havedig = 0; havedig = 0;
s0 = *(CONST unsigned char **)sp + 2; s0 = *(const unsigned char **)sp + 2;
while(s0[havedig] == '0') while(s0[havedig] == '0')
havedig++; havedig++;
s0 += havedig; s0 += havedig;
@ -74,17 +56,9 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
havedig++; havedig++;
else { else {
zret = 1; zret = 1;
#ifdef USE_LOCALE
for(i = 0; decimalpoint[i]; ++i) {
if (s[i] != decimalpoint[i])
goto pcheck;
}
decpt = s += i;
#else
if (*s != '.') if (*s != '.')
goto pcheck; goto pcheck;
decpt = ++s; decpt = ++s;
#endif
if (!hexdig[*s]) if (!hexdig[*s])
goto pcheck; goto pcheck;
while(*s == '0') while(*s == '0')
@ -93,52 +67,43 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
zret = 0; zret = 0;
havedig = 1; havedig = 1;
s0 = s; s0 = s;
} }
while(hexdig[*s]) while(hexdig[*s])
s++; s++;
#ifdef USE_LOCALE
if (*s == *decimalpoint && !decpt) {
for(i = 1; decimalpoint[i]; ++i) {
if (s[i] != decimalpoint[i])
goto pcheck;
}
decpt = s += i;
#else
if (*s == '.' && !decpt) { if (*s == '.' && !decpt) {
decpt = ++s; decpt = ++s;
#endif
while(hexdig[*s]) while(hexdig[*s])
s++; s++;
}/*}*/ }/*}*/
if (decpt) if (decpt)
e = -(((Long)(s-decpt)) << 2); e = -(((Long)(s-decpt)) << 2);
pcheck: pcheck:
s1 = s; s1 = s;
big = esign = 0; big = esign = 0;
switch(*s) { switch(*s) {
case 'p': case 'p':
case 'P': case 'P':
switch(*++s) { switch(*++s) {
case '-': case '-':
esign = 1; esign = 1;
/* no break */ /* no break */
case '+': case '+':
s++; s++;
} }
if ((n = hexdig[*s]) == 0 || n > 0x19) { if ((n = hexdig[*s]) == 0 || n > 0x19) {
s = s1; s = s1;
break; break;
} }
e1 = n - 0x10; e1 = n - 0x10;
while((n = hexdig[*++s]) !=0 && n <= 0x19) { while((n = hexdig[*++s]) !=0 && n <= 0x19) {
if (e1 & 0xf8000000) if (e1 & 0xf8000000)
big = 1; big = 1;
e1 = 10*e1 + n - 0x10; e1 = 10*e1 + n - 0x10;
} }
if (esign) if (esign)
e1 = -e1; e1 = -e1;
e += e1; e += e1;
} }
*sp = (char*)s; *sp = (char*)s;
if (!havedig) if (!havedig)
*sp = (char*)s0 - 1; *sp = (char*)s0 - 1;
@ -147,40 +112,40 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
if (big) { if (big) {
if (esign) { if (esign) {
switch(fpi->rounding) { switch(fpi->rounding) {
case FPI_Round_up: case FPI_Round_up:
if (sign) if (sign)
break; break;
goto ret_tiny; goto ret_tiny;
case FPI_Round_down: case FPI_Round_down:
if (!sign) if (!sign)
break; break;
goto ret_tiny; goto ret_tiny;
} }
goto retz; goto retz;
ret_tiny: ret_tiny:
b = Balloc(0 MTa); b = Balloc(0);
b->wds = 1; b->wds = 1;
b->x[0] = 1; b->x[0] = 1;
goto dret; goto dret;
} }
switch(fpi->rounding) { switch(fpi->rounding) {
case FPI_Round_near: case FPI_Round_near:
goto ovfl1; goto ovfl1;
case FPI_Round_up: case FPI_Round_up:
if (!sign) if (!sign)
goto ovfl1; goto ovfl1;
goto ret_big; goto ret_big;
case FPI_Round_down: case FPI_Round_down:
if (sign) if (sign)
goto ovfl1; goto ovfl1;
} }
ret_big: ret_big:
nbits = fpi->nbits; nbits = fpi->nbits;
n0 = n = nbits >> kshift; n0 = n = nbits >> kshift;
if (nbits & kmask) if (nbits & kmask)
++n; ++n;
for(j = n, k = 0; j >>= 1; ++k); for(j = n, k = 0; j >>= 1; ++k);
*bp = b = Balloc(k MTa); *bp = b = Balloc(k);
b->wds = n; b->wds = n;
for(j = 0; j < n0; ++j) for(j = 0; j < n0; ++j)
b->x[j] = ALL_ON; b->x[j] = ALL_ON;
@ -188,35 +153,25 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
b->x[j] = ALL_ON >> (ULbits - (nbits & kmask)); b->x[j] = ALL_ON >> (ULbits - (nbits & kmask));
*exp = fpi->emax; *exp = fpi->emax;
return STRTOG_Normal | STRTOG_Inexlo; return STRTOG_Normal | STRTOG_Inexlo;
} }
n = s1 - s0 - 1; n = s1 - s0 - 1;
for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1)
k++; k++;
b = Balloc(k MTa); b = Balloc(k);
x = b->x; x = b->x;
n = 0; n = 0;
L = 0; L = 0;
#ifdef USE_LOCALE
for(i = 0; decimalpoint[i+1]; ++i);
#endif
while(s1 > s0) { while(s1 > s0) {
#ifdef USE_LOCALE
if (*--s1 == decimalpoint[i]) {
s1 -= i;
continue;
}
#else
if (*--s1 == '.') if (*--s1 == '.')
continue; continue;
#endif
if (n == ULbits) { if (n == ULbits) {
*x++ = L; *x++ = L;
L = 0; L = 0;
n = 0; n = 0;
} }
L |= (hexdig[*s1] & 0x0f) << n; L |= (hexdig[*s1] & 0x0f) << n;
n += 4; n += 4;
} }
*x++ = L; *x++ = L;
b->wds = n = x - b->x; b->wds = n = x - b->x;
n = ULbits*n - hi0bits(L); n = ULbits*n - hi0bits(L);
@ -232,72 +187,66 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
lostbits = 2; lostbits = 2;
if (k > 0 && any_on(b,k)) if (k > 0 && any_on(b,k))
lostbits = 3; lostbits = 3;
}
} }
}
rshift(b, n); rshift(b, n);
e += n; e += n;
} }
else if (n < nbits) { else if (n < nbits) {
n = nbits - n; n = nbits - n;
b = lshift(b, n MTa); b = lshift(b, n);
e -= n; e -= n;
x = b->x; x = b->x;
} }
if (e > fpi->emax) { if (e > fpi->emax) {
ovfl: ovfl:
Bfree(b MTa); Bfree(b);
ovfl1: ovfl1:
#ifndef NO_ERRNO
errno = ERANGE; errno = ERANGE;
#endif
switch (fpi->rounding) { switch (fpi->rounding) {
case FPI_Round_zero: case FPI_Round_zero:
goto ret_big; goto ret_big;
case FPI_Round_down: case FPI_Round_down:
if (!sign) if (!sign)
goto ret_big; goto ret_big;
break; break;
case FPI_Round_up: case FPI_Round_up:
if (sign) if (sign)
goto ret_big; goto ret_big;
}
return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
} }
return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
}
irv = STRTOG_Normal; irv = STRTOG_Normal;
if (e < fpi->emin) { if (e < fpi->emin) {
irv = STRTOG_Denormal; irv = STRTOG_Denormal;
n = fpi->emin - e; n = fpi->emin - e;
if (n >= nbits) { if (n >= nbits) {
switch (fpi->rounding) { switch (fpi->rounding) {
case FPI_Round_near: case FPI_Round_near:
if (n == nbits && (n < 2 || lostbits || any_on(b,n-1))) if (n == nbits && (n < 2 || lostbits || any_on(b,n-1)))
goto one_bit; goto one_bit;
break; break;
case FPI_Round_up: case FPI_Round_up:
if (!sign) if (!sign)
goto one_bit; goto one_bit;
break; break;
case FPI_Round_down: case FPI_Round_down:
if (sign) { if (sign) {
one_bit: one_bit:
x[0] = b->wds = 1; x[0] = b->wds = 1;
dret: dret:
*bp = b; *bp = b;
*exp = fpi->emin; *exp = fpi->emin;
#ifndef NO_ERRNO
errno = ERANGE; errno = ERANGE;
#endif
return STRTOG_Denormal | STRTOG_Inexhi return STRTOG_Denormal | STRTOG_Inexhi
| STRTOG_Underflow; | STRTOG_Underflow;
} }
}
Bfree(b MTa);
retz:
#ifndef NO_ERRNO
errno = ERANGE;
#endif
return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow;
} }
Bfree(b);
retz:
errno = ERANGE;
return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow;
}
k = n - 1; k = n - 1;
if (lostbits) if (lostbits)
lostbits = 1; lostbits = 1;
@ -308,45 +257,45 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
nbits -= n; nbits -= n;
rshift(b,n); rshift(b,n);
e = fpi->emin; e = fpi->emin;
} }
if (lostbits) { if (lostbits) {
up = 0; up = 0;
switch(fpi->rounding) { switch(fpi->rounding) {
case FPI_Round_zero: case FPI_Round_zero:
break; break;
case FPI_Round_near: case FPI_Round_near:
if (lostbits & 2 if (lostbits & 2
&& (lostbits | x[0]) & 1) && (lostbits | x[0]) & 1)
up = 1; up = 1;
break; break;
case FPI_Round_up: case FPI_Round_up:
up = 1 - sign; up = 1 - sign;
break; break;
case FPI_Round_down: case FPI_Round_down:
up = sign; up = sign;
} }
if (up) { if (up) {
k = b->wds; k = b->wds;
b = increment(b MTa); b = increment(b);
x = b->x; x = b->x;
if (irv == STRTOG_Denormal) { if (irv == STRTOG_Denormal) {
if (nbits == fpi->nbits - 1 if (nbits == fpi->nbits - 1
&& x[nbits >> kshift] & 1 << (nbits & kmask)) && x[nbits >> kshift] & 1 << (nbits & kmask))
irv = STRTOG_Normal; irv = STRTOG_Normal;
} }
else if (b->wds > k else if (b->wds > k
|| ((n = nbits & kmask) !=0 || ((n = nbits & kmask) !=0
&& hi0bits(x[k-1]) < 32-n)) { && hi0bits(x[k-1]) < 32-n)) {
rshift(b,1); rshift(b,1);
if (++e > fpi->emax) if (++e > fpi->emax)
goto ovfl; goto ovfl;
}
irv |= STRTOG_Inexhi;
} }
irv |= STRTOG_Inexhi;
}
else else
irv |= STRTOG_Inexlo; irv |= STRTOG_Inexlo;
} }
*bp = b; *bp = b;
*exp = e; *exp = e;
return irv; return irv;
} }

View file

@ -1,43 +1,42 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
void void
rshift(Bigint *b, int k) rshift(Bigint *b, int k)
{ {
ULong *x, *x1, *xe, y; ULong *x, *x1, *xe, y;
int n; int n;
x = x1 = b->x; x = x1 = b->x;
n = k >> kshift; n = k >> kshift;
if (n < b->wds) { if (n < b->wds) {
@ -49,24 +48,23 @@ rshift(Bigint *b, int k)
while(x < xe) { while(x < xe) {
*x1++ = (y | (*x << n)) & ALL_ON; *x1++ = (y | (*x << n)) & ALL_ON;
y = *x++ >> k; y = *x++ >> k;
} }
if ((*x1 = y) !=0) if ((*x1 = y) !=0)
x1++; x1++;
} }
else else
while(x < xe) while(x < xe)
*x1++ = *x++; *x1++ = *x++;
} }
if ((b->wds = x1 - b->x) == 0) if ((b->wds = x1 - b->x) == 0)
b->x[0] = 0; b->x[0] = 0;
} }
int int
trailz(Bigint *b) trailz(Bigint *b)
{ {
ULong L, *x, *xe; ULong L, *x, *xe;
int n = 0; int n = 0;
x = b->x; x = b->x;
xe = x + b->wds; xe = x + b->wds;
for(n = 0; x < xe && !*x; x++) for(n = 0; x < xe && !*x; x++)
@ -74,6 +72,6 @@ trailz(Bigint *b)
if (x < xe) { if (x < xe) {
L = *x; L = *x;
n += lo0bits(&L); n += lo0bits(&L);
}
return n;
} }
return n;
}

View file

@ -1,36 +1,36 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#if 0 #if 0
unsigned char hexdig[256]; unsigned char hexdig[256];

View file

@ -1,58 +1,56 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
static void static void
L_shift(ULong *x, ULong *x1, int i) L_shift(ULong *x, ULong *x1, int i)
{ {
int j; int j;
i = 8 - i; i = 8 - i;
i <<= 2; i <<= 2;
j = ULbits - i; j = ULbits - i;
do { do {
*x |= x[1] << j; *x |= x[1] << j;
x[1] >>= i; x[1] >>= i;
} while(++x < x1); } while(++x < x1);
} }
int int
hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0) hexnan( const char **sp, const FPI *fpi, ULong *x0)
{ {
ULong c, h, *x, *x1, *xe; ULong c, h, *x, *x1, *xe;
CONST char *s; const char *s;
int havedig, hd0, i, nbits; int havedig, hd0, i, nbits;
/**** if (!hexdig['0']) __gdtoa_hexdig_init(); ****/ /**** if (!hexdig['0']) __gdtoa_hexdig_init(); ****/
nbits = fpi->nbits; nbits = fpi->nbits;
x = x0 + (nbits >> kshift); x = x0 + (nbits >> kshift);
@ -63,15 +61,15 @@ hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0)
havedig = hd0 = i = 0; havedig = hd0 = i = 0;
s = *sp; s = *sp;
/* allow optional initial 0x or 0X */ /* allow optional initial 0x or 0X */
while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') { while((c = *(const unsigned char*)(s+1)) && c <= ' ') {
if (!c) if (!c)
goto retnan; goto retnan;
++s; ++s;
} }
if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')
&& *(CONST unsigned char*)(s+3) > ' ') && *(const unsigned char*)(s+3) > ' ')
s += 2; s += 2;
while((c = *(CONST unsigned char*)++s)) { while((c = *(const unsigned char*)++s)) {
if (!(h = hexdig[c])) { if (!(h = hexdig[c])) {
if (c <= ' ') { if (c <= ' ') {
if (hd0 < havedig) { if (hd0 < havedig) {
@ -80,49 +78,45 @@ hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0)
if (x <= x0) { if (x <= x0) {
i = 8; i = 8;
continue; continue;
} }
hd0 = havedig; hd0 = havedig;
*--x = 0; *--x = 0;
x1 = x; x1 = x;
i = 0; i = 0;
} }
while((c = *(CONST unsigned char*)(s+1)) <= ' ') { while((c = *(const unsigned char*)(s+1)) <= ' ') {
if (!c) if (!c)
goto retnan; goto retnan;
++s; ++s;
} }
if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')
&& *(CONST unsigned char*)(s+3) > ' ') && *(const unsigned char*)(s+3) > ' ')
s += 2; s += 2;
continue; continue;
} }
if (/*(*/ c == ')' && havedig) { if (/*(*/ c == ')' && havedig) {
*sp = s + 1; *sp = s + 1;
break; break;
} }
#ifndef GDTOA_NON_PEDANTIC_NANCHECK
do { do {
if (/*(*/ c == ')') { if (/*(*/ c == ')') {
*sp = s + 1; *sp = s + 1;
goto break2; goto break2;
} }
} while((c = *++s)); } while((c = *++s));
#endif retnan:
retnan:
return STRTOG_NaN; return STRTOG_NaN;
} }
havedig++; havedig++;
if (++i > 8) { if (++i > 8) {
if (x <= x0) if (x <= x0)
continue; continue;
i = 1; i = 1;
*--x = 0; *--x = 0;
}
*x = (*x << 4) | (h & 0xf);
} }
#ifndef GDTOA_NON_PEDANTIC_NANCHECK *x = (*x << 4) | (h & 0xf);
break2: }
#endif break2:
if (!havedig) if (!havedig)
return STRTOG_NaN; return STRTOG_NaN;
if (x < x1 && i < 8) if (x < x1 && i < 8)
@ -130,22 +124,22 @@ hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0)
if (x > x0) { if (x > x0) {
x1 = x0; x1 = x0;
do *x1++ = *x++; do *x1++ = *x++;
while(x <= xe); while(x <= xe);
do *x1++ = 0; do *x1++ = 0;
while(x1 <= xe); while(x1 <= xe);
} }
else { else {
/* truncate high-order word if necessary */ /* truncate high-order word if necessary */
if ( (i = nbits & (ULbits-1)) !=0) if ( (i = nbits & (ULbits-1)) !=0)
*xe &= ((ULong)0xffffffff) >> (ULbits - i); *xe &= ((ULong)0xffffffff) >> (ULbits - i);
} }
for(x1 = xe;; --x1) { for(x1 = xe;; --x1) {
if (*x1 != 0) if (*x1 != 0)
break; break;
if (x1 == x0) { if (x1 == x0) {
*x1 = 1; *x1 = 1;
break; break;
}
} }
return STRTOG_NaNbits;
} }
return STRTOG_NaNbits;
}

View file

@ -1,273 +1,129 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay. static ThInfo TI0;
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#ifndef Omit_Private_Memory
#ifndef PRIVATE_MEM
#define PRIVATE_MEM 2304
#endif
#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
static double private_mem[PRIVATE_mem], *pmem_next;
#endif
static ThInfo TI0;
#ifdef MULTIPLE_THREADS /*{{*/
static unsigned int maxthreads = 0;
static ThInfo *TI1;
static int TI0_used;
void
set_max_gdtoa_threads(unsigned int n)
{
size_t L;
if (n > maxthreads) {
L = n*sizeof(ThInfo);
if (TI1) {
TI1 = (ThInfo*)REALLOC(TI1, L);
memset(TI1 + maxthreads, 0, (n-maxthreads)*sizeof(ThInfo));
}
else {
TI1 = (ThInfo*)MALLOC(L);
if (TI0_used) {
memcpy(TI1, &TI0, sizeof(ThInfo));
if (n > 1)
memset(TI1 + 1, 0, L - sizeof(ThInfo));
memset(&TI0, 0, sizeof(ThInfo));
}
else
memset(TI1, 0, L);
}
maxthreads = n;
}
}
static ThInfo*
get_TI(void)
{
unsigned int thno = dtoa_get_threadno();
if (thno < maxthreads)
return TI1 + thno;
if (thno == 0)
TI0_used = 1;
return &TI0;
}
#define freelist TI->Freelist
#define p5s TI->P5s
#else /*}{*/
#define freelist TI0.Freelist
#define p5s TI0.P5s
#endif /*}}*/
Bigint * Bigint *
Balloc(int k MTd) Balloc(int k)
{ {
int x; int x;
Bigint *rv; Bigint *rv;
#ifndef Omit_Private_Memory if (k <= Kmax && (rv = TI0.Freelist[k]) != 0)
unsigned int len; TI0.Freelist[k] = rv->next;
#endif
static bool once;
if (!once) {
pmem_next = private_mem;
once = true;
}
#ifdef MULTIPLE_THREADS
ThInfo *TI;
if (!(TI = *PTI))
*PTI = TI = get_TI();
if (TI == &TI0)
ACQUIRE_DTOA_LOCK(0);
#endif
/* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
/* but this case seems very unlikely. */
if (k <= Kmax && (rv = freelist[k]) !=0) {
freelist[k] = rv->next;
}
else { else {
x = 1 << k; x = 1 << k;
#ifdef Omit_Private_Memory rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(ULong));
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
#else
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
/sizeof(double);
if (k <= Kmax && pmem_next - private_mem + len - PRIVATE_mem <= 0
#ifdef MULTIPLE_THREADS
&& TI == TI1
#endif
) {
rv = (Bigint*)pmem_next;
pmem_next += len;
}
else
rv = (Bigint*)MALLOC(len*sizeof(double));
#endif
rv->k = k; rv->k = k;
rv->maxwds = x; rv->maxwds = x;
} }
#ifdef MULTIPLE_THREADS
if (TI == &TI0)
FREE_DTOA_LOCK(0);
#endif
rv->sign = rv->wds = 0; rv->sign = rv->wds = 0;
return rv; return rv;
} }
void void
Bfree(Bigint *v MTd) Bfree(Bigint *v)
{ {
#ifdef MULTIPLE_THREADS
ThInfo *TI;
#endif
if (v) { if (v) {
if (v->k > Kmax) if (v->k > Kmax)
#ifdef FREE
FREE((void*)v);
#else
free((void*)v); free((void*)v);
#endif
else { else {
#ifdef MULTIPLE_THREADS v->next = TI0.Freelist[v->k];
if (!(TI = *PTI)) TI0.Freelist[v->k] = v;
*PTI = TI = get_TI();
if (TI == &TI0)
ACQUIRE_DTOA_LOCK(0);
#endif
v->next = freelist[v->k];
freelist[v->k] = v;
#ifdef MULTIPLE_THREADS
if (TI == &TI0)
FREE_DTOA_LOCK(0);
#endif
}
} }
} }
}
Bigint * Bigint *
multadd(Bigint *b, int m, int a MTd) /* multiply by m and add a */ multadd(Bigint *b, int m, int a) /* multiply by m and add a */
{ {
int i, wds; int i, wds;
#ifdef ULLong
ULong *x; ULong *x;
ULLong carry, y; ULLong carry, y;
#else
ULong carry, *x, y;
#ifdef Pack_32
ULong xi, z;
#endif
#endif
Bigint *b1; Bigint *b1;
wds = b->wds; wds = b->wds;
x = b->x; x = b->x;
i = 0; i = 0;
carry = a; carry = a;
do { do {
#ifdef ULLong
y = *x * (ULLong)m + carry; y = *x * (ULLong)m + carry;
carry = y >> 32; carry = y >> 32;
*x++ = y & 0xffffffffUL; *x++ = y & 0xffffffffUL;
#else }
#ifdef Pack_32 while(++i < wds);
xi = *x;
y = (xi & 0xffff) * m + carry;
z = (xi >> 16) * m + (y >> 16);
carry = z >> 16;
*x++ = (z << 16) + (y & 0xffff);
#else
y = *x * m + carry;
carry = y >> 16;
*x++ = y & 0xffff;
#endif
#endif
}
while(++i < wds);
if (carry) { if (carry) {
if (wds >= b->maxwds) { if (wds >= b->maxwds) {
b1 = Balloc(b->k+1 MTa); b1 = Balloc(b->k+1);
Bcopy(b1, b); Bcopy(b1, b);
Bfree(b MTa); Bfree(b);
b = b1; b = b1;
} }
b->x[wds++] = carry; b->x[wds++] = carry;
b->wds = wds; b->wds = wds;
}
return b;
} }
return b;
}
Bigint * Bigint *
i2b(int i MTd) i2b(int i)
{ {
Bigint *b; Bigint *b;
b = Balloc(1);
b = Balloc(1 MTa);
b->x[0] = i; b->x[0] = i;
b->wds = 1; b->wds = 1;
return b; return b;
} }
Bigint * Bigint *
mult(Bigint *a, Bigint *b MTd) mult(Bigint *a, Bigint *b)
{ {
Bigint *c; Bigint *c;
int k, wa, wb, wc; int k, wa, wb, wc;
ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
ULong y; ULong y;
#ifdef ULLong
ULLong carry, z; ULLong carry, z;
#else
ULong carry, z;
#ifdef Pack_32
ULong z2;
#endif
#endif
if (a->wds < b->wds) { if (a->wds < b->wds) {
c = a; c = a;
a = b; a = b;
b = c; b = c;
} }
k = a->k; k = a->k;
wa = a->wds; wa = a->wds;
wb = b->wds; wb = b->wds;
wc = wa + wb; wc = wa + wb;
if (wc > a->maxwds) if (wc > a->maxwds)
k++; k++;
c = Balloc(k MTa); c = Balloc(k);
for(x = c->x, xa = x + wc; x < xa; x++) for(x = c->x, xa = x + wc; x < xa; x++)
*x = 0; *x = 0;
xa = a->x; xa = a->x;
@ -275,7 +131,6 @@ mult(Bigint *a, Bigint *b MTd)
xb = b->x; xb = b->x;
xbe = xb + wb; xbe = xb + wb;
xc0 = c->x; xc0 = c->x;
#ifdef ULLong
for(; xb < xbe; xc0++) { for(; xb < xbe; xc0++) {
if ( (y = *xb++) !=0) { if ( (y = *xb++) !=0) {
x = xa; x = xa;
@ -285,188 +140,89 @@ mult(Bigint *a, Bigint *b MTd)
z = *x++ * (ULLong)y + *xc + carry; z = *x++ * (ULLong)y + *xc + carry;
carry = z >> 32; carry = z >> 32;
*xc++ = z & 0xffffffffUL; *xc++ = z & 0xffffffffUL;
} }
while(x < xae); while(x < xae);
*xc = carry; *xc = carry;
}
} }
#else }
#ifdef Pack_32
for(; xb < xbe; xb++, xc0++) {
if ( (y = *xb & 0xffff) !=0) {
x = xa;
xc = xc0;
carry = 0;
do {
z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
carry = z >> 16;
z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
carry = z2 >> 16;
Storeinc(xc, z2, z);
}
while(x < xae);
*xc = carry;
}
if ( (y = *xb >> 16) !=0) {
x = xa;
xc = xc0;
carry = 0;
z2 = *xc;
do {
z = (*x & 0xffff) * y + (*xc >> 16) + carry;
carry = z >> 16;
Storeinc(xc, z, z2);
z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
carry = z2 >> 16;
}
while(x < xae);
*xc = z2;
}
}
#else
for(; xb < xbe; xc0++) {
if ( (y = *xb++) !=0) {
x = xa;
xc = xc0;
carry = 0;
do {
z = *x++ * y + *xc + carry;
carry = z >> 16;
*xc++ = z & 0xffff;
}
while(x < xae);
*xc = carry;
}
}
#endif
#endif
for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
c->wds = wc; c->wds = wc;
return c; return c;
} }
Bigint * Bigint *
pow5mult(Bigint *b, int k MTd) pow5mult(Bigint *b, int k)
{ {
Bigint *b1, *p5, *p51; Bigint *b1, *p5, *p51;
#ifdef MULTIPLE_THREADS
ThInfo *TI;
#endif
int i; int i;
static const int p05[3] = { 5, 25, 125 }; static const int p05[3] = { 5, 25, 125 };
if ( (i = k & 3) !=0) if ( (i = k & 3) !=0)
b = multadd(b, p05[i-1], 0 MTa); b = multadd(b, p05[i-1], 0);
if (!(k >>= 2)) if (!(k >>= 2))
return b; return b;
#ifdef MULTIPLE_THREADS if ((p5 = TI0.P5s) == 0) {
if (!(TI = *PTI))
*PTI = TI = get_TI();
#endif
if ((p5 = p5s) == 0) {
/* first time */ /* first time */
#ifdef MULTIPLE_THREADS p5 = TI0.P5s = i2b(625);
if (!(TI = *PTI))
*PTI = TI = get_TI();
if (TI == &TI0)
ACQUIRE_DTOA_LOCK(1);
if (!(p5 = p5s)) {
p5 = p5s = i2b(625 MTa);
p5->next = 0;
}
if (TI == &TI0)
FREE_DTOA_LOCK(1);
#else
p5 = p5s = i2b(625);
p5->next = 0; p5->next = 0;
#endif }
}
for(;;) { for(;;) {
if (k & 1) { if (k & 1) {
b1 = mult(b, p5 MTa); b1 = mult(b, p5);
Bfree(b MTa); Bfree(b);
b = b1; b = b1;
} }
if (!(k >>= 1)) if (!(k >>= 1))
break; break;
if ((p51 = p5->next) == 0) { if ((p51 = p5->next) == 0) {
#ifdef MULTIPLE_THREADS p51 = p5->next = mult(p5,p5);
if (!TI && !(TI = *PTI))
*PTI = TI = get_TI();
if (TI == &TI0)
ACQUIRE_DTOA_LOCK(1);
if (!(p51 = p5->next)) {
p51 = p5->next = mult(p5,p5 MTa);
p51->next = 0;
}
if (TI == &TI0)
FREE_DTOA_LOCK(1);
#else
p51 = p5->next = mult(p5,p5 MTa);
p51->next = 0; p51->next = 0;
#endif
}
p5 = p51;
} }
return b; p5 = p51;
} }
return b;
}
Bigint * Bigint *
lshift(Bigint *b, int k MTd) lshift(Bigint *b, int k)
{ {
int i, k1, n, n1; int i, k1, n, n1;
Bigint *b1; Bigint *b1;
ULong *x, *x1, *xe, z; ULong *x, *x1, *xe, z;
n = k >> kshift; n = k >> kshift;
k1 = b->k; k1 = b->k;
n1 = n + b->wds + 1; n1 = n + b->wds + 1;
for(i = b->maxwds; n1 > i; i <<= 1) for(i = b->maxwds; n1 > i; i <<= 1)
k1++; k1++;
b1 = Balloc(k1 MTa); b1 = Balloc(k1);
x1 = b1->x; x1 = b1->x;
for(i = 0; i < n; i++) for(i = 0; i < n; i++)
*x1++ = 0; *x1++ = 0;
x = b->x; x = b->x;
xe = x + b->wds; xe = x + b->wds;
if (k &= kmask) { if (k &= kmask) {
#ifdef Pack_32
k1 = 32 - k; k1 = 32 - k;
z = 0; z = 0;
do { do {
*x1++ = *x << k | z; *x1++ = *x << k | z;
z = *x++ >> k1; z = *x++ >> k1;
} }
while(x < xe); while(x < xe);
if ((*x1 = z) !=0) if ((*x1 = z) !=0)
++n1; ++n1;
#else }
k1 = 16 - k;
z = 0;
do {
*x1++ = *x << k & 0xffff | z;
z = *x++ >> k1;
}
while(x < xe);
if (*x1 = z)
++n1;
#endif
}
else do else do
*x1++ = *x++; *x1++ = *x++;
while(x < xe); while(x < xe);
b1->wds = n1 - 1; b1->wds = n1 - 1;
Bfree(b MTa); Bfree(b);
return b1; return b1;
} }
int int
cmp(Bigint *a, Bigint *b) cmp(Bigint *a, Bigint *b)
{ {
ULong *xa, *xa0, *xb, *xb0; ULong *xa, *xa0, *xb, *xb0;
int i, j; int i, j;
i = a->wds; i = a->wds;
j = b->wds; j = b->wds;
#ifdef DEBUG #ifdef DEBUG
@ -486,41 +242,33 @@ cmp(Bigint *a, Bigint *b)
return *xa < *xb ? -1 : 1; return *xa < *xb ? -1 : 1;
if (xa <= xa0) if (xa <= xa0)
break; break;
}
return 0;
} }
return 0;
}
Bigint * Bigint *
diff(Bigint *a, Bigint *b MTd) diff(Bigint *a, Bigint *b)
{ {
Bigint *c; Bigint *c;
int i, wa, wb; int i, wa, wb;
ULong *xa, *xae, *xb, *xbe, *xc; ULong *xa, *xae, *xb, *xbe, *xc;
#ifdef ULLong
ULLong borrow, y; ULLong borrow, y;
#else
ULong borrow, y;
#ifdef Pack_32
ULong z;
#endif
#endif
i = cmp(a,b); i = cmp(a,b);
if (!i) { if (!i) {
c = Balloc(0 MTa); c = Balloc(0);
c->wds = 1; c->wds = 1;
c->x[0] = 0; c->x[0] = 0;
return c; return c;
} }
if (i < 0) { if (i < 0) {
c = a; c = a;
a = b; a = b;
b = c; b = c;
i = 1; i = 1;
} }
else else
i = 0; i = 0;
c = Balloc(a->k MTa); c = Balloc(a->k);
c->sign = i; c->sign = i;
wa = a->wds; wa = a->wds;
xa = a->x; xa = a->x;
@ -530,54 +278,22 @@ diff(Bigint *a, Bigint *b MTd)
xbe = xb + wb; xbe = xb + wb;
xc = c->x; xc = c->x;
borrow = 0; borrow = 0;
#ifdef ULLong
do { do {
y = (ULLong)*xa++ - *xb++ - borrow; y = (ULLong)*xa++ - *xb++ - borrow;
borrow = y >> 32 & 1UL; borrow = y >> 32 & 1UL;
*xc++ = y & 0xffffffffUL; *xc++ = y & 0xffffffffUL;
} }
while(xb < xbe); while(xb < xbe);
while(xa < xae) { while(xa < xae) {
y = *xa++ - borrow; y = *xa++ - borrow;
borrow = y >> 32 & 1UL; borrow = y >> 32 & 1UL;
*xc++ = y & 0xffffffffUL; *xc++ = y & 0xffffffffUL;
} }
#else
#ifdef Pack_32
do {
y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
borrow = (z & 0x10000) >> 16;
Storeinc(xc, z, y);
}
while(xb < xbe);
while(xa < xae) {
y = (*xa & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
z = (*xa++ >> 16) - borrow;
borrow = (z & 0x10000) >> 16;
Storeinc(xc, z, y);
}
#else
do {
y = *xa++ - *xb++ - borrow;
borrow = (y & 0x10000) >> 16;
*xc++ = y & 0xffff;
}
while(xb < xbe);
while(xa < xae) {
y = *xa++ - borrow;
borrow = (y & 0x10000) >> 16;
*xc++ = y & 0xffff;
}
#endif
#endif
while(!*--xc) while(!*--xc)
wa--; wa--;
c->wds = wa; c->wds = wa;
return c; return c;
} }
double double
b2d(Bigint *a, int *e) b2d(Bigint *a, int *e)
@ -585,13 +301,6 @@ b2d(Bigint *a, int *e)
ULong *xa, *xa0, w, y, z; ULong *xa, *xa0, w, y, z;
int k; int k;
U d; U d;
#ifdef VAX
ULong d0, d1;
#else
#define d0 word0(&d)
#define d1 word1(&d)
#endif
xa0 = a->x; xa0 = a->x;
xa = xa0 + a->wds; xa = xa0 + a->wds;
y = *--xa; y = *--xa;
@ -600,225 +309,76 @@ b2d(Bigint *a, int *e)
#endif #endif
k = hi0bits(y); k = hi0bits(y);
*e = 32 - k; *e = 32 - k;
#ifdef Pack_32
if (k < Ebits) { if (k < Ebits) {
d0 = Exp_1 | y >> (Ebits - k); word0(&d) = Exp_1 | y >> (Ebits - k);
w = xa > xa0 ? *--xa : 0; w = xa > xa0 ? *--xa : 0;
d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); word1(&d) = y << ((32-Ebits) + k) | w >> (Ebits - k);
goto ret_d; goto ret_d;
} }
z = xa > xa0 ? *--xa : 0; z = xa > xa0 ? *--xa : 0;
if (k -= Ebits) { if (k -= Ebits) {
d0 = Exp_1 | y << k | z >> (32 - k); word0(&d) = Exp_1 | y << k | z >> (32 - k);
y = xa > xa0 ? *--xa : 0; y = xa > xa0 ? *--xa : 0;
d1 = z << k | y >> (32 - k); word1(&d) = z << k | y >> (32 - k);
}
else {
d0 = Exp_1 | y;
d1 = z;
}
#else
if (k < Ebits + 16) {
z = xa > xa0 ? *--xa : 0;
d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
w = xa > xa0 ? *--xa : 0;
y = xa > xa0 ? *--xa : 0;
d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
goto ret_d;
}
z = xa > xa0 ? *--xa : 0;
w = xa > xa0 ? *--xa : 0;
k -= Ebits + 16;
d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
y = xa > xa0 ? *--xa : 0;
d1 = w << k + 16 | y << k;
#endif
ret_d:
#ifdef VAX
word0(&d) = d0 >> 16 | d0 << 16;
word1(&d) = d1 >> 16 | d1 << 16;
#endif
return dval(&d);
} }
#undef d0 else {
#undef d1 word0(&d) = Exp_1 | y;
word1(&d) = z;
}
ret_d:
return dval(&d);
}
Bigint * Bigint *
d2b(double dd, int *e, int *bits MTd) d2b(double dd, int *e, int *bits)
{ {
Bigint *b; Bigint *b;
U d; U d;
#ifndef Sudden_Underflow
int i; int i;
#endif
int de, k; int de, k;
ULong *x, y, z; ULong *x, y, z;
#ifdef VAX
ULong d0, d1;
#else
#define d0 word0(&d)
#define d1 word1(&d)
#endif
d.d = dd; d.d = dd;
#ifdef VAX b = Balloc(1);
d0 = word0(&d) >> 16 | word0(&d) << 16;
d1 = word1(&d) >> 16 | word1(&d) << 16;
#endif
#ifdef Pack_32
b = Balloc(1 MTa);
#else
b = Balloc(2 MTa);
#endif
x = b->x; x = b->x;
z = word0(&d) & Frac_mask;
z = d0 & Frac_mask; word0(&d) &= 0x7fffffff; /* clear sign bit, which we ignore */
d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ if ( (de = (int)(word0(&d) >> Exp_shift)) !=0)
#ifdef Sudden_Underflow
de = (int)(d0 >> Exp_shift);
#ifndef IBM
z |= Exp_msk11;
#endif
#else
if ( (de = (int)(d0 >> Exp_shift)) !=0)
z |= Exp_msk1; z |= Exp_msk1;
#endif if ( (y = word1(&d)) !=0) {
#ifdef Pack_32
if ( (y = d1) !=0) {
if ( (k = lo0bits(&y)) !=0) { if ( (k = lo0bits(&y)) !=0) {
x[0] = y | z << (32 - k); x[0] = y | z << (32 - k);
z >>= k; z >>= k;
} }
else else
x[0] = y; x[0] = y;
#ifndef Sudden_Underflow i = b->wds = (x[1] = z) !=0 ? 2 : 1;
i = }
#endif
b->wds = (x[1] = z) !=0 ? 2 : 1;
}
else { else {
k = lo0bits(&z); k = lo0bits(&z);
x[0] = z; x[0] = z;
#ifndef Sudden_Underflow i = b->wds = 1;
i =
#endif
b->wds = 1;
k += 32; k += 32;
} }
#else
if ( (y = d1) !=0) {
if ( (k = lo0bits(&y)) !=0)
if (k >= 16) {
x[0] = y | z << 32 - k & 0xffff;
x[1] = z >> k - 16 & 0xffff;
x[2] = z >> k;
i = 2;
}
else {
x[0] = y & 0xffff;
x[1] = y >> 16 | z << 16 - k & 0xffff;
x[2] = z >> k & 0xffff;
x[3] = z >> k+16;
i = 3;
}
else {
x[0] = y & 0xffff;
x[1] = y >> 16;
x[2] = z & 0xffff;
x[3] = z >> 16;
i = 3;
}
}
else {
#ifdef DEBUG
if (!z)
Bug("Zero passed to d2b");
#endif
k = lo0bits(&z);
if (k >= 16) {
x[0] = z;
i = 0;
}
else {
x[0] = z & 0xffff;
x[1] = z >> 16;
i = 1;
}
k += 32;
}
while(!x[i])
--i;
b->wds = i + 1;
#endif
#ifndef Sudden_Underflow
if (de) { if (de) {
#endif
#ifdef IBM
*e = (de - Bias - (P-1) << 2) + k;
*bits = 4*P + 8 - k - hi0bits(word0(&d) & Frac_mask);
#else
*e = de - Bias - (P-1) + k; *e = de - Bias - (P-1) + k;
*bits = P - k; *bits = P - k;
#endif }
#ifndef Sudden_Underflow
}
else { else {
*e = de - Bias - (P-1) + 1 + k; *e = de - Bias - (P-1) + 1 + k;
#ifdef Pack_32
*bits = 32*i - hi0bits(x[i-1]); *bits = 32*i - hi0bits(x[i-1]);
#else }
*bits = (i+2)*16 - hi0bits(x[i]);
#endif
}
#endif
return b; return b;
} }
#undef d0
#undef d1
CONST double const double
#ifdef IEEE_Arith
bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
};
#else
#ifdef IBM
bigtens[] = { 1e16, 1e32, 1e64 };
CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
#else
bigtens[] = { 1e16, 1e32 };
CONST double tinytens[] = { 1e-16, 1e-32 };
#endif
#endif
CONST double const double
tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
const double
tens[] = { tens[] = {
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1e20, 1e21, 1e22 1e20, 1e21, 1e22
#ifdef VAX };
, 1e23, 1e24
#endif
};
char *
__gdtoa_strcp(char *a, CONST char *b)
{
while((*a = *b++))
a++;
return a;
}
#ifdef NO_STRING_H
Char *
__gdtoa_memcpy(void *a1, void *b1, size_t len)
{
char *a = (char*)a1, *ae = a + len;
char *b = (char*)b1, *a0 = a;
while(a < ae)
*a++ = *b++;
return a0;
}
#endif /* NO_STRING_H */

View file

@ -1,153 +1,112 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
Bigint * Bigint *
s2b(CONST char *s, int nd0, int nd, ULong y9, int dplen MTd) s2b(const char *s, int nd0, int nd, ULong y9, int dplen)
{ {
Bigint *b; Bigint *b;
int i, k; int i, k;
Long x, y; Long x, y;
x = (nd + 8) / 9; x = (nd + 8) / 9;
for(k = 0, y = 1; x > y; y <<= 1, k++) ; for(k = 0, y = 1; x > y; y <<= 1, k++) ;
#ifdef Pack_32 b = Balloc(k);
b = Balloc(k MTa);
b->x[0] = y9; b->x[0] = y9;
b->wds = 1; b->wds = 1;
#else
b = Balloc(k+1 MTa);
b->x[0] = y9 & 0xffff;
b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
#endif
i = 9; i = 9;
if (9 < nd0) { if (9 < nd0) {
s += 9; s += 9;
do b = multadd(b, 10, *s++ - '0' MTa); do b = multadd(b, 10, *s++ - '0');
while(++i < nd0); while(++i < nd0);
s += dplen; s += dplen;
} }
else else
s += dplen + 9; s += dplen + 9;
for(; i < nd; i++) for(; i < nd; i++)
b = multadd(b, 10, *s++ - '0' MTa); b = multadd(b, 10, *s++ - '0');
return b; return b;
} }
double double
ratio(Bigint *a, Bigint *b) ratio(Bigint *a, Bigint *b)
{ {
U da, db; U da, db;
int k, ka, kb; int k, ka, kb;
dval(&da) = b2d(a, &ka); dval(&da) = b2d(a, &ka);
dval(&db) = b2d(b, &kb); dval(&db) = b2d(b, &kb);
k = ka - kb + ULbits*(a->wds - b->wds); k = ka - kb + ULbits*(a->wds - b->wds);
#ifdef IBM
if (k > 0) {
word0(&da) += (k >> 2)*Exp_msk1;
if (k &= 3)
dval(&da) *= 1 << k;
}
else {
k = -k;
word0(&db) += (k >> 2)*Exp_msk1;
if (k &= 3)
dval(&db) *= 1 << k;
}
#else
if (k > 0) if (k > 0)
word0(&da) += k*Exp_msk1; word0(&da) += k*Exp_msk1;
else { else {
k = -k; k = -k;
word0(&db) += k*Exp_msk1; word0(&db) += k*Exp_msk1;
}
#endif
return dval(&da) / dval(&db);
} }
return dval(&da) / dval(&db);
#ifdef INFNAN_CHECK }
int int
match(CONST char **sp, char *t) match(const char **sp, char *t)
{ {
int c, d; int c, d;
CONST char *s = *sp; const char *s = *sp;
while( (d = *t++) !=0) { while( (d = *t++) !=0) {
if ((c = *++s) >= 'A' && c <= 'Z') if ((c = *++s) >= 'A' && c <= 'Z')
c += 'a' - 'A'; c += 'a' - 'A';
if (c != d) if (c != d)
return 0; return 0;
} }
*sp = s + 1; *sp = s + 1;
return 1; return 1;
} }
#endif /* INFNAN_CHECK */
void void
copybits(ULong *c, int n, Bigint *b) copybits(ULong *c, int n, Bigint *b)
{ {
ULong *ce, *x, *xe; ULong *ce, *x, *xe;
#ifdef Pack_16
int nw, nw1;
#endif
ce = c + ((n-1) >> kshift) + 1; ce = c + ((n-1) >> kshift) + 1;
x = b->x; x = b->x;
#ifdef Pack_32
xe = x + b->wds; xe = x + b->wds;
while(x < xe) while(x < xe)
*c++ = *x++; *c++ = *x++;
#else
nw = b->wds;
nw1 = nw & 1;
for(xe = x + (nw - nw1); x < xe; x += 2)
Storeinc(c, x[1], x[0]);
if (nw1)
*c++ = *x;
#endif
while(c < ce) while(c < ce)
*c++ = 0; *c++ = 0;
} }
ULong ULong
any_on(Bigint *b, int k) any_on(Bigint *b, int k)
{ {
int n, nwds; int n, nwds;
ULong *x, *x0, x1, x2; ULong *x, *x0, x1, x2;
x = b->x; x = b->x;
nwds = b->wds; nwds = b->wds;
n = k >> kshift; n = k >> kshift;
@ -159,11 +118,11 @@ any_on(Bigint *b, int k)
x1 <<= k; x1 <<= k;
if (x1 != x2) if (x1 != x2)
return 1; return 1;
} }
x0 = x; x0 = x;
x += n; x += n;
while(x > x0) while(x > x0)
if (*--x) if (*--x)
return 1; return 1;
return 0; return 0;
} }

View file

@ -1,60 +1,56 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int int
strtoId(CONST char *s, char **sp, double *f0, double *f1) strtoId(const char *s, char **sp, double *f0, double *f1)
{ {
static const FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ }; static const FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ };
Long exp[2]; Long exp[2];
Bigint *B[2]; Bigint *B[2];
int k, rv[2]; int k, rv[2];
#ifdef MULTIPLE_THREADS B[0] = Balloc(1);
ThInfo *TI = 0;
#endif
B[0] = Balloc(1 MTb);
B[0]->wds = 2; B[0]->wds = 2;
k = strtoIg(s, sp, &fpi, exp, B, rv); k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtod((ULong*)f0, B[0]->x, exp[0], rv[0]); ULtod((ULong*)f0, B[0]->x, exp[0], rv[0]);
Bfree(B[0] MTb); Bfree(B[0]);
if (B[1]) { if (B[1]) {
ULtod((ULong*)f1, B[1]->x, exp[1], rv[1]); ULtod((ULong*)f1, B[1]->x, exp[1], rv[1]);
Bfree(B[1] MTb); Bfree(B[1]);
} }
else { else {
((ULong*)f1)[0] = ((ULong*)f0)[0]; ((ULong*)f1)[0] = ((ULong*)f0)[0];
((ULong*)f1)[1] = ((ULong*)f0)[1]; ((ULong*)f1)[1] = ((ULong*)f0)[1];
}
return k;
} }
return k;
}

View file

@ -1,66 +1,58 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int int
strtoIdd(CONST char *s, char **sp, double *f0, double *f1) strtoIdd(const char *s, char **sp, double *f0, double *f1)
{ {
#ifdef Sudden_Underflow
static const FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1, 0 /*unused*/ };
#else
static const FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0, 0 /*unused*/ }; static const FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0, 0 /*unused*/ };
#endif
Long exp[2]; Long exp[2];
Bigint *B[2]; Bigint *B[2];
int k, rv[2]; int k, rv[2];
#ifdef MULTIPLE_THREADS B[0] = Balloc(2);
ThInfo *TI = 0;
#endif
B[0] = Balloc(2 MTb);
B[0]->wds = 4; B[0]->wds = 4;
k = strtoIg(s, sp, &fpi, exp, B, rv); k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtodd((ULong*)f0, B[0]->x, exp[0], rv[0]); ULtodd((ULong*)f0, B[0]->x, exp[0], rv[0]);
Bfree(B[0] MTb); Bfree(B[0]);
if (B[1]) { if (B[1]) {
ULtodd((ULong*)f1, B[1]->x, exp[1], rv[1]); ULtodd((ULong*)f1, B[1]->x, exp[1], rv[1]);
Bfree(B[1] MTb); Bfree(B[1]);
} }
else { else {
((ULong*)f1)[0] = ((ULong*)f0)[0]; ((ULong*)f1)[0] = ((ULong*)f0)[0];
((ULong*)f1)[1] = ((ULong*)f0)[1]; ((ULong*)f1)[1] = ((ULong*)f0)[1];
((ULong*)f1)[2] = ((ULong*)f0)[2]; ((ULong*)f1)[2] = ((ULong*)f0)[2];
((ULong*)f1)[3] = ((ULong*)f0)[3]; ((ULong*)f1)[3] = ((ULong*)f0)[3];
}
return k;
} }
return k;
}

View file

@ -1,58 +1,54 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int int
strtoIf(CONST char *s, char **sp, float *f0, float *f1) strtoIf(const char *s, char **sp, float *f0, float *f1)
{ {
static const FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ }; static const FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ };
Long exp[2]; Long exp[2];
Bigint *B[2]; Bigint *B[2];
int k, rv[2]; int k, rv[2];
#ifdef MULTIPLE_THREADS B[0] = Balloc(0);
ThInfo *TI = 0;
#endif
B[0] = Balloc(0 MTb);
B[0]->wds = 1; B[0]->wds = 1;
k = strtoIg(s, sp, &fpi, exp, B, rv); k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtof((ULong*)f0, B[0]->x, exp[0], rv[0]); ULtof((ULong*)f0, B[0]->x, exp[0], rv[0]);
Bfree(B[0] MTb); Bfree(B[0]);
if (B[1]) { if (B[1]) {
ULtof((ULong*)f1, B[1]->x, exp[1], rv[1]); ULtof((ULong*)f1, B[1]->x, exp[1], rv[1]);
Bfree(B[1] MTb); Bfree(B[1]);
} }
else else
*(ULong*)f1 = *(ULong*)f0; *(ULong*)f1 = *(ULong*)f0;
return k; return k;
} }

View file

@ -1,57 +1,53 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int int
strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *rvp) strtoIg(const char *s00, char **se, const FPI *fpi, Long *exp, Bigint **B, int *rvp)
{ {
Bigint *b, *b1; Bigint *b, *b1;
int i, nb, nw, nw1, rv, rv1, swap; int i, nb, nw, nw1, rv, rv1, swap;
unsigned int nb1, nb11; unsigned int nb1, nb11;
Long e1; Long e1;
#ifdef MULTIPLE_THREADS
ThInfo *TI = 0;
#endif
b = *B; b = *B;
rv = strtodg(s00, se, fpi, exp, b->x); rv = strtodg(s00, se, fpi, exp, b->x);
if (!(rv & STRTOG_Inexact)) { if (!(rv & STRTOG_Inexact)) {
B[1] = 0; B[1] = 0;
return *rvp = rv; return *rvp = rv;
} }
e1 = exp[0]; e1 = exp[0];
rv1 = rv ^ STRTOG_Inexact; rv1 = rv ^ STRTOG_Inexact;
b1 = Balloc(b->k MTb); b1 = Balloc(b->k);
Bcopy(b1, b); Bcopy(b1, b);
nb = fpi->nbits; nb = fpi->nbits;
nb1 = nb & 31; nb1 = nb & 31;
@ -60,7 +56,7 @@ strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *
nw1 = nw - 1; nw1 = nw - 1;
if (rv & STRTOG_Inexlo) { if (rv & STRTOG_Inexlo) {
swap = 0; swap = 0;
b1 = increment(b1 MTb); b1 = increment(b1);
if ((rv & STRTOG_Retmask) == STRTOG_Zero) { if ((rv & STRTOG_Retmask) == STRTOG_Zero) {
if (fpi->sudden_underflow) { if (fpi->sudden_underflow) {
b1->x[0] = 0; b1->x[0] = 0;
@ -68,41 +64,41 @@ strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *
rv1 += STRTOG_Normal - STRTOG_Zero; rv1 += STRTOG_Normal - STRTOG_Zero;
rv1 &= ~STRTOG_Underflow; rv1 &= ~STRTOG_Underflow;
goto swapcheck; goto swapcheck;
} }
rv1 &= STRTOG_Inexlo | STRTOG_Underflow | STRTOG_Zero | STRTOG_Neg; rv1 &= STRTOG_Inexlo | STRTOG_Underflow | STRTOG_Zero | STRTOG_Neg;
rv1 |= STRTOG_Inexhi | STRTOG_Denormal; rv1 |= STRTOG_Inexhi | STRTOG_Denormal;
goto swapcheck; goto swapcheck;
} }
if (b1->wds > nw if (b1->wds > nw
|| (nb1 && b1->x[nw1] & 1L << nb1)) { || (nb1 && b1->x[nw1] & 1L << nb1)) {
if (++e1 > fpi->emax) if (++e1 > fpi->emax)
rv1 = STRTOG_Infinite | STRTOG_Inexhi; rv1 = STRTOG_Infinite | STRTOG_Inexhi;
rshift(b1, 1); rshift(b1, 1);
} }
else if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { else if ((rv & STRTOG_Retmask) == STRTOG_Denormal) {
if (b1->x[nw1] & 1L << nb11) { if (b1->x[nw1] & 1L << nb11) {
rv1 += STRTOG_Normal - STRTOG_Denormal; rv1 += STRTOG_Normal - STRTOG_Denormal;
rv1 &= ~STRTOG_Underflow; rv1 &= ~STRTOG_Underflow;
}
} }
} }
}
else { else {
swap = STRTOG_Neg; swap = STRTOG_Neg;
if ((rv & STRTOG_Retmask) == STRTOG_Infinite) { if ((rv & STRTOG_Retmask) == STRTOG_Infinite) {
b1 = set_ones(b1, nb MTb); b1 = set_ones(b1, nb);
e1 = fpi->emax; e1 = fpi->emax;
rv1 = STRTOG_Normal | STRTOG_Inexlo | (rv & STRTOG_Neg); rv1 = STRTOG_Normal | STRTOG_Inexlo | (rv & STRTOG_Neg);
goto swapcheck; goto swapcheck;
} }
decrement(b1); decrement(b1);
if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { if ((rv & STRTOG_Retmask) == STRTOG_Denormal) {
for(i = nw1; !b1->x[i]; --i) for(i = nw1; !b1->x[i]; --i)
if (!i) { if (!i) {
rv1 = STRTOG_Zero | STRTOG_Inexlo | (rv & STRTOG_Neg); rv1 = STRTOG_Zero | STRTOG_Inexlo | (rv & STRTOG_Neg);
break; break;
} }
goto swapcheck; goto swapcheck;
} }
if (!(b1->x[nw1] & 1L << nb11)) { if (!(b1->x[nw1] & 1L << nb11)) {
if (e1 == fpi->emin) { if (e1 == fpi->emin) {
if (fpi->sudden_underflow) if (fpi->sudden_underflow)
@ -110,15 +106,15 @@ strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *
else else
rv1 += STRTOG_Denormal - STRTOG_Normal; rv1 += STRTOG_Denormal - STRTOG_Normal;
rv1 |= STRTOG_Underflow; rv1 |= STRTOG_Underflow;
} }
else { else {
b1 = lshift(b1, 1 MTb); b1 = lshift(b1, 1);
b1->x[0] |= 1; b1->x[0] |= 1;
--e1; --e1;
}
} }
} }
swapcheck: }
swapcheck:
if (swap ^ (rv & STRTOG_Neg)) { if (swap ^ (rv & STRTOG_Neg)) {
rvp[0] = rv1; rvp[0] = rv1;
rvp[1] = rv; rvp[1] = rv;
@ -126,12 +122,12 @@ strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *
B[1] = b; B[1] = b;
exp[1] = exp[0]; exp[1] = exp[0];
exp[0] = e1; exp[0] = e1;
} }
else { else {
rvp[0] = rv; rvp[0] = rv;
rvp[1] = rv1; rvp[1] = rv1;
B[1] = b1; B[1] = b1;
exp[1] = e1; exp[1] = e1;
}
return rv;
} }
return rv;
}

View file

@ -1,64 +1,60 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int int
strtoIx(CONST char *s, char **sp, void *a, void *b) strtoIx(const char *s, char **sp, void *a, void *b)
{ {
static const FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ }; static const FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ };
Long exp[2]; Long exp[2];
Bigint *B[2]; Bigint *B[2];
int k, rv[2]; int k, rv[2];
UShort *L = (UShort *)a, *M = (UShort *)b; UShort *L = (UShort *)a, *M = (UShort *)b;
#ifdef MULTIPLE_THREADS B[0] = Balloc(1);
ThInfo *TI = 0;
#endif
B[0] = Balloc(1 MTb);
B[0]->wds = 2; B[0]->wds = 2;
k = strtoIg(s, sp, &fpi, exp, B, rv); k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtox(L, B[0]->x, exp[0], rv[0]); ULtox(L, B[0]->x, exp[0], rv[0]);
Bfree(B[0] MTb); Bfree(B[0]);
if (B[1]) { if (B[1]) {
ULtox(M, B[1]->x, exp[1], rv[1]); ULtox(M, B[1]->x, exp[1], rv[1]);
Bfree(B[1] MTb); Bfree(B[1]);
} }
else { else {
M[0] = L[0]; M[0] = L[0];
M[1] = L[1]; M[1] = L[1];
M[2] = L[2]; M[2] = L[2];
M[3] = L[3]; M[3] = L[3];
M[4] = L[4]; M[4] = L[4];
}
return k;
} }
return k;
}

File diff suppressed because it is too large Load diff

View file

@ -1,156 +1,113 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
static double static double
ulpdown(U *d) ulpdown(U *d)
{ {
double u; double u;
ULong *L = d->L; ULong *L = d->L;
u = ulp(d); u = ulp(d);
if (!(L[_1] | (L[_0] & 0xfffff)) if (!(L[0] | (L[1] & 0xfffff))
&& (L[_0] & 0x7ff00000) > 0x00100000) && (L[1] & 0x7ff00000) > 0x00100000)
u *= 0.5; u *= 0.5;
return u; return u;
} }
int int
strtodI(CONST char *s, char **sp, double *dd) strtodI(const char *s, char **sp, double *dd)
{ {
static const FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ }; static const FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ };
ULong bits[2], sign; ULong bits[2], sign;
Long exp; Long exp;
int j, k; int j, k;
U *u; U *u;
k = strtodg(s, sp, &fpi, &exp, bits); k = strtodg(s, sp, &fpi, &exp, bits);
u = (U*)dd; u = (U*)dd;
sign = k & STRTOG_Neg ? 0x80000000L : 0; sign = k & STRTOG_Neg ? 0x80000000L : 0;
switch(k & STRTOG_Retmask) { switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber: case STRTOG_NoNumber:
dval(&u[0]) = dval(&u[1]) = 0.; dval(&u[0]) = dval(&u[1]) = 0.;
break; break;
case STRTOG_Zero:
case STRTOG_Zero:
dval(&u[0]) = dval(&u[1]) = 0.; dval(&u[0]) = dval(&u[1]) = 0.;
#ifdef Sudden_Underflow
if (k & STRTOG_Inexact) {
if (sign)
word0(&u[0]) = 0x80100000L;
else
word0(&u[1]) = 0x100000L;
}
break;
#else
goto contain; goto contain;
#endif case STRTOG_Denormal:
case STRTOG_Denormal:
word1(&u[0]) = bits[0]; word1(&u[0]) = bits[0];
word0(&u[0]) = bits[1]; word0(&u[0]) = bits[1];
goto contain; goto contain;
case STRTOG_Normal:
case STRTOG_Normal:
word1(&u[0]) = bits[0]; word1(&u[0]) = bits[0];
word0(&u[0]) = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); word0(&u[0]) = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
contain: contain:
j = k & STRTOG_Inexact; j = k & STRTOG_Inexact;
if (sign) { if (sign) {
word0(&u[0]) |= sign; word0(&u[0]) |= sign;
j = STRTOG_Inexact - j; j = STRTOG_Inexact - j;
} }
switch(j) { switch(j) {
case STRTOG_Inexlo: case STRTOG_Inexlo:
#ifdef Sudden_Underflow
if ((u->L[_0] & 0x7ff00000) < 0x3500000) {
word0(&u[1]) = word0(&u[0]) + 0x3500000;
word1(&u[1]) = word1(&u[0]);
dval(&u[1]) += ulp(&u[1]);
word0(&u[1]) -= 0x3500000;
if (!(word0(&u[1]) & 0x7ff00000)) {
word0(&u[1]) = sign;
word1(&u[1]) = 0;
}
}
else
#endif
dval(&u[1]) = dval(&u[0]) + ulp(&u[0]); dval(&u[1]) = dval(&u[0]) + ulp(&u[0]);
break; break;
case STRTOG_Inexhi: case STRTOG_Inexhi:
dval(&u[1]) = dval(&u[0]); dval(&u[1]) = dval(&u[0]);
#ifdef Sudden_Underflow
if ((word0(&u[0]) & 0x7ff00000) < 0x3500000) {
word0(&u[0]) += 0x3500000;
dval(&u[0]) -= ulpdown(u);
word0(&u[0]) -= 0x3500000;
if (!(word0(&u[0]) & 0x7ff00000)) {
word0(&u[0]) = sign;
word1(&u[0]) = 0;
}
}
else
#endif
dval(&u[0]) -= ulpdown(u); dval(&u[0]) -= ulpdown(u);
break; break;
default: default:
dval(&u[1]) = dval(&u[0]); dval(&u[1]) = dval(&u[0]);
} }
break; break;
case STRTOG_Infinite:
case STRTOG_Infinite:
word0(&u[0]) = word0(&u[1]) = sign | 0x7ff00000; word0(&u[0]) = word0(&u[1]) = sign | 0x7ff00000;
word1(&u[0]) = word1(&u[1]) = 0; word1(&u[0]) = word1(&u[1]) = 0;
if (k & STRTOG_Inexact) { if (k & STRTOG_Inexact) {
if (sign) { if (sign) {
word0(&u[1]) = 0xffefffffL; word0(&u[1]) = 0xffefffffL;
word1(&u[1]) = 0xffffffffL; word1(&u[1]) = 0xffffffffL;
} }
else { else {
word0(&u[0]) = 0x7fefffffL; word0(&u[0]) = 0x7fefffffL;
word1(&u[0]) = 0xffffffffL; word1(&u[0]) = 0xffffffffL;
}
} }
}
break; break;
case STRTOG_NaN:
case STRTOG_NaN:
u->L[0] = (u+1)->L[0] = d_QNAN0; u->L[0] = (u+1)->L[0] = d_QNAN0;
u->L[1] = (u+1)->L[1] = d_QNAN1; u->L[1] = (u+1)->L[1] = d_QNAN1;
break; break;
case STRTOG_NaNbits:
case STRTOG_NaNbits:
word0(&u[0]) = word0(&u[1]) = 0x7ff00000 | sign | bits[1]; word0(&u[0]) = word0(&u[1]) = 0x7ff00000 | sign | bits[1];
word1(&u[0]) = word1(&u[1]) = bits[0]; word1(&u[0]) = word1(&u[1]) = bits[0];
}
return k;
} }
return k;
}

File diff suppressed because it is too large Load diff

View file

@ -1,84 +1,76 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 2004 by David M. Gay.
All Rights Reserved
Based on material in the rest of /netlib/fp/gdota.tar.gz,
which is copyright (C) 1998, 2000 by Lucent Technologies.
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* This is a variant of strtod that works on Intel ia32 systems */ /* This is a variant of strtod that works on Intel ia32 systems */
/* with the default extended-precision arithmetic -- it does not */ /* with the default extended-precision arithmetic -- it does not */
/* require setting the precision control to 53 bits. */ /* require setting the precision control to 53 bits. */
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
double double
strtod(CONST char *s, char **sp) strtod(const char *s, char **sp)
{ {
static const FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ }; static const FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ };
ULong bits[2]; ULong bits[2];
Long exp; Long exp;
int k; int k;
union { ULong L[2]; double d; } u; union { ULong L[2]; double d; } u;
k = strtodg(s, sp, &fpi, &exp, bits); k = strtodg(s, sp, &fpi, &exp, bits);
switch(k & STRTOG_Retmask) { switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber: case STRTOG_NoNumber:
case STRTOG_Zero: case STRTOG_Zero:
u.L[0] = u.L[1] = 0; u.L[0] = u.L[1] = 0;
break; break;
case STRTOG_Normal:
case STRTOG_Normal: u.L[0] = bits[0];
u.L[_1] = bits[0]; u.L[1] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
u.L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
break; break;
case STRTOG_Denormal:
case STRTOG_Denormal: u.L[0] = bits[0];
u.L[_1] = bits[0]; u.L[1] = bits[1];
u.L[_0] = bits[1];
break; break;
case STRTOG_Infinite:
case STRTOG_Infinite: u.L[1] = 0x7ff00000;
u.L[_0] = 0x7ff00000; u.L[0] = 0;
u.L[_1] = 0;
break; break;
case STRTOG_NaN:
case STRTOG_NaN:
u.L[0] = d_QNAN0; u.L[0] = d_QNAN0;
u.L[1] = d_QNAN1; u.L[1] = d_QNAN1;
break; break;
case STRTOG_NaNbits:
case STRTOG_NaNbits: u.L[1] = 0x7ff00000 | bits[1];
u.L[_0] = 0x7ff00000 | bits[1]; u.L[0] = bits[0];
u.L[_1] = bits[0];
}
if (k & STRTOG_Neg)
u.L[_0] |= 0x80000000L;
return u.d;
} }
if (k & STRTOG_Neg)
u.L[1] |= 0x80000000L;
return u.d;
}

View file

@ -1,76 +1,67 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
float float
strtof(CONST char *s, char **sp) strtof(const char *s, char **sp)
{ {
static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ }; static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ };
ULong bits[1]; ULong bits[1];
Long exp; Long exp;
int k; int k;
union { ULong L[1]; float f; } u; union { ULong L[1]; float f; } u;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc" #include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
k = strtodg(s, sp, fpi, &exp, bits); k = strtodg(s, sp, fpi, &exp, bits);
switch(k & STRTOG_Retmask) { switch(k & STRTOG_Retmask) {
default: /* unused */ default: /* unused */
case STRTOG_NoNumber: case STRTOG_NoNumber:
case STRTOG_Zero: case STRTOG_Zero:
u.L[0] = 0; u.L[0] = 0;
break; break;
case STRTOG_Normal:
case STRTOG_Normal: case STRTOG_NaNbits:
case STRTOG_NaNbits:
u.L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23); u.L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23);
break; break;
case STRTOG_Denormal:
case STRTOG_Denormal:
u.L[0] = bits[0]; u.L[0] = bits[0];
break; break;
case STRTOG_Infinite:
case STRTOG_Infinite:
u.L[0] = 0x7f800000; u.L[0] = 0x7f800000;
break; break;
case STRTOG_NaN:
case STRTOG_NaN:
u.L[0] = f_QNAN; u.L[0] = f_QNAN;
} }
if (k & STRTOG_Neg) if (k & STRTOG_Neg)
u.L[0] |= 0x80000000L; u.L[0] |= 0x80000000L;
return u.f; return u.f;
} }

View file

@ -1,12 +1,34 @@
#if 0 /*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
/*─────────────────────────────────────────────────────────────────╗ vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
To the extent possible under law, Justine Tunney has waived
all copyright and related or neighboring rights to this file,
as it is written in the following disclaimers: The author of this software is David M. Gay.
http://unlicense.org/ │ Please send bug reports to David M. Gay <dmg@acm.org>
http://creativecommons.org/publicdomain/zero/1.0/ │ or Justine Tunney <jtunney@gmail.com>
*/
#endif Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.h" #include "third_party/gdtoa/gdtoa.h"
/** /**

View file

@ -1,51 +1,46 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int int
strtopd(CONST char *s, char **sp, double *d) strtopd(const char *s, char **sp, double *d)
{ {
static const FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ }; static const FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ };
ULong bits[2]; ULong bits[2];
Long exp; Long exp;
int k; int k;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc" #include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
k = strtodg(s, sp, fpi, &exp, bits); k = strtodg(s, sp, fpi, &exp, bits);
ULtod((ULong*)d, bits, exp, k); ULtod((ULong*)d, bits, exp, k);
return k; return k;
} }

View file

@ -1,111 +1,100 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int int
strtopdd(CONST char *s, char **sp, double *dd) strtopdd(const char *s, char **sp, double *dd)
{ {
#ifdef Sudden_Underflow
static const FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1, 0 /*unused*/ };
#else
static const FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0, 0 /*unused*/ }; static const FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0, 0 /*unused*/ };
#endif
ULong bits[4]; ULong bits[4];
Long exp; Long exp;
int i, j, rv; int i, j, rv;
typedef union { typedef union {
double d[2]; double d[2];
ULong L[4]; ULong L[4];
} U; } U;
U *u; U *u;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc" #include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
rv = strtodg(s, sp, fpi, &exp, bits); rv = strtodg(s, sp, fpi, &exp, bits);
u = (U*)dd; u = (U*)dd;
switch(rv & STRTOG_Retmask) { switch(rv & STRTOG_Retmask) {
case STRTOG_NoNumber: case STRTOG_NoNumber:
case STRTOG_Zero: case STRTOG_Zero:
u->d[0] = u->d[1] = 0.; u->d[0] = u->d[1] = 0.;
break; break;
case STRTOG_Normal:
case STRTOG_Normal: u->L[0] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL;
u->L[_1] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL; u->L[1] = (bits[2] >> 21) | ((bits[3] << 11) & 0xfffff)
u->L[_0] = (bits[2] >> 21) | ((bits[3] << 11) & 0xfffff) | ((exp + 0x3ff + 105) << 20);
| ((exp + 0x3ff + 105) << 20);
exp += 0x3ff + 52; exp += 0x3ff + 52;
if (bits[1] &= 0x1fffff) { if (bits[1] &= 0x1fffff) {
i = hi0bits(bits[1]) - 11; i = hi0bits(bits[1]) - 11;
if (i >= exp) { if (i >= exp) {
i = exp - 1; i = exp - 1;
exp = 0; exp = 0;
} }
else else
exp -= i; exp -= i;
if (i > 0) { if (i > 0) {
bits[1] = bits[1] << i | bits[0] >> (32-i); bits[1] = bits[1] << i | bits[0] >> (32-i);
bits[0] = bits[0] << i & 0xffffffffL; bits[0] = bits[0] << i & 0xffffffffL;
}
} }
}
else if (bits[0]) { else if (bits[0]) {
i = hi0bits(bits[0]) + 21; i = hi0bits(bits[0]) + 21;
if (i >= exp) { if (i >= exp) {
i = exp - 1; i = exp - 1;
exp = 0; exp = 0;
} }
else else
exp -= i; exp -= i;
if (i < 32) { if (i < 32) {
bits[1] = bits[0] >> (32 - i); bits[1] = bits[0] >> (32 - i);
bits[0] = bits[0] << i & 0xffffffffL; bits[0] = bits[0] << i & 0xffffffffL;
} }
else { else {
bits[1] = bits[0] << (i - 32); bits[1] = bits[0] << (i - 32);
bits[0] = 0; bits[0] = 0;
}
} }
}
else { else {
u->L[2] = u->L[3] = 0; u->L[2] = u->L[3] = 0;
break; break;
} }
u->L[2+_1] = bits[0]; u->L[2+0] = bits[0];
u->L[2+_0] = (bits[1] & 0xfffff) | (exp << 20); u->L[2+1] = (bits[1] & 0xfffff) | (exp << 20);
break; break;
case STRTOG_Denormal:
case STRTOG_Denormal:
if (bits[3]) if (bits[3])
goto nearly_normal; goto nearly_normal;
if (bits[2]) if (bits[2])
@ -114,67 +103,62 @@ strtopdd(CONST char *s, char **sp, double *dd)
goto hardly_normal; goto hardly_normal;
/* completely denormal */ /* completely denormal */
u->L[2] = u->L[3] = 0; u->L[2] = u->L[3] = 0;
u->L[_1] = bits[0]; u->L[0] = bits[0];
u->L[_0] = bits[1]; u->L[1] = bits[1];
break; break;
nearly_normal:
nearly_normal:
i = hi0bits(bits[3]) - 11; /* i >= 12 */ i = hi0bits(bits[3]) - 11; /* i >= 12 */
j = 32 - i; j = 32 - i;
u->L[_0] = ((bits[3] << i | bits[2] >> j) & 0xfffff) u->L[1] = ((bits[3] << i | bits[2] >> j) & 0xfffff)
| ((65 - i) << 20); | ((65 - i) << 20);
u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; u->L[0] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
u->L[2+_0] = bits[1] & ((1L << j) - 1); u->L[2+1] = bits[1] & ((1L << j) - 1);
u->L[2+_1] = bits[0]; u->L[2+0] = bits[0];
break; break;
partly_normal:
partly_normal:
i = hi0bits(bits[2]) - 11; i = hi0bits(bits[2]) - 11;
if (i < 0) { if (i < 0) {
j = -i; j = -i;
i += 32; i += 32;
u->L[_0] = (bits[2] >> j & 0xfffff) | (33 + j) << 20; u->L[1] = (bits[2] >> j & 0xfffff) | (33 + j) << 20;
u->L[_1] = ((bits[2] << i) | (bits[1] >> j)) & 0xffffffffL; u->L[0] = ((bits[2] << i) | (bits[1] >> j)) & 0xffffffffL;
u->L[2+_0] = bits[1] & ((1L << j) - 1); u->L[2+1] = bits[1] & ((1L << j) - 1);
u->L[2+_1] = bits[0]; u->L[2+0] = bits[0];
break; break;
} }
if (i == 0) { if (i == 0) {
u->L[_0] = (bits[2] & 0xfffff) | (33 << 20); u->L[1] = (bits[2] & 0xfffff) | (33 << 20);
u->L[_1] = bits[1]; u->L[0] = bits[1];
u->L[2+_0] = 0; u->L[2+1] = 0;
u->L[2+_1] = bits[0]; u->L[2+0] = bits[0];
break; break;
} }
j = 32 - i; j = 32 - i;
u->L[_0] = (((bits[2] << i) | (bits[1] >> j)) & 0xfffff) u->L[1] = (((bits[2] << i) | (bits[1] >> j)) & 0xfffff)
| ((j + 1) << 20); | ((j + 1) << 20);
u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[0] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
u->L[2+_0] = 0; u->L[2+1] = 0;
u->L[2+_1] = bits[0] & ((1L << j) - 1); u->L[2+0] = bits[0] & ((1L << j) - 1);
break; break;
hardly_normal:
hardly_normal:
j = 11 - hi0bits(bits[1]); j = 11 - hi0bits(bits[1]);
i = 32 - j; i = 32 - j;
u->L[_0] = (bits[1] >> j & 0xfffff) | ((j + 1) << 20); u->L[1] = (bits[1] >> j & 0xfffff) | ((j + 1) << 20);
u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[0] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
u->L[2+_0] = 0; u->L[2+1] = 0;
u->L[2+_1] = bits[0] & ((1L << j) - 1); u->L[2+0] = bits[0] & ((1L << j) - 1);
break; break;
case STRTOG_Infinite:
case STRTOG_Infinite: u->L[1] = u->L[2+1] = 0x7ff00000;
u->L[_0] = u->L[2+_0] = 0x7ff00000; u->L[0] = u->L[2+0] = 0;
u->L[_1] = u->L[2+_1] = 0;
break; break;
case STRTOG_NaN:
case STRTOG_NaN:
u->L[0] = u->L[2] = d_QNAN0; u->L[0] = u->L[2] = d_QNAN0;
u->L[1] = u->L[3] = d_QNAN1; u->L[1] = u->L[3] = d_QNAN1;
}
if (rv & STRTOG_Neg) {
u->L[ _0] |= 0x80000000L;
u->L[2+_0] |= 0x80000000L;
}
return rv;
} }
if (rv & STRTOG_Neg) {
u->L[ 1] |= 0x80000000L;
u->L[2+1] |= 0x80000000L;
}
return rv;
}

View file

@ -1,75 +1,66 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int int
strtopf(CONST char *s, char **sp, float *f) strtopf(const char *s, char **sp, float *f)
{ {
static const FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ }; static const FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ };
ULong bits[1], *L; ULong bits[1], *L;
Long exp; Long exp;
int k; int k;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc" #include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
k = strtodg(s, sp, fpi, &exp, bits); k = strtodg(s, sp, fpi, &exp, bits);
L = (ULong*)f; L = (ULong*)f;
switch(k & STRTOG_Retmask) { switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber: case STRTOG_NoNumber:
case STRTOG_Zero: case STRTOG_Zero:
L[0] = 0; L[0] = 0;
break; break;
case STRTOG_Normal:
case STRTOG_Normal: case STRTOG_NaNbits:
case STRTOG_NaNbits:
L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23); L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23);
break; break;
case STRTOG_Denormal:
case STRTOG_Denormal:
L[0] = bits[0]; L[0] = bits[0];
break; break;
case STRTOG_Infinite:
case STRTOG_Infinite:
L[0] = 0x7f800000; L[0] = 0x7f800000;
break; break;
case STRTOG_NaN:
case STRTOG_NaN:
L[0] = f_QNAN; L[0] = f_QNAN;
} }
if (k & STRTOG_Neg) if (k & STRTOG_Neg)
L[0] |= 0x80000000L; L[0] |= 0x80000000L;
return k; return k;
} }

View file

@ -1,108 +1,79 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay. extern UShort __gdtoa_NanDflt_ldus[5];
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern UShort __gdtoa_NanDflt_ldus[5];
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#define _4 4
#endif
#ifdef IEEE_8087
#define _0 4
#define _1 3
#define _2 2
#define _3 1
#define _4 0
#endif
int int
strtopx(CONST char *s, char **sp, void *V) strtopx(const char *s, char **sp, void *V)
{ {
const static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ }; const static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ };
ULong bits[2]; ULong bits[2];
Long exp; Long exp;
int k; int k;
UShort *L = (UShort*)V; UShort *L = (UShort*)V;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc" #include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
k = strtodg(s, sp, fpi, &exp, bits); k = strtodg(s, sp, fpi, &exp, bits);
switch(k & STRTOG_Retmask) { switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber: case STRTOG_NoNumber:
case STRTOG_Zero: case STRTOG_Zero:
L[0] = L[1] = L[2] = L[3] = L[4] = 0; L[0] = L[1] = L[2] = L[3] = L[4] = 0;
break; break;
case STRTOG_Denormal:
case STRTOG_Denormal: L[4] = 0;
L[_0] = 0;
goto normal_bits; goto normal_bits;
case STRTOG_Normal:
case STRTOG_Normal: case STRTOG_NaNbits:
case STRTOG_NaNbits: L[4] = exp + 0x3fff + 63;
L[_0] = exp + 0x3fff + 63; normal_bits:
normal_bits: L[0] = (UShort)bits[0];
L[_4] = (UShort)bits[0]; L[1] = (UShort)(bits[0] >> 16);
L[_3] = (UShort)(bits[0] >> 16); L[2] = (UShort)bits[1];
L[_2] = (UShort)bits[1]; L[3] = (UShort)(bits[1] >> 16);
L[_1] = (UShort)(bits[1] >> 16);
break; break;
case STRTOG_Infinite:
case STRTOG_Infinite: L[4] = 0x7fff;
L[_0] = 0x7fff; L[3] = 0x8000;
L[_1] = 0x8000; L[2] = L[1] = L[0] = 0;
L[_2] = L[_3] = L[_4] = 0;
break; break;
case STRTOG_NaN:
case STRTOG_NaN: L[0] = __gdtoa_NanDflt_ldus[0];
L[_4] = __gdtoa_NanDflt_ldus[0]; L[1] = __gdtoa_NanDflt_ldus[1];
L[_3] = __gdtoa_NanDflt_ldus[1]; L[2] = __gdtoa_NanDflt_ldus[2];
L[_2] = __gdtoa_NanDflt_ldus[2]; L[3] = __gdtoa_NanDflt_ldus[3];
L[_1] = __gdtoa_NanDflt_ldus[3]; L[4] = __gdtoa_NanDflt_ldus[4];
L[_0] = __gdtoa_NanDflt_ldus[4];
}
if (k & STRTOG_Neg)
L[_0] |= 0x8000;
return k;
} }
if (k & STRTOG_Neg)
L[4] |= 0x8000;
return k;
}

View file

@ -1,88 +1,83 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay. extern ULong __gdtoa_NanDflt_d[2];
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong __gdtoa_NanDflt_d[2];
void void
ULtod(ULong *L, ULong *bits, Long exp, int k) ULtod(ULong *L, ULong *bits, Long exp, int k)
{ {
switch(k & STRTOG_Retmask) { switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber: case STRTOG_NoNumber:
case STRTOG_Zero: case STRTOG_Zero:
L[0] = L[1] = 0; L[0] = L[1] = 0;
break; break;
case STRTOG_Denormal:
case STRTOG_Denormal: L[0] = bits[0];
L[_1] = bits[0]; L[1] = bits[1];
L[_0] = bits[1];
break; break;
case STRTOG_Normal:
case STRTOG_Normal: case STRTOG_NaNbits:
case STRTOG_NaNbits: L[0] = bits[0];
L[_1] = bits[0]; L[1] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
break; break;
case STRTOG_Infinite:
case STRTOG_Infinite: L[1] = 0x7ff00000;
L[_0] = 0x7ff00000; L[0] = 0;
L[_1] = 0;
break; break;
case STRTOG_NaN:
case STRTOG_NaN: L[1] = __gdtoa_NanDflt_d[1];
L[_0] = __gdtoa_NanDflt_d[1]; L[0] = __gdtoa_NanDflt_d[0];
L[_1] = __gdtoa_NanDflt_d[0];
}
if (k & STRTOG_Neg)
L[_0] |= 0x80000000L;
} }
if (k & STRTOG_Neg)
L[1] |= 0x80000000L;
}
int int
strtord(CONST char *s, char **sp, int rounding, double *d) strtord(const char *s, char **sp, int rounding, double *d)
{ {
static const FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ }; static const FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ };
FPI *fpi, fpi1; FPI *fpi, fpi1;
ULong bits[2]; ULong bits[2];
Long exp; Long exp;
int k; int k;
fpi = &fpi0; fpi = &fpi0;
if (rounding != FPI_Round_near) { if (rounding != FPI_Round_near) {
fpi1 = fpi0; fpi1 = fpi0;
fpi1.rounding = rounding; fpi1.rounding = rounding;
fpi = &fpi1; fpi = &fpi1;
} }
k = strtodg(s, sp, fpi, &exp, bits); k = strtodg(s, sp, fpi, &exp, bits);
ULtod((ULong*)d, bits, exp, k); ULtod((ULong*)d, bits, exp, k);
return k; return k;
} }

View file

@ -1,94 +1,91 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay. extern ULong __gdtoa_NanDflt_d[2];
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong __gdtoa_NanDflt_d[2];
void void
ULtodd(ULong *L, ULong *bits, Long exp, int k) ULtodd(ULong *L, ULong *bits, Long exp, int k)
{ {
int i, j; int i, j;
switch(k & STRTOG_Retmask) { switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber: case STRTOG_NoNumber:
case STRTOG_Zero: case STRTOG_Zero:
L[0] = L[1] = L[2] = L[3] = 0; L[0] = L[1] = L[2] = L[3] = 0;
break; break;
case STRTOG_Normal:
case STRTOG_Normal: L[0] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL;
L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL; L[1] = (bits[2] >> 21) | (bits[3] << 11 & 0xfffff)
L[_0] = (bits[2] >> 21) | (bits[3] << 11 & 0xfffff) | ((exp + 0x3ff + 105) << 20);
| ((exp + 0x3ff + 105) << 20);
exp += 0x3ff + 52; exp += 0x3ff + 52;
if (bits[1] &= 0x1fffff) { if (bits[1] &= 0x1fffff) {
i = hi0bits(bits[1]) - 11; i = hi0bits(bits[1]) - 11;
if (i >= exp) { if (i >= exp) {
i = exp - 1; i = exp - 1;
exp = 0; exp = 0;
} }
else else
exp -= i; exp -= i;
if (i > 0) { if (i > 0) {
bits[1] = bits[1] << i | bits[0] >> (32-i); bits[1] = bits[1] << i | bits[0] >> (32-i);
bits[0] = bits[0] << i & (ULong)0xffffffffL; bits[0] = bits[0] << i & (ULong)0xffffffffL;
}
} }
}
else if (bits[0]) { else if (bits[0]) {
i = hi0bits(bits[0]) + 21; i = hi0bits(bits[0]) + 21;
if (i >= exp) { if (i >= exp) {
i = exp - 1; i = exp - 1;
exp = 0; exp = 0;
} }
else else
exp -= i; exp -= i;
if (i < 32) { if (i < 32) {
bits[1] = bits[0] >> (32 - i); bits[1] = bits[0] >> (32 - i);
bits[0] = bits[0] << i & (ULong)0xffffffffL; bits[0] = bits[0] << i & (ULong)0xffffffffL;
} }
else { else {
bits[1] = bits[0] << (i - 32); bits[1] = bits[0] << (i - 32);
bits[0] = 0; bits[0] = 0;
}
} }
}
else { else {
L[2] = L[3] = 0; L[2] = L[3] = 0;
break; break;
} }
L[2+_1] = bits[0]; L[2+0] = bits[0];
L[2+_0] = (bits[1] & 0xfffff) | (exp << 20); L[2+1] = (bits[1] & 0xfffff) | (exp << 20);
break; break;
case STRTOG_Denormal:
case STRTOG_Denormal:
if (bits[3]) if (bits[3])
goto nearly_normal; goto nearly_normal;
if (bits[2]) if (bits[2])
@ -97,99 +94,88 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k)
goto hardly_normal; goto hardly_normal;
/* completely denormal */ /* completely denormal */
L[2] = L[3] = 0; L[2] = L[3] = 0;
L[_1] = bits[0]; L[0] = bits[0];
L[_0] = bits[1]; L[1] = bits[1];
break; break;
nearly_normal:
nearly_normal:
i = hi0bits(bits[3]) - 11; /* i >= 12 */ i = hi0bits(bits[3]) - 11; /* i >= 12 */
j = 32 - i; j = 32 - i;
L[_0] = ((bits[3] << i | bits[2] >> j) & 0xfffff) L[1] = ((bits[3] << i | bits[2] >> j) & 0xfffff)
| ((65 - i) << 20); | ((65 - i) << 20);
L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; L[0] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
L[2+_0] = bits[1] & (((ULong)1L << j) - 1); L[2+1] = bits[1] & (((ULong)1L << j) - 1);
L[2+_1] = bits[0]; L[2+0] = bits[0];
break; break;
partly_normal:
partly_normal:
i = hi0bits(bits[2]) - 11; i = hi0bits(bits[2]) - 11;
if (i < 0) { if (i < 0) {
j = -i; j = -i;
i += 32; i += 32;
L[_0] = (bits[2] >> j & 0xfffff) | ((33 + j) << 20); L[1] = (bits[2] >> j & 0xfffff) | ((33 + j) << 20);
L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; L[0] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
L[2+_0] = bits[1] & (((ULong)1L << j) - 1); L[2+1] = bits[1] & (((ULong)1L << j) - 1);
L[2+_1] = bits[0]; L[2+0] = bits[0];
break; break;
} }
if (i == 0) { if (i == 0) {
L[_0] = (bits[2] & 0xfffff) | (33 << 20); L[1] = (bits[2] & 0xfffff) | (33 << 20);
L[_1] = bits[1]; L[0] = bits[1];
L[2+_0] = 0; L[2+1] = 0;
L[2+_1] = bits[0]; L[2+0] = bits[0];
break; break;
} }
j = 32 - i; j = 32 - i;
L[_0] = (((bits[2] << i) | (bits[1] >> j)) & 0xfffff) L[1] = (((bits[2] << i) | (bits[1] >> j)) & 0xfffff)
| ((j + 1) << 20); | ((j + 1) << 20);
L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; L[0] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
L[2+_0] = 0; L[2+1] = 0;
L[2+_1] = bits[0] & ((1L << j) - 1); L[2+0] = bits[0] & ((1L << j) - 1);
break; break;
hardly_normal:
hardly_normal:
j = 11 - hi0bits(bits[1]); j = 11 - hi0bits(bits[1]);
i = 32 - j; i = 32 - j;
L[_0] = (bits[1] >> j & 0xfffff) | ((j + 1) << 20); L[1] = (bits[1] >> j & 0xfffff) | ((j + 1) << 20);
L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; L[0] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
L[2+_0] = 0; L[2+1] = 0;
L[2+_1] = bits[0] & (((ULong)1L << j) - 1); L[2+0] = bits[0] & (((ULong)1L << j) - 1);
break; break;
case STRTOG_Infinite:
case STRTOG_Infinite: L[1] = L[2+1] = 0x7ff00000;
L[_0] = L[2+_0] = 0x7ff00000; L[0] = L[2+0] = 0;
L[_1] = L[2+_1] = 0;
break; break;
case STRTOG_NaN:
case STRTOG_NaN: L[1] = L[1+2] = __gdtoa_NanDflt_d[1];
L[_0] = L[_0+2] = __gdtoa_NanDflt_d[1]; L[0] = L[0+2] = __gdtoa_NanDflt_d[0];
L[_1] = L[_1+2] = __gdtoa_NanDflt_d[0];
break; break;
case STRTOG_NaNbits:
case STRTOG_NaNbits: L[0] = (bits[1] >> 20 | bits[2] << 12) & (ULong)0xffffffffL;
L[_1] = (bits[1] >> 20 | bits[2] << 12) & (ULong)0xffffffffL; L[1] = bits[2] >> 20 | bits[3] << 12;
L[_0] = bits[2] >> 20 | bits[3] << 12; L[1] |= (L[0] | L[1]) ? (ULong)0x7ff00000L : (ULong)0x7ff80000L;
L[_0] |= (L[_1] | L[_0]) ? (ULong)0x7ff00000L : (ULong)0x7ff80000L; L[2+0] = bits[0] & (ULong)0xffffffffL;
L[2+_1] = bits[0] & (ULong)0xffffffffL; L[2+1] = bits[1] & 0xfffffL;
L[2+_0] = bits[1] & 0xfffffL; L[2+1] |= (L[2+0] | L[2+1]) ? (ULong)0x7ff00000L : (ULong)0x7ff80000L;
L[2+_0] |= (L[2+_1] | L[2+_0]) ? (ULong)0x7ff00000L : (ULong)0x7ff80000L;
}
if (k & STRTOG_Neg) {
L[_0] |= 0x80000000L;
L[2+_0] |= 0x80000000L;
}
} }
if (k & STRTOG_Neg) {
L[1] |= 0x80000000L;
L[2+1] |= 0x80000000L;
}
}
int int
strtordd(CONST char *s, char **sp, int rounding, double *dd) strtordd(const char *s, char **sp, int rounding, double *dd)
{ {
#ifdef Sudden_Underflow
static const FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1, 0 /*unused*/ };
#else
static const FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0, 0 /*unused*/ }; static const FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0, 0 /*unused*/ };
#endif
FPI *fpi, fpi1; FPI *fpi, fpi1;
ULong bits[4]; ULong bits[4];
Long exp; Long exp;
int k; int k;
fpi = &fpi0; fpi = &fpi0;
if (rounding != FPI_Round_near) { if (rounding != FPI_Round_near) {
fpi1 = fpi0; fpi1 = fpi0;
fpi1.rounding = rounding; fpi1.rounding = rounding;
fpi = &fpi1; fpi = &fpi1;
} }
k = strtodg(s, sp, fpi, &exp, bits); k = strtodg(s, sp, fpi, &exp, bits);
ULtodd((ULong*)dd, bits, exp, k); ULtodd((ULong*)dd, bits, exp, k);
return k; return k;
} }

View file

@ -1,84 +1,79 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay. extern ULong __gdtoa_NanDflt_f[1];
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong __gdtoa_NanDflt_f[1];
void void
ULtof(ULong *L, ULong *bits, Long exp, int k) ULtof(ULong *L, ULong *bits, Long exp, int k)
{ {
switch(k & STRTOG_Retmask) { switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber: case STRTOG_NoNumber:
case STRTOG_Zero: case STRTOG_Zero:
*L = 0; *L = 0;
break; break;
case STRTOG_Normal:
case STRTOG_Normal: case STRTOG_NaNbits:
case STRTOG_NaNbits:
L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23); L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23);
break; break;
case STRTOG_Denormal:
case STRTOG_Denormal:
L[0] = bits[0]; L[0] = bits[0];
break; break;
case STRTOG_Infinite:
case STRTOG_Infinite:
L[0] = 0x7f800000; L[0] = 0x7f800000;
break; break;
case STRTOG_NaN:
case STRTOG_NaN:
L[0] = __gdtoa_NanDflt_f[0]; L[0] = __gdtoa_NanDflt_f[0];
} }
if (k & STRTOG_Neg) if (k & STRTOG_Neg)
L[0] |= 0x80000000L; L[0] |= 0x80000000L;
} }
int int
strtorf(CONST char *s, char **sp, int rounding, float *f) strtorf(const char *s, char **sp, int rounding, float *f)
{ {
static const FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ }; static const FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ };
FPI *fpi, fpi1; FPI *fpi, fpi1;
ULong bits[1]; ULong bits[1];
Long exp; Long exp;
int k; int k;
fpi = &fpi0; fpi = &fpi0;
if (rounding != FPI_Round_near) { if (rounding != FPI_Round_near) {
fpi1 = fpi0; fpi1 = fpi0;
fpi1.rounding = rounding; fpi1.rounding = rounding;
fpi = &fpi1; fpi = &fpi1;
} }
k = strtodg(s, sp, fpi, &exp, bits); k = strtodg(s, sp, fpi, &exp, bits);
ULtof((ULong*)f, bits, exp, k); ULtof((ULong*)f, bits, exp, k);
return k; return k;
} }

View file

@ -1,56 +1,36 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#define _4 4
#endif
#ifdef IEEE_8087
#define _0 4
#define _1 3
#define _2 2
#define _3 1
#define _4 0
#endif
extern UShort __gdtoa_NanDflt_ldus[5]; extern UShort __gdtoa_NanDflt_ldus[5];
@ -58,58 +38,53 @@ void
ULtox(UShort *L, ULong *bits, Long exp, int k) ULtox(UShort *L, ULong *bits, Long exp, int k)
{ {
switch(k & STRTOG_Retmask) { switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber: case STRTOG_NoNumber:
case STRTOG_Zero: case STRTOG_Zero:
L[0] = L[1] = L[2] = L[3] = L[4] = 0; L[0] = L[1] = L[2] = L[3] = L[4] = 0;
break; break;
case STRTOG_Denormal:
case STRTOG_Denormal: L[4] = 0;
L[_0] = 0;
goto normal_bits; goto normal_bits;
case STRTOG_Normal:
case STRTOG_Normal: case STRTOG_NaNbits:
case STRTOG_NaNbits: L[4] = exp + 0x3fff + 63;
L[_0] = exp + 0x3fff + 63; normal_bits:
normal_bits: L[0] = (UShort)bits[0];
L[_4] = (UShort)bits[0]; L[1] = (UShort)(bits[0] >> 16);
L[_3] = (UShort)(bits[0] >> 16); L[2] = (UShort)bits[1];
L[_2] = (UShort)bits[1]; L[3] = (UShort)(bits[1] >> 16);
L[_1] = (UShort)(bits[1] >> 16);
break; break;
case STRTOG_Infinite:
case STRTOG_Infinite: L[4] = 0x7fff;
L[_0] = 0x7fff; L[3] = 0x8000;
L[_1] = 0x8000; L[2] = L[1] = L[0] = 0;
L[_2] = L[_3] = L[_4] = 0;
break; break;
case STRTOG_NaN:
case STRTOG_NaN: L[0] = __gdtoa_NanDflt_ldus[0];
L[_4] = __gdtoa_NanDflt_ldus[0]; L[1] = __gdtoa_NanDflt_ldus[1];
L[_3] = __gdtoa_NanDflt_ldus[1]; L[2] = __gdtoa_NanDflt_ldus[2];
L[_2] = __gdtoa_NanDflt_ldus[2]; L[3] = __gdtoa_NanDflt_ldus[3];
L[_1] = __gdtoa_NanDflt_ldus[3]; L[4] = __gdtoa_NanDflt_ldus[4];
L[_0] = __gdtoa_NanDflt_ldus[4];
}
if (k & STRTOG_Neg)
L[_0] |= 0x8000;
} }
if (k & STRTOG_Neg)
L[4] |= 0x8000;
}
int int
strtorx(CONST char *s, char **sp, int rounding, void *L) strtorx(const char *s, char **sp, int rounding, void *L)
{ {
static const FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ }; static const FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ };
FPI *fpi, fpi1; FPI *fpi, fpi1;
ULong bits[2]; ULong bits[2];
Long exp; Long exp;
int k; int k;
fpi = &fpi0; fpi = &fpi0;
if (rounding != FPI_Round_near) { if (rounding != FPI_Round_near) {
fpi1 = fpi0; fpi1 = fpi0;
fpi1.rounding = rounding; fpi1.rounding = rounding;
fpi = &fpi1; fpi = &fpi1;
} }
k = strtodg(s, sp, fpi, &exp, bits); k = strtodg(s, sp, fpi, &exp, bits);
ULtox((UShort*)L, bits, exp, k); ULtox((UShort*)L, bits, exp, k);
return k; return k;
} }

View file

@ -1,65 +1,61 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
Bigint * Bigint *
sum(Bigint *a, Bigint *b MTd) sum(Bigint *a, Bigint *b)
{ {
Bigint *c; Bigint *c;
ULong carry, *xc, *xa, *xb, *xe, y; ULong carry, *xc, *xa, *xb, *xe, y;
#ifdef Pack_32
ULong z; ULong z;
#endif
if (a->wds < b->wds) { if (a->wds < b->wds) {
c = b; b = a; a = c; c = b; b = a; a = c;
} }
c = Balloc(a->k MTa); c = Balloc(a->k);
c->wds = a->wds; c->wds = a->wds;
carry = 0; carry = 0;
xa = a->x; xa = a->x;
xb = b->x; xb = b->x;
xc = c->x; xc = c->x;
xe = xc + b->wds; xe = xc + b->wds;
#ifdef Pack_32
do { do {
y = (*xa & 0xffff) + (*xb & 0xffff) + carry; y = (*xa & 0xffff) + (*xb & 0xffff) + carry;
carry = (y & 0x10000) >> 16; carry = (y & 0x10000) >> 16;
z = (*xa++ >> 16) + (*xb++ >> 16) + carry; z = (*xa++ >> 16) + (*xb++ >> 16) + carry;
carry = (z & 0x10000) >> 16; carry = (z & 0x10000) >> 16;
Storeinc(xc, z, y); Storeinc(xc, z, y);
} }
while(xc < xe); while(xc < xe);
xe += a->wds - b->wds; xe += a->wds - b->wds;
while(xc < xe) { while(xc < xe) {
y = (*xa & 0xffff) + carry; y = (*xa & 0xffff) + carry;
@ -67,29 +63,15 @@ sum(Bigint *a, Bigint *b MTd)
z = (*xa++ >> 16) + carry; z = (*xa++ >> 16) + carry;
carry = (z & 0x10000) >> 16; carry = (z & 0x10000) >> 16;
Storeinc(xc, z, y); Storeinc(xc, z, y);
} }
#else
do {
y = *xa++ + *xb++ + carry;
carry = (y & 0x10000) >> 16;
*xc++ = y & 0xffff;
}
while(xc < xe);
xe += a->wds - b->wds;
while(xc < xe) {
y = *xa++ + carry;
carry = (y & 0x10000) >> 16;
*xc++ = y & 0xffff;
}
#endif
if (carry) { if (carry) {
if (c->wds == c->maxwds) { if (c->wds == c->maxwds) {
b = Balloc(c->k + 1 MTa); b = Balloc(c->k + 1);
Bcopy(b, c); Bcopy(b, c);
Bfree(c MTa); Bfree(c);
c = b; c = b;
}
c->x[c->wds++] = 1;
} }
return c; c->x[c->wds++] = 1;
} }
return c;
}

View file

@ -1,66 +1,58 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
The author of this software is David M. Gay.
Please send bug reports to David M. Gay <dmg@acm.org>
or Justine Tunney <jtunney@gmail.com>
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
*/
#include "third_party/gdtoa/gdtoa.internal.h" #include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */ /* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
double double
ulp(U *x) ulp(U *x)
{ {
Long L; Long L;
U a; U a;
L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
#ifndef Sudden_Underflow
if (L > 0) { if (L > 0) {
#endif
#ifdef IBM
L |= Exp_msk1 >> 4;
#endif
word0(&a) = L; word0(&a) = L;
word1(&a) = 0; word1(&a) = 0;
#ifndef Sudden_Underflow }
}
else { else {
L = -L >> Exp_shift; L = -L >> Exp_shift;
if (L < Exp_shift) { if (L < Exp_shift) {
word0(&a) = 0x80000 >> L; word0(&a) = 0x80000 >> L;
word1(&a) = 0; word1(&a) = 0;
} }
else { else {
word0(&a) = 0; word0(&a) = 0;
L -= Exp_shift; L -= Exp_shift;
word1(&a) = L >= 31 ? 1 : 1 << (31 - L); word1(&a) = L >= 31 ? 1 : 1 << (31 - L);
}
} }
#endif
return dval(&a);
} }
return dval(&a);
}

View file

@ -9,6 +9,8 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/sigbits.h" #include "libc/calls/sigbits.h"
#include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/sigaction.h"
#include "libc/dce.h"
#include "libc/log/log.h"
#include "libc/runtime/gc.internal.h" #include "libc/runtime/gc.internal.h"
#include "libc/sysv/consts/exit.h" #include "libc/sysv/consts/exit.h"
#include "libc/x/x.h" #include "libc/x/x.h"
@ -644,6 +646,7 @@ static int pmain (lua_State *L) {
int main (int argc, char **argv) { int main (int argc, char **argv) {
int status, result; int status, result;
lua_State *L; lua_State *L;
if (IsModeDbg()) ShowCrashReports();
L = luaL_newstate(); /* create state */ L = luaL_newstate(); /* create state */
if (L == NULL) { if (L == NULL) {
l_message(argv[0], "cannot create state: not enough memory"); l_message(argv[0], "cannot create state: not enough memory");

View file

@ -186,7 +186,7 @@ o/$(MODE)/third_party/quickjs/quickjs.o: \
-DSTACK_FRAME_UNLIMITED -DSTACK_FRAME_UNLIMITED
o/$(MODE)/third_party/quickjs/call.o: QUOTA = -M1024m -C16 o/$(MODE)/third_party/quickjs/call.o: QUOTA = -M1024m -C16
o/$(MODE)/third_party/quickjs/quickjs.o: QUOTA = -M512m o/$(MODE)/third_party/quickjs/quickjs.o: QUOTA = -M512m -C16
.PHONY: o/$(MODE)/third_party/quickjs .PHONY: o/$(MODE)/third_party/quickjs
o/$(MODE)/third_party/quickjs: \ o/$(MODE)/third_party/quickjs: \

View file

@ -165,7 +165,7 @@ $(THIRD_PARTY_SQLITE3_SHELL_OBJS): \
o/$(MODE)/%.shell.o: %.c o/$(MODE)/%.shell.o: %.c
@$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $< @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $<
o/$(MODE)/third_party/sqlite3/shell.shell.o: QUOTA = -M512m o/$(MODE)/third_party/sqlite3/shell.shell.o: QUOTA = -M512m -C16
o/$(MODE)/third_party/sqlite3/vdbe.o: QUOTA = -M512m o/$(MODE)/third_party/sqlite3/vdbe.o: QUOTA = -M512m
o/$(MODE)/third_party/sqlite3/vdbe.shell.o: QUOTA = -M512m o/$(MODE)/third_party/sqlite3/vdbe.shell.o: QUOTA = -M512m

View file

@ -4,7 +4,8 @@
"WEOF" "WEOF"
"NDEBUG" "NDEBUG"
"HUGE_VAL" "HUGE_VAL"
"CLK_TCK")) "CLK_TCK"
"FLT_ROUNDS"))
(defconst cosmo-c-constants-c11 (defconst cosmo-c-constants-c11
'("__func__" '("__func__"

View file

@ -54,7 +54,8 @@
"__SSE4_2__" "__SSE4_2__"
"__XSAVE__" "__XSAVE__"
"__CLFLUSHOPT__" "__CLFLUSHOPT__"
"__RDPID__")) "__RDPID__"
"FLT_ROUNDS"))
(defconst cosmo-cpp-constants-gcc-92 (defconst cosmo-cpp-constants-gcc-92
'("__x86_64__" '("__x86_64__"