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,38 +85,18 @@ 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
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); while(sx <= sxe);
if (!*bxe) { if (!*bxe) {
@ -164,31 +113,11 @@ 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
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); while(sx <= sxe);
bx = b->x; bx = b->x;
@ -200,4 +129,4 @@ quorem(Bigint *b, Bigint *S)
} }
} }
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,13 +67,6 @@ 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)
{ {
@ -109,45 +103,18 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
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 */
@ -156,36 +123,18 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
} }
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;
@ -193,22 +142,11 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
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,18 +168,11 @@ 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);
@ -250,7 +181,6 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
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)
@ -282,19 +212,12 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
} }
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. */
@ -322,17 +245,11 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
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);
@ -382,7 +299,6 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
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.
@ -419,7 +335,6 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
} }
} }
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.) {
@ -435,9 +350,7 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
break; break;
} }
} }
#ifndef No_leftright
} }
#endif
fast_failed: fast_failed:
s = s0; s = s0;
dval(&d) = dval(&d2); dval(&d) = dval(&d2);
@ -446,7 +359,6 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
} }
/* 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];
@ -459,35 +371,23 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
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)
#else
if (dval(&d) > ds || (dval(&d) == ds && L & 1))
#endif
{
bump_up: bump_up:
while(*--s == '9') while(*--s == '9')
if (s == s0) { if (s == s0) {
@ -502,23 +402,14 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
} }
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;
@ -529,34 +420,26 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
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) if (( j = b5 - m5 )!=0)
b = pow5mult(b, j MTb); b = pow5mult(b, j);
} }
else else
b = pow5mult(b, b5 MTb); b = pow5mult(b, b5);
} }
S = i2b(1 MTb); 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;
@ -571,13 +454,8 @@ 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;
@ -591,20 +469,20 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
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;
@ -617,72 +495,47 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
} }
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) { 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 /*)*/
#else
if ((j1 > 0 || (j1 == 0 && dig & 1)) if ((j1 > 0 || (j1 == 0 && dig & 1))
#endif
&& dig++ == '9') && dig++ == '9')
goto round_9_up; goto round_9_up;
} }
@ -691,10 +544,8 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
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';
@ -703,50 +554,39 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
*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')
@ -758,38 +598,25 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
++*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,12 +64,7 @@ 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++;
} }
@ -124,12 +90,7 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
*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++)
@ -141,12 +102,7 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
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) {
@ -158,20 +114,18 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
*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]; t = bits[nb];
do *--b = Hexdig[t & 0xf]; while(t >>= 4); do *--b = HEXDIG[t & 0xf]; while(t >>= 4);
*--b = '('; /*)*/ *--b = '(';
return rv; 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+1] & 0x7ff00000) == 0x7ff00000) {
if (L[2+_0] & 0xfffff || L[2+_1]) if (L[2+1] & 0xfffff || L[2+0])
goto nanret; goto nanret;
if ((L[_0] ^ L[2+_0]) & 0x80000000L) if ((L[1] ^ L[2+1]) & 0x80000000L)
goto nanret; /* Infinity - Infinity */ goto nanret; /* Infinity - Infinity */
} }
infret: infret:
b = buf; b = buf;
if (L[_0] & 0x80000000L) if (L[1] & 0x80000000L)
*b++ = '-'; *b++ = '-';
return strcp(b, "Infinity"); return stpcpy(b, "Infinity");
} }
if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { 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;
@ -152,19 +132,19 @@ g_ddfmt(char *buf, double *dd0, int ndig, size_t bufsize)
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+1] & 0x7ff00000) == 0x7ff00000) {
if (L[2+_0] & 0xfffff || L[2+_1]) if (L[2+1] & 0xfffff || L[2+0])
goto nanret; goto nanret;
if ((L[_0] ^ L[2+_0]) & 0x80000000L) if ((L[1] ^ L[2+1]) & 0x80000000L)
goto nanret; /* Infinity - Infinity */ goto nanret; /* Infinity - Infinity */
} }
infret: infret:
b = buf; b = buf;
if (L[_0] & 0x80000000L) if (L[1] & 0x80000000L)
*b++ = '-'; *b++ = '-';
return strcp(b, InfName[nik%6]); return stpcpy(b, InfName[nik%6]);
} }
if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { 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;
@ -172,19 +153,19 @@ g_ddfmt_p(char *buf, double *dd0, int ndig, size_t bufsize, int nik)
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,35 +41,29 @@ 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;
@ -77,21 +71,19 @@ g_dfmt_p(char *buf, double *d, int ndig, size_t bufsize, int nik)
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,35 +39,27 @@ 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;
@ -87,4 +79,4 @@ g_ffmt(char *buf, float *f, int ndig, size_t bufsize)
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,7 +56,7 @@ 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);
@ -71,14 +65,12 @@ g_ffmt_p(char *buf, float *f, int ndig, size_t bufsize, int nik)
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;
@ -98,4 +90,4 @@ g_ffmt_p(char *buf, float *f, int ndig, size_t bufsize, int nik)
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,32 +40,26 @@ 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 else
b = strcp(buf, "NaN"); b = stpcpy(buf, "NaN");
return b; return b;
} }
i = STRTOG_Normal; i = STRTOG_Normal;
@ -96,10 +70,8 @@ g_xfmt(char *buf, void *V, int ndig, size_t bufsize)
} }
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;
@ -113,4 +85,4 @@ g_xfmt(char *buf, void *V, int ndig, size_t bufsize)
} }
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,18 +60,18 @@ 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);
} }
@ -112,10 +86,8 @@ g_xfmt_p(char *buf, void *V, int ndig, size_t bufsize, int nik)
} }
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;
@ -129,4 +101,4 @@ g_xfmt_p(char *buf, void *V, int ndig, size_t bufsize, int nik)
} }
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,62 +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, 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
*x++ = (*bits >> 16) & ALL_ON;
#endif
} while(++bits <= be); } while(++bits <= be);
i = x - x0; i = x - x0;
while(!x0[--i]) while(!x0[--i])
@ -67,9 +59,9 @@ bitstob(ULong *bits, int nbits, int *bbits MTd)
} }
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,13 +143,6 @@ 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) {
@ -171,14 +153,14 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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);
@ -186,21 +168,15 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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,7 +225,6 @@ 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--;
@ -319,8 +285,7 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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) {
@ -329,17 +294,9 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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;
@ -390,7 +347,6 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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.
@ -414,7 +370,6 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
} }
} }
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,18 +388,14 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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];
@ -457,13 +408,11 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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;
@ -475,11 +424,7 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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;
@ -498,7 +443,6 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
} }
goto ret1; goto ret1;
} }
m2 = b2; m2 = b2;
m5 = b5; m5 = b5;
mhi = mlo = 0; mhi = mlo = 0;
@ -527,7 +471,7 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
} }
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;
@ -538,23 +482,21 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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) if ( (j = b5 - m5) !=0)
b = pow5mult(b, j MTb); b = pow5mult(b, j);
} }
else else
b = pow5mult(b, b5 MTb); b = pow5mult(b, b5);
} }
S = i2b(1 MTb); 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) {
@ -564,7 +506,6 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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,20 +516,20 @@ 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;
@ -603,29 +544,25 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
} }
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;
@ -640,12 +577,7 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
*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;
@ -653,11 +585,11 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
} }
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')
@ -666,14 +598,9 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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;
} }
@ -697,12 +624,12 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
*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);
} }
} }
} }
@ -711,23 +638,17 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
*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;
@ -744,21 +665,21 @@ gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, in
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

@ -17,48 +17,8 @@ asm(".include \"libc/disclaimer.inc\"");
#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,17 +1,10 @@
/* 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')
@ -96,23 +70,14 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
} }
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) {
@ -158,7 +123,7 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
} }
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;
@ -180,7 +145,7 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
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;
@ -192,23 +157,13 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
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;
@ -239,17 +194,15 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
} }
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;
@ -284,18 +237,14 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
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); Bfree(b);
retz: retz:
#ifndef NO_ERRNO
errno = ERANGE; errno = ERANGE;
#endif
return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow; return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow;
} }
k = n - 1; k = n - 1;
@ -327,7 +276,7 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
} }
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
@ -349,4 +298,4 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
*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) {
@ -59,14 +58,13 @@ rshift(Bigint *b, int k)
} }
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++)
@ -76,4 +74,4 @@ trailz(Bigint *b)
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,42 +1,41 @@
/*-*- 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;
@ -44,15 +43,14 @@ L_shift(ULong *x, ULong *x1, int i)
*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) {
@ -86,13 +84,13 @@ hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0)
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;
} }
@ -100,14 +98,12 @@ hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0)
*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;
} }
@ -120,9 +116,7 @@ hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0)
} }
*x = (*x << 4) | (h & 0xf); *x = (*x << 4) | (h & 0xf);
} }
#ifndef GDTOA_NON_PEDANTIC_NANCHECK break2:
break2:
#endif
if (!havedig) if (!havedig)
return STRTOG_NaN; return STRTOG_NaN;
if (x < x1 && i < 8) if (x < x1 && i < 8)
@ -148,4 +142,4 @@ hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0)
} }
} }
return STRTOG_NaNbits; return STRTOG_NaNbits;
} }

View file

@ -1,261 +1,117 @@
/*-*- 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
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); 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;
@ -267,7 +123,7 @@ mult(Bigint *a, Bigint *b MTd)
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;
@ -290,148 +145,61 @@ mult(Bigint *a, Bigint *b MTd)
*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; p5->next = 0;
} }
if (TI == &TI0)
FREE_DTOA_LOCK(1);
#else
p5 = p5s = i2b(625);
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; p51->next = 0;
} }
if (TI == &TI0)
FREE_DTOA_LOCK(1);
#else
p51 = p5->next = mult(p5,p5 MTa);
p51->next = 0;
#endif
}
p5 = p51; p5 = p51;
} }
return b; 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 {
@ -441,32 +209,20 @@ lshift(Bigint *b, int k MTd)
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
@ -488,26 +244,18 @@ cmp(Bigint *a, Bigint *b)
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;
@ -520,7 +268,7 @@ diff(Bigint *a, Bigint *b MTd)
} }
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,7 +278,6 @@ 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;
@ -542,42 +289,11 @@ diff(Bigint *a, Bigint *b MTd)
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 { else {
d0 = Exp_1 | y; word0(&d) = Exp_1 | y;
d1 = z; word1(&d) = z;
} }
#else ret_d:
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); return dval(&d);
} }
#undef d0
#undef d1
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,110 +1,84 @@
/*-*- 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';
@ -113,41 +87,26 @@ match(CONST char **sp, char *t)
} }
*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;
@ -166,4 +125,4 @@ any_on(Bigint *b, int k)
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,60 +1,52 @@
/*-*- 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];
@ -63,4 +55,4 @@ strtoIdd(CONST char *s, char **sp, double *f0, double *f1)
((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,48 +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.
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)) {
@ -51,7 +47,7 @@ strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *
} }
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;
@ -89,7 +85,7 @@ strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *
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;
@ -112,13 +108,13 @@ strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *
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;
@ -134,4 +130,4 @@ strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *
exp[1] = e1; exp[1] = e1;
} }
return rv; return rv;
} }

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
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];
@ -61,4 +57,4 @@ strtoIx(CONST char *s, char **sp, void *a, void *b)
M[4] = L[4]; M[4] = L[4];
} }
return k; return k;
} }

View file

@ -1,130 +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 "libc/errno.h" #include "libc/errno.h"
#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-2001 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.
****************************************************************/
#ifdef IEEE_Arith
#ifndef NO_IEEE_Scale
#define Avoid_Underflow #define Avoid_Underflow
#define dplen 1
#undef tinytens #undef tinytens
/* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */ /* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */
/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ /* flag unnecessarily. It leads to a song and dance at the end of strtod. */
static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, static const double tinytens[] = {
1e-16, 1e-32, 1e-64, 1e-128,
9007199254740992.*9007199254740992.e-256 9007199254740992.*9007199254740992.e-256
}; };
#endif
#endif
#ifdef Honor_FLT_ROUNDS
#undef Check_FLT_ROUNDS
#define Check_FLT_ROUNDS
#else
#define Rounding Flt_Rounds
#endif
#ifdef Avoid_Underflow /*{*/
static double static double
sulp(U *x, int scale) sulp(U *x, int scale)
{ {
U u; U u;
double rv;
int i; int i;
double rv;
rv = ulp(x); rv = ulp(x);
if (!scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0) if (!scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0)
return rv; /* Is there an example where i <= 0 ? */ return rv; /* Is there an example where i <= 0 ? */
word0(&u) = Exp_1 + (i << Exp_shift); word0(&u) = Exp_1 + (i << Exp_shift);
word1(&u) = 0; word1(&u) = 0;
return rv * u.d; return rv * u.d;
} }
#endif /*}*/
double double
strtod(CONST char *s00, char **se) strtod(const char *s00, char **se)
{ {
#ifdef Avoid_Underflow
int scale; int scale;
#endif
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign,
e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
CONST char *s, *s0, *s1; const char *s, *s0, *s1;
double aadj; double aadj;
Long L; Long L;
U adj, aadj1, rv, rv0; U adj, aadj1, rv, rv0;
ULong y, z; ULong y, z;
Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
#ifdef Avoid_Underflow
ULong Lsb, Lsb1; ULong Lsb, Lsb1;
#endif
#ifdef SET_INEXACT
int inexact, oldinexact;
#endif
#ifdef MULTIPLE_THREADS
ThInfo *TI = 0;
#endif
#ifdef USE_LOCALE /*{{*/
#ifdef NO_LOCALE_CACHE
char *decimalpoint = localeconv()->decimal_point;
int dplen = strlen(decimalpoint);
#else
char *decimalpoint;
static char *decimalpoint_cache;
static int dplen;
if (!(s0 = decimalpoint_cache)) {
s0 = localeconv()->decimal_point;
if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
strcpy(decimalpoint_cache, s0);
s0 = decimalpoint_cache;
}
dplen = strlen(s0);
}
decimalpoint = (char*)s0;
#endif /*NO_LOCALE_CACHE*/
#else /*USE_LOCALE}{*/
#define dplen 1
#endif /*USE_LOCALE}}*/
#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 /*}*/
sign = nz0 = nz = decpt = 0; sign = nz0 = nz = decpt = 0;
dval(&rv) = 0.; dval(&rv) = 0.;
for(s = s00;;s++) switch(*s) { for(s = s00;;s++) switch(*s) {
@ -147,9 +96,8 @@ strtod(CONST char *s00, char **se)
default: default:
goto break2; goto break2;
} }
break2: break2:
if (*s == '0') { if (*s == '0') {
#ifndef NO_HEX_FP /*{*/
{ {
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; Long exp;
@ -158,13 +106,9 @@ strtod(CONST char *s00, char **se)
case 'x': case 'x':
case 'X': case 'X':
{ {
#ifdef Honor_FLT_ROUNDS
FPI fpi1 = fpi; FPI fpi1 = fpi;
fpi1.rounding = Rounding; fpi1.rounding = Rounding;
#else switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) {
#define fpi1 fpi
#endif
switch((i = gethex(&s, &fpi1, &exp, &bb, sign MTb)) & STRTOG_Retmask) {
case STRTOG_NoNumber: case STRTOG_NoNumber:
s = s00; s = s00;
sign = 0; sign = 0;
@ -173,14 +117,13 @@ strtod(CONST char *s00, char **se)
default: default:
if (bb) { if (bb) {
copybits(bits, fpi.nbits, bb); copybits(bits, fpi.nbits, bb);
Bfree(bb MTb); Bfree(bb);
} }
ULtod(((U*)&rv)->L, bits, exp, i); ULtod(((U*)&rv)->L, bits, exp, i);
}} }}
goto ret; goto ret;
} }
} }
#endif /*}*/
nz0 = 1; nz0 = 1;
while(*++s == '0') ; while(*++s == '0') ;
if (!*s) if (!*s)
@ -194,17 +137,8 @@ strtod(CONST char *s00, char **se)
else if (nd < DBL_DIG + 2) else if (nd < DBL_DIG + 2)
z = 10*z + c - '0'; z = 10*z + c - '0';
nd0 = nd; nd0 = nd;
#ifdef USE_LOCALE
if (c == *decimalpoint) {
for(i = 1; decimalpoint[i]; ++i)
if (s[i] != decimalpoint[i])
goto dig_done;
s += i;
c = *s;
#else
if (c == '.') { if (c == '.') {
c = *++s; c = *++s;
#endif
decpt = 1; decpt = 1;
if (!nd) { if (!nd) {
for(; c == '0'; c = *++s) for(; c == '0'; c = *++s)
@ -235,7 +169,7 @@ strtod(CONST char *s00, char **se)
} }
} }
}/*}*/ }/*}*/
dig_done: dig_done:
e = 0; e = 0;
if (c == 'e' || c == 'E') { if (c == 'e' || c == 'E') {
if (!nd && !nz && !nz0) { if (!nd && !nz && !nz0) {
@ -275,7 +209,6 @@ strtod(CONST char *s00, char **se)
} }
if (!nd) { if (!nd) {
if (!nz && !nz0) { if (!nz && !nz0) {
#ifdef INFNAN_CHECK
/* Check for Nan and Infinity */ /* Check for Nan and Infinity */
ULong bits[2]; ULong bits[2];
static FPI fpinan = /* only 52 explicit bits */ static FPI fpinan = /* only 52 explicit bits */
@ -296,7 +229,6 @@ strtod(CONST char *s00, char **se)
case 'n': case 'n':
case 'N': case 'N':
if (match(&s, "an")) { if (match(&s, "an")) {
#ifndef No_Hex_NaN
if (*s == '(' /*)*/ if (*s == '(' /*)*/
&& hexnan(&s, &fpinan, bits) && hexnan(&s, &fpinan, bits)
== STRTOG_NaNbits) { == STRTOG_NaNbits) {
@ -304,16 +236,12 @@ strtod(CONST char *s00, char **se)
word1(&rv) = bits[0]; word1(&rv) = bits[0];
} }
else { else {
#endif
word0(&rv) = NAN_WORD0; word0(&rv) = NAN_WORD0;
word1(&rv) = NAN_WORD1; word1(&rv) = NAN_WORD1;
#ifndef No_Hex_NaN
} }
#endif
goto ret; goto ret;
} }
} }
#endif /* INFNAN_CHECK */
ret0: ret0:
s = s00; s = s00;
sign = 0; sign = 0;
@ -321,108 +249,59 @@ strtod(CONST char *s00, char **se)
goto ret; goto ret;
} }
e1 = e -= nf; e1 = e -= nf;
/* Now we have nd0 digits, starting at s0, followed by a /* Now we have nd0 digits, starting at s0, followed by a
* decimal point, followed by nd-nd0 digits. The number we're * decimal point, followed by nd-nd0 digits. The number we're
* after is the integer represented by those digits times * after is the integer represented by those digits times
* 10**e */ * 10**e */
if (!nd0) if (!nd0)
nd0 = nd; nd0 = nd;
k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2; k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2;
dval(&rv) = y; dval(&rv) = y;
if (k > 9) { if (k > 9) {
#ifdef SET_INEXACT
if (k > DBL_DIG)
oldinexact = get_inexact();
#endif
dval(&rv) = tens[k - 9] * dval(&rv) + z; dval(&rv) = tens[k - 9] * dval(&rv) + z;
} }
bd0 = 0; bd0 = 0;
if (nd <= DBL_DIG if (nd <= DBL_DIG) {
#ifndef RND_PRODQUOT
#ifndef Honor_FLT_ROUNDS
&& Flt_Rounds == 1
#endif
#endif
) {
if (!e) if (!e)
goto ret; goto ret;
#ifndef ROUND_BIASED_without_Round_Up
if (e > 0) { if (e > 0) {
if (e <= Ten_pmax) { if (e <= Ten_pmax) {
#ifdef VAX
goto vax_ovfl_check;
#else
#ifdef Honor_FLT_ROUNDS
/* round correctly FLT_ROUNDS = 2 or 3 */ /* round correctly FLT_ROUNDS = 2 or 3 */
if (sign) { if (sign) {
rv.d = -rv.d; rv.d = -rv.d;
sign = 0; sign = 0;
} }
#endif
/* rv = */ rounded_product(dval(&rv), tens[e]); /* rv = */ rounded_product(dval(&rv), tens[e]);
goto ret; goto ret;
#endif
} }
i = DBL_DIG - nd; i = DBL_DIG - nd;
if (e <= Ten_pmax + i) { if (e <= Ten_pmax + i) {
/* A fancier test would sometimes let us do /* A fancier test would sometimes let us do
* this for larger i values. * this for larger i values.
*/ */
#ifdef Honor_FLT_ROUNDS
/* round correctly FLT_ROUNDS = 2 or 3 */ /* round correctly FLT_ROUNDS = 2 or 3 */
if (sign) { if (sign) {
rv.d = -rv.d; rv.d = -rv.d;
sign = 0; sign = 0;
} }
#endif
e -= i; e -= i;
dval(&rv) *= tens[i]; dval(&rv) *= tens[i];
#ifdef VAX
/* VAX exponent range is so narrow we must
* worry about overflow here...
*/
vax_ovfl_check:
word0(&rv) -= P*Exp_msk1;
/* rv = */ rounded_product(dval(&rv), tens[e]); /* rv = */ rounded_product(dval(&rv), tens[e]);
if ((word0(&rv) & Exp_mask)
> Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
goto ovfl;
word0(&rv) += P*Exp_msk1;
#else
/* rv = */ rounded_product(dval(&rv), tens[e]);
#endif
goto ret; goto ret;
} }
} }
#ifndef Inaccurate_Divide
else if (e >= -Ten_pmax) { else if (e >= -Ten_pmax) {
#ifdef Honor_FLT_ROUNDS
/* round correctly FLT_ROUNDS = 2 or 3 */ /* round correctly FLT_ROUNDS = 2 or 3 */
if (sign) { if (sign) {
rv.d = -rv.d; rv.d = -rv.d;
sign = 0; sign = 0;
} }
#endif
/* rv = */ rounded_quotient(dval(&rv), tens[-e]); /* rv = */ rounded_quotient(dval(&rv), tens[-e]);
goto ret; goto ret;
} }
#endif
#endif /* ROUND_BIASED_without_Round_Up */
} }
e1 += nd - k; e1 += nd - k;
#ifdef IEEE_Arith
#ifdef SET_INEXACT
inexact = 1;
if (k <= DBL_DIG)
oldinexact = get_inexact();
#endif
#ifdef Avoid_Underflow
scale = 0; scale = 0;
#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;
@ -430,11 +309,7 @@ strtod(CONST char *s00, char **se)
if (Rounding != 2) if (Rounding != 2)
Rounding = 0; Rounding = 0;
} }
#endif
#endif /*IEEE_Arith*/
/* Get starting approximation = rv * 10**e1 */ /* Get starting approximation = rv * 10**e1 */
if (e1 > 0) { if (e1 > 0) {
if ( (i = e1 & 15) !=0) if ( (i = e1 & 15) !=0)
dval(&rv) *= tens[i]; dval(&rv) *= tens[i];
@ -442,8 +317,6 @@ strtod(CONST char *s00, char **se)
if (e1 > DBL_MAX_10_EXP) { if (e1 > DBL_MAX_10_EXP) {
ovfl: ovfl:
/* Can't trust HUGE_VAL */ /* Can't trust HUGE_VAL */
#ifdef IEEE_Arith
#ifdef Honor_FLT_ROUNDS
switch(Rounding) { switch(Rounding) {
case 0: /* toward 0 */ case 0: /* toward 0 */
case 3: /* toward -infinity */ case 3: /* toward -infinity */
@ -454,30 +327,15 @@ strtod(CONST char *s00, char **se)
word0(&rv) = Exp_mask; word0(&rv) = Exp_mask;
word1(&rv) = 0; word1(&rv) = 0;
} }
#else /*Honor_FLT_ROUNDS*/
word0(&rv) = Exp_mask;
word1(&rv) = 0;
#endif /*Honor_FLT_ROUNDS*/
#ifdef SET_INEXACT
/* set overflow bit */
dval(&rv0) = 1e300;
dval(&rv0) *= dval(&rv0);
#endif
#else /*IEEE_Arith*/
word0(&rv) = Big0;
word1(&rv) = Big1;
#endif /*IEEE_Arith*/
range_err: range_err:
if (bd0) { if (bd0) {
Bfree(bb MTb); Bfree(bb);
Bfree(bd MTb); Bfree(bd);
Bfree(bs MTb); Bfree(bs);
Bfree(bd0 MTb); Bfree(bd0);
Bfree(delta MTb); Bfree(delta);
} }
#ifndef NO_ERRNO
errno = ERANGE; errno = ERANGE;
#endif
goto ret; goto ret;
} }
e1 >>= 4; e1 >>= 4;
@ -507,7 +365,6 @@ strtod(CONST char *s00, char **se)
if (e1 >>= 4) { if (e1 >>= 4) {
if (e1 >= 1 << n_bigtens) if (e1 >= 1 << n_bigtens)
goto undfl; goto undfl;
#ifdef Avoid_Underflow
if (e1 & Scale_Bit) if (e1 & Scale_Bit)
scale = 2*P; scale = 2*P;
for(j = 0; e1 > 0; j++, e1 >>= 1) for(j = 0; e1 > 0; j++, e1 >>= 1)
@ -526,49 +383,23 @@ strtod(CONST char *s00, char **se)
else else
word1(&rv) &= 0xffffffff << j; word1(&rv) &= 0xffffffff << j;
} }
#else
for(j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
dval(&rv) *= tinytens[j];
/* The last multiplication could underflow. */
dval(&rv0) = dval(&rv);
dval(&rv) *= tinytens[j];
if (!dval(&rv)) {
dval(&rv) = 2.*dval(&rv0);
dval(&rv) *= tinytens[j];
#endif
if (!dval(&rv)) { if (!dval(&rv)) {
undfl: undfl:
dval(&rv) = 0.; dval(&rv) = 0.;
#ifdef Honor_FLT_ROUNDS
if (Rounding == 2) if (Rounding == 2)
word1(&rv) = 1; word1(&rv) = 1;
#endif
goto range_err; goto range_err;
} }
#ifndef Avoid_Underflow
word0(&rv) = Tiny0;
word1(&rv) = Tiny1;
/* The refinement below will clean
* this approximation up.
*/
}
#endif
} }
} }
/* Now the hard part -- adjusting rv to the correct value.*/ /* Now the hard part -- adjusting rv to the correct value.*/
/* Put digits into bd: true value = bd * 10^e */ /* Put digits into bd: true value = bd * 10^e */
bd0 = s2b(s0, nd0, nd, y, dplen);
bd0 = s2b(s0, nd0, nd, y, dplen MTb);
for(;;) { for(;;) {
bd = Balloc(bd0->k MTb); bd = Balloc(bd0->k);
Bcopy(bd, bd0); Bcopy(bd, bd0);
bb = d2b(dval(&rv), &bbe, &bbbits MTb); /* rv = bb * 2^bbe */ bb = d2b(dval(&rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
bs = i2b(1 MTb); bs = i2b(1);
if (e >= 0) { if (e >= 0) {
bb2 = bb5 = 0; bb2 = bb5 = 0;
bd2 = bd5 = e; bd2 = bd5 = e;
@ -582,11 +413,8 @@ strtod(CONST char *s00, char **se)
else else
bd2 -= bbe; bd2 -= bbe;
bs2 = bb2; bs2 = bb2;
#ifdef Honor_FLT_ROUNDS
if (Rounding != 1) if (Rounding != 1)
bs2++; bs2++;
#endif
#ifdef Avoid_Underflow
Lsb = LSB; Lsb = LSB;
Lsb1 = 0; Lsb1 = 0;
j = bbe - scale; j = bbe - scale;
@ -600,27 +428,9 @@ strtod(CONST char *s00, char **se)
else else
Lsb1 = Lsb << (i-32); Lsb1 = Lsb << (i-32);
} }
#else /*Avoid_Underflow*/
#ifdef Sudden_Underflow
#ifdef IBM
j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
#else
j = P + 1 - bbbits;
#endif
#else /*Sudden_Underflow*/
j = bbe;
i = j + bbbits - 1; /* logb(&rv) */
if (i < Emin) /* denormal */
j += P - Emin;
else
j = P + 1 - bbbits;
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/
bb2 += j; bb2 += j;
bd2 += j; bd2 += j;
#ifdef Avoid_Underflow
bd2 += scale; bd2 += scale;
#endif
i = bb2 < bd2 ? bb2 : bd2; i = bb2 < bd2 ? bb2 : bd2;
if (i > bs2) if (i > bs2)
i = bs2; i = bs2;
@ -630,32 +440,28 @@ strtod(CONST char *s00, char **se)
bs2 -= i; bs2 -= i;
} }
if (bb5 > 0) { if (bb5 > 0) {
bs = pow5mult(bs, bb5 MTb); bs = pow5mult(bs, bb5);
bb1 = mult(bs, bb MTb); bb1 = mult(bs, bb);
Bfree(bb MTb); Bfree(bb);
bb = bb1; bb = bb1;
} }
if (bb2 > 0) if (bb2 > 0)
bb = lshift(bb, bb2 MTb); bb = lshift(bb, bb2);
if (bd5 > 0) if (bd5 > 0)
bd = pow5mult(bd, bd5 MTb); bd = pow5mult(bd, bd5);
if (bd2 > 0) if (bd2 > 0)
bd = lshift(bd, bd2 MTb); bd = lshift(bd, bd2);
if (bs2 > 0) if (bs2 > 0)
bs = lshift(bs, bs2 MTb); bs = lshift(bs, bs2);
delta = diff(bb, bd MTb); delta = diff(bb, bd);
dsign = delta->sign; dsign = delta->sign;
delta->sign = 0; delta->sign = 0;
i = cmp(delta, bs); i = cmp(delta, bs);
#ifdef Honor_FLT_ROUNDS
if (Rounding != 1) { if (Rounding != 1) {
if (i < 0) { if (i < 0) {
/* Error is less than an ulp */ /* Error is less than an ulp */
if (!delta->x[0] && delta->wds <= 1) { if (!delta->x[0] && delta->wds <= 1) {
/* exact */ /* exact */
#ifdef SET_INEXACT
inexact = 0;
#endif
break; break;
} }
if (Rounding) { if (Rounding) {
@ -669,33 +475,17 @@ strtod(CONST char *s00, char **se)
if (!word1(&rv) if (!word1(&rv)
&& !(word0(&rv) & Frac_mask)) { && !(word0(&rv) & Frac_mask)) {
y = word0(&rv) & Exp_mask; y = word0(&rv) & Exp_mask;
#ifdef Avoid_Underflow
if (!scale || y > 2*P*Exp_msk1) if (!scale || y > 2*P*Exp_msk1)
#else
if (y)
#endif
{ {
delta = lshift(delta,Log2P MTb); delta = lshift(delta,Log2P);
if (cmp(delta, bs) <= 0) if (cmp(delta, bs) <= 0)
dval(&adj) = -0.5; dval(&adj) = -0.5;
} }
} }
apply_adj: apply_adj:
#ifdef Avoid_Underflow
if (scale && (y = word0(&rv) & Exp_mask) if (scale && (y = word0(&rv) & Exp_mask)
<= 2*P*Exp_msk1) <= 2*P*Exp_msk1)
word0(&adj) += (2*P+1)*Exp_msk1 - y; word0(&adj) += (2*P+1)*Exp_msk1 - y;
#else
#ifdef Sudden_Underflow
if ((word0(&rv) & Exp_mask) <=
P*Exp_msk1) {
word0(&rv) += P*Exp_msk1;
dval(&rv) += adj*ulp(&rv);
word0(&rv) -= P*Exp_msk1;
}
else
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/
dval(&rv) += adj.d*ulp(&rv); dval(&rv) += adj.d*ulp(&rv);
} }
break; break;
@ -712,23 +502,8 @@ strtod(CONST char *s00, char **se)
dval(&adj) = y; dval(&adj) = y;
} }
} }
#ifdef Avoid_Underflow
if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
word0(&adj) += (2*P+1)*Exp_msk1 - y; word0(&adj) += (2*P+1)*Exp_msk1 - y;
#else
#ifdef Sudden_Underflow
if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
word0(&rv) += P*Exp_msk1;
dval(&adj) *= ulp(&rv);
if (dsign)
dval(&rv) += adj;
else
dval(&rv) -= adj;
word0(&rv) -= P*Exp_msk1;
goto cont;
}
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/
dval(&adj) *= ulp(&rv); /* XXX */ dval(&adj) *= ulp(&rv); /* XXX */
if (dsign) { if (dsign) {
if (word0(&rv) == Big0 && word1(&rv) == Big1) if (word0(&rv) == Big0 && word1(&rv) == Big1)
@ -739,35 +514,19 @@ strtod(CONST char *s00, char **se)
dval(&rv) -= adj.d; dval(&rv) -= adj.d;
goto cont; goto cont;
} }
#endif /*Honor_FLT_ROUNDS*/
if (i < 0) { if (i < 0) {
/* Error is less than half an ulp -- check for /* Error is less than half an ulp -- check for
* special case of mantissa a power of two. * special case of mantissa a power of two.
*/ */
if (dsign || word1(&rv) || word0(&rv) & Bndry_mask if (dsign || word1(&rv) || word0(&rv) & Bndry_mask ||
#ifdef IEEE_Arith (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1) {
#ifdef Avoid_Underflow
|| (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1
#else
|| (word0(&rv) & Exp_mask) <= Exp_msk1
#endif
#endif
) {
#ifdef SET_INEXACT
if (!delta->x[0] && delta->wds <= 1)
inexact = 0;
#endif
break; break;
} }
if (!delta->x[0] && delta->wds <= 1) { if (!delta->x[0] && delta->wds <= 1) {
/* exact result */ /* exact result */
#ifdef SET_INEXACT
inexact = 0;
#endif
break; break;
} }
delta = lshift(delta,Log2P MTb); delta = lshift(delta,Log2P);
if (cmp(delta, bs) > 0) if (cmp(delta, bs) > 0)
goto drop_down; goto drop_down;
break; break;
@ -777,45 +536,23 @@ strtod(CONST char *s00, char **se)
if (dsign) { if (dsign) {
if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
&& word1(&rv) == ( && word1(&rv) == (
#ifdef Avoid_Underflow
(scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
#endif
0xffffffff)) { 0xffffffff)) {
/*boundary case -- increment exponent*/ /*boundary case -- increment exponent*/
if (word0(&rv) == Big0 && word1(&rv) == Big1) if (word0(&rv) == Big0 && word1(&rv) == Big1)
goto ovfl; goto ovfl;
word0(&rv) = (word0(&rv) & Exp_mask) word0(&rv) = (word0(&rv) & Exp_mask)
+ Exp_msk1 + Exp_msk1
#ifdef IBM
| Exp_msk1 >> 4
#endif
; ;
word1(&rv) = 0; word1(&rv) = 0;
#ifdef Avoid_Underflow
dsign = 0; dsign = 0;
#endif
break; break;
} }
} }
else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
drop_down: drop_down:
/* boundary case -- decrement exponent */ /* boundary case -- decrement exponent */
#ifdef Sudden_Underflow /*{{*/
L = word0(&rv) & Exp_mask;
#ifdef IBM
if (L < Exp_msk1)
#else
#ifdef Avoid_Underflow
if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
#else
if (L <= Exp_msk1)
#endif /*Avoid_Underflow*/
#endif /*IBM*/
goto undfl;
L -= Exp_msk1;
#else /*Sudden_Underflow}{*/
#ifdef Avoid_Underflow
if (scale) { if (scale) {
L = word0(&rv) & Exp_mask; L = word0(&rv) & Exp_mask;
if (L <= (2*P+1)*Exp_msk1) { if (L <= (2*P+1)*Exp_msk1) {
@ -827,69 +564,39 @@ strtod(CONST char *s00, char **se)
goto undfl; goto undfl;
} }
} }
#endif /*Avoid_Underflow*/
L = (word0(&rv) & Exp_mask) - Exp_msk1; L = (word0(&rv) & Exp_mask) - Exp_msk1;
#endif /*Sudden_Underflow}}*/
word0(&rv) = L | Bndry_mask1; word0(&rv) = L | Bndry_mask1;
word1(&rv) = 0xffffffff; word1(&rv) = 0xffffffff;
#ifdef IBM
goto cont;
#else
break; break;
#endif
} }
#ifndef ROUND_BIASED
#ifdef Avoid_Underflow
if (Lsb1) { if (Lsb1) {
if (!(word0(&rv) & Lsb1)) if (!(word0(&rv) & Lsb1))
break; break;
} }
else if (!(word1(&rv) & Lsb)) else if (!(word1(&rv) & Lsb))
break; break;
#else
if (!(word1(&rv) & LSB))
break;
#endif
#endif
if (dsign) if (dsign)
#ifdef Avoid_Underflow
dval(&rv) += sulp(&rv, scale); dval(&rv) += sulp(&rv, scale);
#else
dval(&rv) += ulp(&rv);
#endif
#ifndef ROUND_BIASED
else { else {
#ifdef Avoid_Underflow
dval(&rv) -= sulp(&rv, scale); dval(&rv) -= sulp(&rv, scale);
#else
dval(&rv) -= ulp(&rv);
#endif
#ifndef Sudden_Underflow
if (!dval(&rv)) if (!dval(&rv))
goto undfl; goto undfl;
#endif
} }
#ifdef Avoid_Underflow
dsign = 1 - dsign; dsign = 1 - dsign;
#endif
#endif
break; break;
} }
if ((aadj = ratio(delta, bs)) <= 2.) { if ((aadj = ratio(delta, bs)) <= 2.) {
if (dsign) if (dsign)
aadj = dval(&aadj1) = 1.; aadj = dval(&aadj1) = 1.;
else if (word1(&rv) || word0(&rv) & Bndry_mask) { else if (word1(&rv) || word0(&rv) & Bndry_mask) {
#ifndef Sudden_Underflow
if (word1(&rv) == Tiny1 && !word0(&rv)) if (word1(&rv) == Tiny1 && !word0(&rv))
goto undfl; goto undfl;
#endif
aadj = 1.; aadj = 1.;
dval(&aadj1) = -1.; dval(&aadj1) = -1.;
} }
else { else {
/* special case -- power of FLT_RADIX to be */ /* special case -- power of FLT_RADIX to be */
/* rounded down... */ /* rounded down... */
if (aadj < 2./FLT_RADIX) if (aadj < 2./FLT_RADIX)
aadj = 1./FLT_RADIX; aadj = 1./FLT_RADIX;
else else
@ -900,7 +607,6 @@ strtod(CONST char *s00, char **se)
else { else {
aadj *= 0.5; aadj *= 0.5;
dval(&aadj1) = dsign ? aadj : -aadj; dval(&aadj1) = dsign ? aadj : -aadj;
#ifdef Check_FLT_ROUNDS
switch(Rounding) { switch(Rounding) {
case 2: /* towards +infinity */ case 2: /* towards +infinity */
dval(&aadj1) -= 0.5; dval(&aadj1) -= 0.5;
@ -909,15 +615,9 @@ strtod(CONST char *s00, char **se)
case 3: /* towards -infinity */ case 3: /* towards -infinity */
dval(&aadj1) += 0.5; dval(&aadj1) += 0.5;
} }
#else
if (Flt_Rounds == 0)
dval(&aadj1) += 0.5;
#endif /*Check_FLT_ROUNDS*/
} }
y = word0(&rv) & Exp_mask; y = word0(&rv) & Exp_mask;
/* Check for overflow */ /* Check for overflow */
if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
dval(&rv0) = dval(&rv); dval(&rv0) = dval(&rv);
word0(&rv) -= P*Exp_msk1; word0(&rv) -= P*Exp_msk1;
@ -935,7 +635,6 @@ strtod(CONST char *s00, char **se)
word0(&rv) += P*Exp_msk1; word0(&rv) += P*Exp_msk1;
} }
else { else {
#ifdef Avoid_Underflow
if (scale && y <= 2*P*Exp_msk1) { if (scale && y <= 2*P*Exp_msk1) {
if (aadj <= 0x7fffffff) { if (aadj <= 0x7fffffff) {
if ((z = aadj) <= 0) if ((z = aadj) <= 0)
@ -947,56 +646,9 @@ strtod(CONST char *s00, char **se)
} }
dval(&adj) = dval(&aadj1) * ulp(&rv); dval(&adj) = dval(&aadj1) * ulp(&rv);
dval(&rv) += dval(&adj); dval(&rv) += dval(&adj);
#else
#ifdef Sudden_Underflow
if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
dval(&rv0) = dval(&rv);
word0(&rv) += P*Exp_msk1;
dval(&adj) = dval(&aadj1) * ulp(&rv);
dval(&rv) += adj;
#ifdef IBM
if ((word0(&rv) & Exp_mask) < P*Exp_msk1)
#else
if ((word0(&rv) & Exp_mask) <= P*Exp_msk1)
#endif
{
if (word0(&rv0) == Tiny0
&& word1(&rv0) == Tiny1)
goto undfl;
word0(&rv) = Tiny0;
word1(&rv) = Tiny1;
goto cont;
}
else
word0(&rv) -= P*Exp_msk1;
}
else {
dval(&adj) = dval(&aadj1) * ulp(&rv);
dval(&rv) += adj;
}
#else /*Sudden_Underflow*/
/* Compute dval(&adj) so that the IEEE rounding rules will
* correctly round rv + dval(&adj) in some half-way cases.
* If rv * ulp(&rv) is denormalized (i.e.,
* y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
* trouble from bits lost to denormalization;
* example: 1.2e-307 .
*/
if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
dval(&aadj1) = (double)(int)(aadj + 0.5);
if (!dsign)
dval(&aadj1) = -dval(&aadj1);
}
dval(&adj) = dval(&aadj1) * ulp(&rv);
dval(&rv) += adj;
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/
} }
z = word0(&rv) & Exp_mask; z = word0(&rv) & Exp_mask;
#ifndef SET_INEXACT
#ifdef Avoid_Underflow
if (!scale) if (!scale)
#endif
if (y == z) { if (y == z) {
/* Can we stop now? */ /* Can we stop now? */
L = (Long)aadj; L = (Long)aadj;
@ -1009,55 +661,27 @@ strtod(CONST char *s00, char **se)
else if (aadj < .4999999/FLT_RADIX) else if (aadj < .4999999/FLT_RADIX)
break; break;
} }
#endif
cont: cont:
Bfree(bb MTb); Bfree(bb);
Bfree(bd MTb); Bfree(bd);
Bfree(bs MTb); Bfree(bs);
Bfree(delta MTb); Bfree(delta);
} }
Bfree(bb MTb); Bfree(bb);
Bfree(bd MTb); Bfree(bd);
Bfree(bs MTb); Bfree(bs);
Bfree(bd0 MTb); Bfree(bd0);
Bfree(delta MTb); Bfree(delta);
#ifdef SET_INEXACT
if (inexact) {
if (!oldinexact) {
word0(&rv0) = Exp_1 + (70 << Exp_shift);
word1(&rv0) = 0;
dval(&rv0) += 1.;
}
}
else if (!oldinexact)
clear_inexact();
#endif
#ifdef Avoid_Underflow
if (scale) { if (scale) {
word0(&rv0) = Exp_1 - 2*P*Exp_msk1; word0(&rv0) = Exp_1 - 2*P*Exp_msk1;
word1(&rv0) = 0; word1(&rv0) = 0;
dval(&rv) *= dval(&rv0); dval(&rv) *= dval(&rv0);
#ifndef NO_ERRNO
/* try to avoid the bug of testing an 8087 register value */ /* try to avoid the bug of testing an 8087 register value */
#ifdef IEEE_Arith
if (!(word0(&rv) & Exp_mask)) if (!(word0(&rv) & Exp_mask))
#else
if (word0(&rv) == 0 && word1(&rv) == 0)
#endif
errno = ERANGE; errno = ERANGE;
#endif
} }
#endif /* Avoid_Underflow */ ret:
#ifdef SET_INEXACT
if (inexact && !(word0(&rv) & Exp_mask)) {
/* set underflow bit */
dval(&rv0) = 1e-300;
dval(&rv0) *= dval(&rv0);
}
#endif
ret:
if (se) if (se)
*se = (char *)s; *se = (char *)s;
return sign ? -dval(&rv) : dval(&rv); return sign ? -dval(&rv) : dval(&rv);
} }

View file

@ -1,59 +1,57 @@
/*-*- 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;
@ -61,26 +59,13 @@ strtodI(CONST char *s, char **sp, double *dd)
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);
@ -92,42 +77,16 @@ strtodI(CONST char *s, char **sp, double *dd)
} }
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;
@ -142,15 +101,13 @@ strtodI(CONST char *s, char **sp, double *dd)
} }
} }
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;
} }

View file

@ -1,59 +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. static const int
Copyright (C) 1998-2001 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 CONST int
fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21, fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21,
24, 26, 28, 31, 33, 35, 38, 40, 42, 45, 24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
47, 49, 52 47, 49, 52 };
#ifdef VAX
, 54, 56
#endif
};
Bigint * Bigint *
increment(Bigint *b MTd) increment(Bigint *b)
{ {
ULong *x, *xe; ULong *x, *xe;
Bigint *b1; Bigint *b1;
#ifdef Pack_16
ULong carry = 1, y;
#endif
x = b->x; x = b->x;
xe = x + b->wds; xe = x + b->wds;
#ifdef Pack_32
do { do {
if (*x < (ULong)0xffffffffL) { if (*x < (ULong)0xffffffffL) {
++*x; ++*x;
@ -61,39 +52,24 @@ increment(Bigint *b MTd)
} }
*x++ = 0; *x++ = 0;
} while(x < xe); } while(x < xe);
#else
do {
y = *x + carry;
carry = y >> 16;
*x++ = y & 0xffff;
if (!carry)
return b;
} while(x < xe);
if (carry)
#endif
{ {
if (b->wds >= b->maxwds) { if (b->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[b->wds++] = 1; b->x[b->wds++] = 1;
} }
return b; return b;
} }
void void
decrement(Bigint *b) decrement(Bigint *b)
{ {
ULong *x, *xe; ULong *x, *xe;
#ifdef Pack_16
ULong borrow = 1, y;
#endif
x = b->x; x = b->x;
xe = x + b->wds; xe = x + b->wds;
#ifdef Pack_32
do { do {
if (*x) { if (*x) {
--*x; --*x;
@ -102,20 +78,12 @@ decrement(Bigint *b)
*x++ = 0xffffffffL; *x++ = 0xffffffffL;
} }
while(x < xe); while(x < xe);
#else }
do {
y = *x - borrow;
borrow = (y & 0x10000) >> 16;
*x++ = y & 0xffff;
} while(borrow && x < xe);
#endif
}
static int static int
all_on(Bigint *b, int n) all_on(Bigint *b, int n)
{ {
ULong *x, *xe; ULong *x, *xe;
x = b->x; x = b->x;
xe = x + (n >> kshift); xe = x + (n >> kshift);
while(x < xe) while(x < xe)
@ -124,18 +92,17 @@ all_on(Bigint *b, int n)
if (n &= kmask) if (n &= kmask)
return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON; return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON;
return 1; return 1;
} }
Bigint * Bigint *
set_ones(Bigint *b, int n MTd) set_ones(Bigint *b, int n)
{ {
int k; int k;
ULong *x, *xe; ULong *x, *xe;
k = (n + ((1 << kshift) - 1)) >> kshift; k = (n + ((1 << kshift) - 1)) >> kshift;
if (b->k < k) { if (b->k < k) {
Bfree(b MTa); Bfree(b);
b = Balloc(k MTa); b = Balloc(k);
} }
k = n >> kshift; k = n >> kshift;
if (n &= kmask) if (n &= kmask)
@ -148,17 +115,16 @@ set_ones(Bigint *b, int n MTd)
if (n) if (n)
x[-1] >>= ULbits - n; x[-1] >>= ULbits - n;
return b; return b;
} }
static int static int
rvOK(U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv MTd) rvOK(U *d, const FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv)
{ {
Bigint *b; Bigint *b;
ULong carry, inex, lostbits; ULong carry, inex, lostbits;
int bdif, e, j, k, k1, nb, rv; int bdif, e, j, k, k1, nb, rv;
carry = rv = 0; carry = rv = 0;
b = d2b(dval(d), &e, &bdif MTa); b = d2b(dval(d), &e, &bdif);
bdif -= nb = fpi->nbits; bdif -= nb = fpi->nbits;
e += bdif; e += bdif;
if (bdif <= 0) { if (bdif <= 0) {
@ -167,17 +133,7 @@ rvOK(U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv M
goto ret; goto ret;
} }
if (P == nb) { if (P == nb) {
if ( if (exact && fpi->rounding == FLT_ROUNDS) goto trunc;
#ifndef IMPRECISE_INEXACT
exact &&
#endif
fpi->rounding ==
#ifdef RND_PRODQUOT
FPI_Round_near
#else
Flt_Rounds
#endif
) goto trunc;
goto ret; goto ret;
} }
switch(rd) { switch(rd) {
@ -202,7 +158,7 @@ rvOK(U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv M
} }
/* "break" cases: round up 1 bit, then truncate; bdif > 0 */ /* "break" cases: round up 1 bit, then truncate; bdif > 0 */
carry = 1; carry = 1;
trunc: trunc:
inex = lostbits = 0; inex = lostbits = 0;
if (bdif > 0) { if (bdif > 0) {
if ( (lostbits = any_on(b, bdif)) !=0) if ( (lostbits = any_on(b, bdif)) !=0)
@ -210,7 +166,7 @@ rvOK(U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv M
rshift(b, bdif); rshift(b, bdif);
if (carry) { if (carry) {
inex = STRTOG_Inexhi; inex = STRTOG_Inexhi;
b = increment(b MTa); b = increment(b);
if ( (j = nb & kmask) !=0) if ( (j = nb & kmask) !=0)
j = ULbits - j; j = ULbits - j;
if (hi0bits(b->x[b->wds - 1]) != j) { if (hi0bits(b->x[b->wds - 1]) != j) {
@ -222,7 +178,7 @@ rvOK(U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv M
} }
} }
else if (bdif < 0) else if (bdif < 0)
b = lshift(b, -bdif MTa); b = lshift(b, -bdif);
if (e < fpi->emin) { if (e < fpi->emin) {
k = fpi->emin - e; k = fpi->emin - e;
e = fpi->emin; e = fpi->emin;
@ -241,7 +197,7 @@ rvOK(U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv M
rshift(b, k); rshift(b, k);
*irv = STRTOG_Denormal; *irv = STRTOG_Denormal;
if (carry) { if (carry) {
b = increment(b MTa); b = increment(b);
inex = STRTOG_Inexhi | STRTOG_Underflow; inex = STRTOG_Inexhi | STRTOG_Underflow;
} }
else if (lostbits) else if (lostbits)
@ -251,78 +207,42 @@ rvOK(U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv M
else if (e > fpi->emax) { else if (e > fpi->emax) {
e = fpi->emax + 1; e = fpi->emax + 1;
*irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
#ifndef NO_ERRNO
errno = ERANGE; errno = ERANGE;
#endif
b->wds = inex = 0; b->wds = inex = 0;
} }
*exp = e; *exp = e;
copybits(bits, nb, b); copybits(bits, nb, b);
*irv |= inex; *irv |= inex;
rv = 1; rv = 1;
ret: ret:
Bfree(b MTa); Bfree(b);
return rv; return rv;
} }
static int static int
mantbits(U *d) mantbits(U *d)
{ {
ULong L; ULong L;
#ifdef VAX
L = word1(d) << 16 | word1(d) >> 16;
if (L)
#else
if ( (L = word1(d)) !=0) if ( (L = word1(d)) !=0)
#endif
return P - lo0bits(&L); return P - lo0bits(&L);
#ifdef VAX
L = word0(d) << 16 | word0(d) >> 16 | Exp_msk11;
#else
L = word0(d) | Exp_msk1; L = word0(d) | Exp_msk1;
#endif
return P - 32 - lo0bits(&L); return P - 32 - lo0bits(&L);
} }
int int
strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits) strtodg(const char *s00, char **se, const FPI *fpi, Long *exp, ULong *bits)
{ {
int abe, abits, asub; int abe, abits, asub;
int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm; int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm;
int dsign, e, e1, e2, emin, esign, finished, i, inex, irv, j, k; int dsign, e, e1, e2, emin, esign, finished, i, inex, irv, j, k;
int nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign; int nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign;
int sudden_underflow; int sudden_underflow;
CONST char *s, *s0, *s1; const char *s, *s0, *s1;
double adj0, tol; double adj0, tol;
Long L; Long L;
U adj, rv; U adj, rv;
ULong *b, *be, y, z; ULong *b, *be, y, z;
Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0;
#ifdef MULTIPLE_THREADS
ThInfo *TI = 0;
#endif
#ifdef USE_LOCALE /*{{*/
#ifdef NO_LOCALE_CACHE
char *decimalpoint = localeconv()->decimal_point;
int dplen = strlen(decimalpoint);
#else
char *decimalpoint;
static char *decimalpoint_cache;
static int dplen;
if (!(s0 = decimalpoint_cache)) {
s0 = localeconv()->decimal_point;
if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
strcpy(decimalpoint_cache, s0);
s0 = decimalpoint_cache;
}
dplen = strlen(s0);
}
decimalpoint = (char*)s0;
#endif /*NO_LOCALE_CACHE*/
#else /*USE_LOCALE}{*/
#define dplen 1
#endif /*USE_LOCALE}}*/
irv = STRTOG_Zero; irv = STRTOG_Zero;
denorm = sign = nz0 = nz = 0; denorm = sign = nz0 = nz = 0;
dval(&rv) = 0.; dval(&rv) = 0.;
@ -351,20 +271,18 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
default: default:
goto break2; goto break2;
} }
break2: break2:
if (*s == '0') { if (*s == '0') {
#ifndef NO_HEX_FP
switch(s[1]) { switch(s[1]) {
case 'x': case 'x':
case 'X': case 'X':
irv = gethex(&s, fpi, exp, &rvb, sign MTb); irv = gethex(&s, fpi, exp, &rvb, sign);
if (irv == STRTOG_NoNumber) { if (irv == STRTOG_NoNumber) {
s = s00; s = s00;
sign = 0; sign = 0;
} }
goto ret; goto ret;
} }
#endif
nz0 = 1; nz0 = 1;
while(*++s == '0') ; while(*++s == '0') ;
if (!*s) if (!*s)
@ -379,17 +297,8 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
else if (nd < DBL_DIG + 2) else if (nd < DBL_DIG + 2)
z = 10*z + c - '0'; z = 10*z + c - '0';
nd0 = nd; nd0 = nd;
#ifdef USE_LOCALE
if (c == *decimalpoint) {
for(i = 1; decimalpoint[i]; ++i)
if (s[i] != decimalpoint[i])
goto dig_done;
s += i;
c = *s;
#else
if (c == '.') { if (c == '.') {
c = *++s; c = *++s;
#endif
decpt = 1; decpt = 1;
if (!nd) { if (!nd) {
for(; c == '0'; c = *++s) for(; c == '0'; c = *++s)
@ -420,7 +329,7 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
} }
} }
}/*}*/ }/*}*/
dig_done: dig_done:
e = 0; e = 0;
if (c == 'e' || c == 'E') { if (c == 'e' || c == 'E') {
if (!nd && !nz && !nz0) { if (!nd && !nz && !nz0) {
@ -462,7 +371,6 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
} }
if (!nd) { if (!nd) {
if (!nz && !nz0) { if (!nz && !nz0) {
#ifdef INFNAN_CHECK
/* Check for Nan and Infinity */ /* Check for Nan and Infinity */
if (!decpt) if (!decpt)
switch(c) { switch(c) {
@ -481,20 +389,16 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
if (match(&s, "an")) { if (match(&s, "an")) {
irv = STRTOG_NaN; irv = STRTOG_NaN;
*exp = fpi->emax + 1; *exp = fpi->emax + 1;
#ifndef No_Hex_NaN if (*s == '(')
if (*s == '(') /*)*/
irv = hexnan(&s, fpi, bits); irv = hexnan(&s, fpi, bits);
#endif
goto infnanexp; goto infnanexp;
} }
} }
#endif /* INFNAN_CHECK */
irv = STRTOG_NoNumber; irv = STRTOG_NoNumber;
s = s00; s = s00;
} }
goto ret; goto ret;
} }
irv = STRTOG_Normal; irv = STRTOG_Normal;
e1 = e -= nf; e1 = e -= nf;
rd = 0; rd = 0;
@ -508,12 +412,10 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
case FPI_Round_down: case FPI_Round_down:
rd = 1 + sign; rd = 1 + sign;
} }
/* Now we have nd0 digits, starting at s0, followed by a /* Now we have nd0 digits, starting at s0, followed by a
* decimal point, followed by nd-nd0 digits. The number we're * decimal point, followed by nd-nd0 digits. The number we're
* after is the integer represented by those digits times * after is the integer represented by those digits times
* 10**e */ * 10**e */
if (!nd0) if (!nd0)
nd0 = nd; nd0 = nd;
k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2; k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2;
@ -523,21 +425,17 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
bd0 = 0; bd0 = 0;
if (nbits <= P && nd <= DBL_DIG) { if (nbits <= P && nd <= DBL_DIG) {
if (!e) { if (!e) {
if (rvOK(&rv, fpi, exp, bits, 1, rd, &irv MTb)) if (rvOK(&rv, fpi, exp, bits, 1, rd, &irv))
goto ret; goto ret;
} }
else if (e > 0) { else if (e > 0) {
if (e <= Ten_pmax) { if (e <= Ten_pmax) {
#ifdef VAX
goto vax_ovfl_check;
#else
i = fivesbits[e] + mantbits(&rv) <= P; i = fivesbits[e] + mantbits(&rv) <= P;
/* rv = */ rounded_product(dval(&rv), tens[e]); /* rv = */ rounded_product(dval(&rv), tens[e]);
if (rvOK(&rv, fpi, exp, bits, i, rd, &irv MTb)) if (rvOK(&rv, fpi, exp, bits, i, rd, &irv))
goto ret; goto ret;
e1 -= e; e1 -= e;
goto rv_notOK; goto rv_notOK;
#endif
} }
i = DBL_DIG - nd; i = DBL_DIG - nd;
if (e <= Ten_pmax + i) { if (e <= Ten_pmax + i) {
@ -547,41 +445,22 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
e2 = e - i; e2 = e - i;
e1 -= i; e1 -= i;
dval(&rv) *= tens[i]; dval(&rv) *= tens[i];
#ifdef VAX
/* VAX exponent range is so narrow we must
* worry about overflow here...
*/
vax_ovfl_check:
dval(&adj) = dval(&rv);
word0(&adj) -= P*Exp_msk1;
/* adj = */ rounded_product(dval(&adj), tens[e2]);
if ((word0(&adj) & Exp_mask)
> Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
goto rv_notOK;
word0(&adj) += P*Exp_msk1;
dval(&rv) = dval(&adj);
#else
/* rv = */ rounded_product(dval(&rv), tens[e2]); /* rv = */ rounded_product(dval(&rv), tens[e2]);
#endif if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv))
if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv MTb))
goto ret; goto ret;
e1 -= e2; e1 -= e2;
} }
} }
#ifndef Inaccurate_Divide
else if (e >= -Ten_pmax) { else if (e >= -Ten_pmax) {
/* rv = */ rounded_quotient(dval(&rv), tens[-e]); /* rv = */ rounded_quotient(dval(&rv), tens[-e]);
if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv MTb)) if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv))
goto ret; goto ret;
e1 -= e; e1 -= e;
} }
#endif
} }
rv_notOK: rv_notOK:
e1 += nd - k; e1 += nd - k;
/* Get starting approximation = rv * 10**e1 */ /* Get starting approximation = rv * 10**e1 */
e2 = 0; e2 = 0;
if (e1 > 0) { if (e1 > 0) {
if ( (i = e1 & 15) !=0) if ( (i = e1 & 15) !=0)
@ -626,15 +505,7 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
dval(&rv) *= tinytens[j]; dval(&rv) *= tinytens[j];
} }
} }
#ifdef IBM rvb = d2b(dval(&rv), &rve, &rvbits); /* rv = rvb * 2^rve */
/* e2 is a correction to the (base 2) exponent of the return
* value, reflecting adjustments above to avoid overflow in the
* native arithmetic. For native IBM (base 16) arithmetic, we
* must multiply e2 by 4 to change from base 16 to 2.
*/
e2 <<= 2;
#endif
rvb = d2b(dval(&rv), &rve, &rvbits MTb); /* rv = rvb * 2^rve */
rve += e2; rve += e2;
if ((j = rvbits - nbits) > 0) { if ((j = rvbits - nbits) > 0) {
rshift(rvb, j); rshift(rvb, j);
@ -650,7 +521,7 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
denorm = 1; denorm = 1;
j = rve - emin; j = rve - emin;
if (j > 0) { if (j > 0) {
rvb = lshift(rvb, j MTb); rvb = lshift(rvb, j);
rvbits += j; rvbits += j;
} }
else if (j < 0) { else if (j < 0) {
@ -684,22 +555,17 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
if (sudden_underflow && e2 + 1 < emin) if (sudden_underflow && e2 + 1 < emin)
goto ufl; goto ufl;
} }
/* Now the hard part -- adjusting rv to the correct value.*/ /* Now the hard part -- adjusting rv to the correct value.*/
/* Put digits into bd: true value = bd * 10^e */ /* Put digits into bd: true value = bd * 10^e */
bd0 = s2b(s0, nd0, nd, y, 1);
bd0 = s2b(s0, nd0, nd, y, dplen MTb);
for(;;) { for(;;) {
bd = Balloc(bd0->k MTb); bd = Balloc(bd0->k);
Bcopy(bd, bd0); Bcopy(bd, bd0);
bb = Balloc(rvb->k MTb); bb = Balloc(rvb->k);
Bcopy(bb, rvb); Bcopy(bb, rvb);
bbbits = rvbits - bb0; bbbits = rvbits - bb0;
bbe = rve + bb0; bbe = rve + bb0;
bs = i2b(1 MTb); bs = i2b(1);
if (e >= 0) { if (e >= 0) {
bb2 = bb5 = 0; bb2 = bb5 = 0;
bd2 = bd5 = e; bd2 = bd5 = e;
@ -728,25 +594,25 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
bs2 -= i; bs2 -= i;
} }
if (bb5 > 0) { if (bb5 > 0) {
bs = pow5mult(bs, bb5 MTb); bs = pow5mult(bs, bb5);
bb1 = mult(bs, bb MTb); bb1 = mult(bs, bb);
Bfree(bb MTb); Bfree(bb);
bb = bb1; bb = bb1;
} }
bb2 -= bb0; bb2 -= bb0;
if (bb2 > 0) if (bb2 > 0)
bb = lshift(bb, bb2 MTb); bb = lshift(bb, bb2);
else if (bb2 < 0) else if (bb2 < 0)
rshift(bb, -bb2); rshift(bb, -bb2);
if (bd5 > 0) if (bd5 > 0)
bd = pow5mult(bd, bd5 MTb); bd = pow5mult(bd, bd5);
if (bd2 > 0) if (bd2 > 0)
bd = lshift(bd, bd2 MTb); bd = lshift(bd, bd2);
if (bs2 > 0) if (bs2 > 0)
bs = lshift(bs, bs2 MTb); bs = lshift(bs, bs2);
asub = 1; asub = 1;
inex = STRTOG_Inexhi; inex = STRTOG_Inexhi;
delta = diff(bb, bd MTb); delta = diff(bb, bd);
if (delta->wds <= 1 && !delta->x[0]) if (delta->wds <= 1 && !delta->x[0])
break; break;
dsign = delta->sign; dsign = delta->sign;
@ -771,7 +637,7 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
if (j > 1 && lo0bits(rvb->x + i) < j - 1) if (j > 1 && lo0bits(rvb->x + i) < j - 1)
goto adj1; goto adj1;
rve = rve1 - 1; rve = rve1 - 1;
rvb = set_ones(rvb, rvbits = nbits MTb); rvb = set_ones(rvb, rvbits = nbits);
break; break;
} }
irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi; irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi;
@ -786,7 +652,7 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
: STRTOG_Normal | STRTOG_Inexhi; : STRTOG_Normal | STRTOG_Inexhi;
if (dsign || bbbits > 1 || denorm || rve1 == emin) if (dsign || bbbits > 1 || denorm || rve1 == emin)
break; break;
delta = lshift(delta,1 MTb); delta = lshift(delta,1);
if (cmp(delta, bs) > 0) { if (cmp(delta, bs) > 0) {
irv = STRTOG_Normal | STRTOG_Inexlo; irv = STRTOG_Normal | STRTOG_Inexlo;
goto drop_down; goto drop_down;
@ -818,7 +684,7 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
break; break;
} }
rve -= nbits; rve -= nbits;
rvb = set_ones(rvb, rvbits = nbits MTb); rvb = set_ones(rvb, rvbits = nbits);
break; break;
} }
else else
@ -826,7 +692,7 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1)) if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1))
break; break;
if (dsign) { if (dsign) {
rvb = increment(rvb MTb); rvb = increment(rvb);
j = kmask & (ULbits - (rvbits & kmask)); j = kmask & (ULbits - (rvbits & kmask));
if (hi0bits(rvb->x[rvb->wds - 1]) != j) if (hi0bits(rvb->x[rvb->wds - 1]) != j)
rvbits++; rvbits++;
@ -890,25 +756,23 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
} }
} }
y = rve + rvbits; y = rve + rvbits;
/* adj *= ulp(dval(&rv)); */ /* adj *= ulp(dval(&rv)); */
/* if (asub) rv -= adj; else rv += adj; */ /* if (asub) rv -= adj; else rv += adj; */
if (!denorm && rvbits < nbits) { if (!denorm && rvbits < nbits) {
rvb = lshift(rvb, j = nbits - rvbits MTb); rvb = lshift(rvb, j = nbits - rvbits);
rve -= j; rve -= j;
rvbits = nbits; rvbits = nbits;
} }
ab = d2b(dval(&adj), &abe, &abits MTb); ab = d2b(dval(&adj), &abe, &abits);
if (abe < 0) if (abe < 0)
rshift(ab, -abe); rshift(ab, -abe);
else if (abe > 0) else if (abe > 0)
ab = lshift(ab, abe MTb); ab = lshift(ab, abe);
rvb0 = rvb; rvb0 = rvb;
if (asub) { if (asub) {
/* rv -= adj; */ /* rv -= adj; */
j = hi0bits(rvb->x[rvb->wds-1]); j = hi0bits(rvb->x[rvb->wds-1]);
rvb = diff(rvb, ab MTb); rvb = diff(rvb, ab);
k = rvb0->wds - 1; k = rvb0->wds - 1;
if (denorm) if (denorm)
/* do nothing */; /* do nothing */;
@ -921,7 +785,7 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
denorm = 1; denorm = 1;
} }
else { else {
rvb = lshift(rvb, 1 MTb); rvb = lshift(rvb, 1);
--rve; --rve;
--rve1; --rve1;
L = finished = 0; L = finished = 0;
@ -929,7 +793,7 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
} }
} }
else { else {
rvb = sum(rvb, ab MTb); rvb = sum(rvb, ab);
k = rvb->wds - 1; k = rvb->wds - 1;
if (k >= rvb0->wds if (k >= rvb0->wds
|| hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) { || hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) {
@ -945,11 +809,10 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
} }
} }
} }
Bfree(ab MTb); Bfree(ab);
Bfree(rvb0 MTb); Bfree(rvb0);
if (finished) if (finished)
break; break;
z = rve + rvbits; z = rve + rvbits;
if (y == z && L) { if (y == z && L) {
/* Can we stop now? */ /* Can we stop now? */
@ -967,31 +830,29 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
} }
} }
bb0 = denorm ? 0 : trailz(rvb); bb0 = denorm ? 0 : trailz(rvb);
Bfree(bb MTb); Bfree(bb);
Bfree(bd MTb); Bfree(bd);
Bfree(bs MTb); Bfree(bs);
Bfree(delta MTb); Bfree(delta);
} }
if (!denorm && (j = nbits - rvbits)) { if (!denorm && (j = nbits - rvbits)) {
if (j > 0) if (j > 0)
rvb = lshift(rvb, j MTb); rvb = lshift(rvb, j);
else else
rshift(rvb, -j); rshift(rvb, -j);
rve -= j; rve -= j;
} }
*exp = rve; *exp = rve;
Bfree(bb MTb); Bfree(bb);
Bfree(bd MTb); Bfree(bd);
Bfree(bs MTb); Bfree(bs);
Bfree(bd0 MTb); Bfree(bd0);
Bfree(delta MTb); Bfree(delta);
if (rve > fpi->emax) { if (rve > fpi->emax) {
huge: huge:
Bfree(rvb MTb); Bfree(rvb);
rvb = 0; rvb = 0;
#ifndef NO_ERRNO
errno = ERANGE; errno = ERANGE;
#endif
switch(fpi->rounding & 3) { switch(fpi->rounding & 3) {
case FPI_Round_up: case FPI_Round_up:
if (!sign) if (!sign)
@ -1021,23 +882,19 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
if ((j = fpi->nbits & 0x1f)) if ((j = fpi->nbits & 0x1f))
*--be >>= (32 - j); *--be >>= (32 - j);
} }
ret: ret:
if (denorm) { if (denorm) {
if (sudden_underflow) { if (sudden_underflow) {
rvb->wds = 0; rvb->wds = 0;
irv = STRTOG_Underflow | STRTOG_Inexlo; irv = STRTOG_Underflow | STRTOG_Inexlo;
#ifndef NO_ERRNO
errno = ERANGE; errno = ERANGE;
#endif
} }
else { else {
irv = (irv & ~STRTOG_Retmask) | irv = (irv & ~STRTOG_Retmask) |
(rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero); (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero);
if (irv & STRTOG_Inexact) { if (irv & STRTOG_Inexact) {
irv |= STRTOG_Underflow; irv |= STRTOG_Underflow;
#ifndef NO_ERRNO
errno = ERANGE; errno = ERANGE;
#endif
} }
} }
} }
@ -1047,7 +904,7 @@ strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
irv |= STRTOG_Neg; irv |= STRTOG_Neg;
if (rvb) { if (rvb) {
copybits(bits, nbits, rvb); copybits(bits, nbits, rvb);
Bfree(rvb MTb); Bfree(rvb);
} }
return irv; return irv;
} }

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[_1] = bits[0]; u.L[0] = bits[0];
u.L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); u.L[1] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
break; break;
case STRTOG_Denormal: case STRTOG_Denormal:
u.L[_1] = bits[0]; u.L[0] = bits[0];
u.L[_0] = bits[1]; u.L[1] = bits[1];
break; break;
case STRTOG_Infinite: case STRTOG_Infinite:
u.L[_0] = 0x7ff00000; u.L[1] = 0x7ff00000;
u.L[_1] = 0; u.L[0] = 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[_0] = 0x7ff00000 | bits[1]; u.L[1] = 0x7ff00000 | bits[1];
u.L[_1] = bits[0]; u.L[0] = bits[0];
} }
if (k & STRTOG_Neg) if (k & STRTOG_Neg)
u.L[_0] |= 0x80000000L; u.L[1] |= 0x80000000L;
return u.d; return u.d;
} }

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, 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 */
@ -53,24 +48,20 @@ strtof(CONST char *s, char **sp)
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,45 +1,41 @@
/*-*- 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;
@ -48,12 +44,7 @@ strtopdd(CONST char *s, char **sp, double *dd)
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) {
@ -61,10 +52,9 @@ strtopdd(CONST char *s, char **sp, double *dd)
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[_1] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL; u->L[0] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL;
u->L[_0] = (bits[2] >> 21) | ((bits[3] << 11) & 0xfffff) u->L[1] = (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) {
@ -101,10 +91,9 @@ strtopdd(CONST char *s, char **sp, double *dd)
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;
@ -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[_0] = u->L[2+_0] = 0x7ff00000; u->L[1] = u->L[2+1] = 0x7ff00000;
u->L[_1] = u->L[2+_1] = 0; u->L[0] = u->L[2+0] = 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) { if (rv & STRTOG_Neg) {
u->L[ _0] |= 0x80000000L; u->L[ 1] |= 0x80000000L;
u->L[2+_0] |= 0x80000000L; u->L[2+1] |= 0x80000000L;
} }
return rv; return rv;
} }

View file

@ -1,50 +1,45 @@
/*-*- 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) {
@ -52,24 +47,20 @@ strtopf(CONST char *s, char **sp, float *f)
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[_0] = 0; L[4] = 0;
goto normal_bits; goto normal_bits;
case STRTOG_Normal: case STRTOG_Normal:
case STRTOG_NaNbits: case STRTOG_NaNbits:
L[_0] = exp + 0x3fff + 63; L[4] = exp + 0x3fff + 63;
normal_bits: normal_bits:
L[_4] = (UShort)bits[0]; L[0] = (UShort)bits[0];
L[_3] = (UShort)(bits[0] >> 16); L[1] = (UShort)(bits[0] >> 16);
L[_2] = (UShort)bits[1]; L[2] = (UShort)bits[1];
L[_1] = (UShort)(bits[1] >> 16); L[3] = (UShort)(bits[1] >> 16);
break; break;
case STRTOG_Infinite: case STRTOG_Infinite:
L[_0] = 0x7fff; L[4] = 0x7fff;
L[_1] = 0x8000; L[3] = 0x8000;
L[_2] = L[_3] = L[_4] = 0; L[2] = L[1] = L[0] = 0;
break; break;
case STRTOG_NaN: case STRTOG_NaN:
L[_4] = __gdtoa_NanDflt_ldus[0]; L[0] = __gdtoa_NanDflt_ldus[0];
L[_3] = __gdtoa_NanDflt_ldus[1]; L[1] = __gdtoa_NanDflt_ldus[1];
L[_2] = __gdtoa_NanDflt_ldus[2]; L[2] = __gdtoa_NanDflt_ldus[2];
L[_1] = __gdtoa_NanDflt_ldus[3]; L[3] = __gdtoa_NanDflt_ldus[3];
L[_0] = __gdtoa_NanDflt_ldus[4]; L[4] = __gdtoa_NanDflt_ldus[4];
} }
if (k & STRTOG_Neg) if (k & STRTOG_Neg)
L[_0] |= 0x8000; L[4] |= 0x8000;
return k; return k;
} }

View file

@ -1,38 +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 "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)
@ -42,40 +42,35 @@ ULtod(ULong *L, ULong *bits, Long exp, int k)
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[_1] = bits[0]; L[0] = bits[0];
L[_0] = bits[1]; L[1] = bits[1];
break; break;
case STRTOG_Normal: case STRTOG_Normal:
case STRTOG_NaNbits: case STRTOG_NaNbits:
L[_1] = bits[0]; L[0] = bits[0];
L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); L[1] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
break; break;
case STRTOG_Infinite: case STRTOG_Infinite:
L[_0] = 0x7ff00000; L[1] = 0x7ff00000;
L[_1] = 0; L[0] = 0;
break; break;
case STRTOG_NaN: case STRTOG_NaN:
L[_0] = __gdtoa_NanDflt_d[1]; L[1] = __gdtoa_NanDflt_d[1];
L[_1] = __gdtoa_NanDflt_d[0]; L[0] = __gdtoa_NanDflt_d[0];
} }
if (k & STRTOG_Neg) if (k & STRTOG_Neg)
L[_0] |= 0x80000000L; 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;
@ -85,4 +80,4 @@ strtord(CONST char *s, char **sp, int rounding, double *d)
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,53 +1,51 @@
/*-*- 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[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL; L[0] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL;
L[_0] = (bits[2] >> 21) | (bits[3] << 11 & 0xfffff) L[1] = (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) {
@ -84,10 +82,9 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k)
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;
@ -97,92 +94,81 @@ 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[_0] = L[2+_0] = 0x7ff00000; L[1] = L[2+1] = 0x7ff00000;
L[_1] = L[2+_1] = 0; L[0] = L[2+0] = 0;
break; break;
case STRTOG_NaN: case STRTOG_NaN:
L[_0] = L[_0+2] = __gdtoa_NanDflt_d[1]; L[1] = L[1+2] = __gdtoa_NanDflt_d[1];
L[_1] = L[_1+2] = __gdtoa_NanDflt_d[0]; L[0] = L[0+2] = __gdtoa_NanDflt_d[0];
break; break;
case STRTOG_NaNbits: case STRTOG_NaNbits:
L[_1] = (bits[1] >> 20 | bits[2] << 12) & (ULong)0xffffffffL; L[0] = (bits[1] >> 20 | bits[2] << 12) & (ULong)0xffffffffL;
L[_0] = bits[2] >> 20 | bits[3] << 12; L[1] = bits[2] >> 20 | bits[3] << 12;
L[_0] |= (L[_1] | L[_0]) ? (ULong)0x7ff00000L : (ULong)0x7ff80000L; L[1] |= (L[0] | L[1]) ? (ULong)0x7ff00000L : (ULong)0x7ff80000L;
L[2+_1] = bits[0] & (ULong)0xffffffffL; L[2+0] = bits[0] & (ULong)0xffffffffL;
L[2+_0] = bits[1] & 0xfffffL; L[2+1] = bits[1] & 0xfffffL;
L[2+_0] |= (L[2+_1] | L[2+_0]) ? (ULong)0x7ff00000L : (ULong)0x7ff80000L; L[2+1] |= (L[2+0] | L[2+1]) ? (ULong)0x7ff00000L : (ULong)0x7ff80000L;
} }
if (k & STRTOG_Neg) { if (k & STRTOG_Neg) {
L[_0] |= 0x80000000L; L[1] |= 0x80000000L;
L[2+_0] |= 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;
@ -192,4 +178,4 @@ strtordd(CONST char *s, char **sp, int rounding, double *dd)
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,38 +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 "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)
@ -42,36 +42,31 @@ ULtof(ULong *L, ULong *bits, Long exp, int k)
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;
@ -81,4 +76,4 @@ strtorf(CONST char *s, char **sp, int rounding, float *f)
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];
@ -62,47 +42,42 @@ ULtox(UShort *L, ULong *bits, Long exp, int k)
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[_0] = 0; L[4] = 0;
goto normal_bits; goto normal_bits;
case STRTOG_Normal: case STRTOG_Normal:
case STRTOG_NaNbits: case STRTOG_NaNbits:
L[_0] = exp + 0x3fff + 63; L[4] = exp + 0x3fff + 63;
normal_bits: normal_bits:
L[_4] = (UShort)bits[0]; L[0] = (UShort)bits[0];
L[_3] = (UShort)(bits[0] >> 16); L[1] = (UShort)(bits[0] >> 16);
L[_2] = (UShort)bits[1]; L[2] = (UShort)bits[1];
L[_1] = (UShort)(bits[1] >> 16); L[3] = (UShort)(bits[1] >> 16);
break; break;
case STRTOG_Infinite: case STRTOG_Infinite:
L[_0] = 0x7fff; L[4] = 0x7fff;
L[_1] = 0x8000; L[3] = 0x8000;
L[_2] = L[_3] = L[_4] = 0; L[2] = L[1] = L[0] = 0;
break; break;
case STRTOG_NaN: case STRTOG_NaN:
L[_4] = __gdtoa_NanDflt_ldus[0]; L[0] = __gdtoa_NanDflt_ldus[0];
L[_3] = __gdtoa_NanDflt_ldus[1]; L[1] = __gdtoa_NanDflt_ldus[1];
L[_2] = __gdtoa_NanDflt_ldus[2]; L[2] = __gdtoa_NanDflt_ldus[2];
L[_1] = __gdtoa_NanDflt_ldus[3]; L[3] = __gdtoa_NanDflt_ldus[3];
L[_0] = __gdtoa_NanDflt_ldus[4]; L[4] = __gdtoa_NanDflt_ldus[4];
} }
if (k & STRTOG_Neg) if (k & STRTOG_Neg)
L[_0] |= 0x8000; 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;
@ -112,4 +87,4 @@ strtorx(CONST char *s, char **sp, int rounding, void *L)
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,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 "."). */
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;
@ -68,28 +64,14 @@ sum(Bigint *a, Bigint *b MTd)
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; c->x[c->wds++] = 1;
} }
return c; return c;
} }

View file

@ -1,53 +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, 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;
@ -61,6 +54,5 @@ ulp(U *x)
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__"