strtopx(CONST char *s, char **sp, void *V) #endif { static const FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; ULong bits[2]; Long expt; int k; UShort *L = (UShort*)V; #ifdef Honor_FLT_ROUNDS #include "gdtoa_fltrnds.h" #else #define fpi &fpi0 #endif k = strtodg(s, sp, fpi, &expt, bits); if (k == STRTOG_NoMemory) return k; switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: L[0] = L[1] = L[2] = L[3] = L[4] = 0; break; case STRTOG_Denormal: L[_0] = 0; goto normal_bits; case STRTOG_Normal: case STRTOG_NaNbits: L[_0] = expt + 0x3fff + 63; normal_bits: L[_4] = (UShort)bits[0]; L[_3] = (UShort)(bits[0] >> 16); L[_2] = (UShort)bits[1]; L[_1] = (UShort)(bits[1] >> 16); break; case STRTOG_Infinite: L[_0] = 0x7fff; L[_1] = 0x8000; L[_2] = L[_3] = L[_4] = 0; break; case STRTOG_NaN: L[0] = ldus_QNAN0; L[1] = ldus_QNAN1; L[2] = ldus_QNAN2; L[3] = ldus_QNAN3; L[4] = ldus_QNAN4; } if (k & STRTOG_Neg) L[_0] |= 0x8000; return k; }
strtopQ(CONST char *s, char **sp, void *V) #endif { static FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, SI }; ULong bits[4]; Long exp; int k; ULong *L = (ULong*)V; #ifdef Honor_FLT_ROUNDS #include "gdtoa_fltrnds.h" #else #define fpi &fpi0 #endif k = strtodg(s, sp, fpi, &exp, bits); switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: L[0] = L[1] = L[2] = L[3] = 0; break; case STRTOG_Normal: case STRTOG_NaNbits: L[_3] = bits[0]; L[_2] = bits[1]; L[_1] = bits[2]; L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16); break; case STRTOG_Denormal: L[_3] = bits[0]; L[_2] = bits[1]; L[_1] = bits[2]; L[_0] = bits[3]; break; case STRTOG_Infinite: L[_0] = 0x7fff0000; L[_1] = L[_2] = L[_3] = 0; break; case STRTOG_NaN: L[_0] = NanDflt_Q_D2A[3]; L[_1] = NanDflt_Q_D2A[2]; L[_2] = NanDflt_Q_D2A[1]; L[_3] = NanDflt_Q_D2A[0]; } if (k & STRTOG_Neg) L[_0] |= 0x80000000L; return k; }
strtopx(CONST char *s, char **sp, void *V) #endif { static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; ULong bits[2]; Long expt; int k; UShort *L = (UShort*)V; k = strtodg(s, sp, &fpi, &expt, bits); if (k == STRTOG_NoMemory) return k; switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: L[0] = L[1] = L[2] = L[3] = L[4] = 0; break; case STRTOG_Denormal: L[_0] = 0; goto normal_bits; case STRTOG_Normal: case STRTOG_NaNbits: L[_0] = (UShort)(expt + 0x3fff + 63); normal_bits: L[_4] = (UShort)bits[0]; L[_3] = (UShort)(bits[0] >> 16); L[_2] = (UShort)bits[1]; L[_1] = (UShort)(bits[1] >> 16); break; case STRTOG_Infinite: L[_0] = 0x7fff; L[_1] = L[_2] = L[_3] = L[_4] = 0; break; case STRTOG_NaN: L[0] = ldus_QNAN0; L[1] = ldus_QNAN1; L[2] = ldus_QNAN2; L[3] = ldus_QNAN3; L[4] = ldus_QNAN4; } if (k & STRTOG_Neg) L[_0] |= 0x8000; return k; }
strtopQ(CONST char *s, char **sp, void *V) #endif { static CONST FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, SI }; ULong bits[4]; Long expt; int k; ULong *L = (ULong*)V; k = strtodg(s, sp, &fpi, &expt, bits); if (k == STRTOG_NoMemory) return k; switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: L[0] = L[1] = L[2] = L[3] = 0; break; case STRTOG_Normal: case STRTOG_NaNbits: L[_3] = bits[0]; L[_2] = bits[1]; L[_1] = bits[2]; L[_0] = (bits[3] & ~0x10000) | ((expt + 0x3fff + 112) << 16); break; case STRTOG_Denormal: L[_3] = bits[0]; L[_2] = bits[1]; L[_1] = bits[2]; L[_0] = bits[3]; break; case STRTOG_Infinite: L[_0] = 0x7fff0000; L[_1] = L[_2] = L[_3] = 0; break; case STRTOG_NaN: L[0] = ld_QNAN0; L[1] = ld_QNAN1; L[2] = ld_QNAN2; L[3] = ld_QNAN3; } if (k & STRTOG_Neg) L[_0] |= 0x80000000L; return k; }
strtof(CONST char *s, char **sp) #endif { static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; ULong bits[1]; Long exp; int k; union { ULong L[1]; float f; } u; #ifdef Honor_FLT_ROUNDS #include "gdtoa_fltrnds.h" #else #define fpi &fpi0 #endif k = strtodg(s, sp, fpi, &exp, bits); switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: u.L[0] = 0; break; case STRTOG_Normal: u.L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23); break; case STRTOG_NaNbits: /* FreeBSD local: always return a quiet NaN */ u.L[0] = bits[0] | 0x7fc00000; break; case STRTOG_Denormal: u.L[0] = bits[0]; break; case STRTOG_Infinite: u.L[0] = 0x7f800000; break; case STRTOG_NaN: u.L[0] = f_QNAN; } if (k & STRTOG_Neg) u.L[0] |= 0x80000000L; return u.f; }
strtod(CONST char *s, char **sp) #endif { static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; ULong bits[2]; Long exp; int k; union { ULong L[2]; double d; } u; k = strtodg(s, sp, &fpi, &exp, bits); switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: u.L[0] = u.L[1] = 0; break; case STRTOG_Normal: u.L[_1] = bits[0]; u.L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); break; case STRTOG_Denormal: u.L[_1] = bits[0]; u.L[_0] = bits[1]; break; case STRTOG_Infinite: u.L[_0] = 0x7ff00000; u.L[_1] = 0; break; case STRTOG_NaN: u.L[0] = d_QNAN0; u.L[1] = d_QNAN1; break; case STRTOG_NaNbits: u.L[_0] = 0x7ff00000 | bits[1]; u.L[_1] = bits[0]; } if (k & STRTOG_Neg) u.L[_0] |= 0x80000000L; return u.d; }
strtof(CONST char *s, char **sp) #endif { static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; ULong bits[1]; Long exp; int k; union { ULong L[1]; float f; } u; #ifdef Honor_FLT_ROUNDS #include "gdtoa_fltrnds.h" #else #define fpi &fpi0 #endif k = strtodg(s, sp, fpi, &exp, bits); switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: u.L[0] = 0; break; case STRTOG_Normal: case STRTOG_NaNbits: u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; break; case STRTOG_Denormal: u.L[0] = bits[0]; break; case STRTOG_NoMemory: errno = ERANGE; /* FALLTHROUGH */ case STRTOG_Infinite: u.L[0] = 0x7f800000; break; case STRTOG_NaN: u.L[0] = f_QNAN; } if (k & STRTOG_Neg) u.L[0] |= 0x80000000L; return u.f; }
strtord(CONST char *s, char **sp, int rounding, double *d) #endif { static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; FPI *fpi, fpi1; ULong bits[2]; Long exp; int k; fpi = &fpi0; if (rounding != FPI_Round_near) { fpi1 = fpi0; fpi1.rounding = rounding; fpi = &fpi1; } k = strtodg(s, sp, fpi, &exp, bits); ULtod((ULong*)d, bits, exp, k); return k; }
strtopxL(CONST char *s, char **sp, void *V) #endif { static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; ULong bits[2]; Long exp; int k; ULong *L = (ULong*)V; #ifdef Honor_FLT_ROUNDS #include "gdtoa_fltrnds.h" #else #define fpi &fpi0 #endif k = strtodg(s, sp, fpi, &exp, bits); switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: L[0] = L[1] = L[2] = 0; break; case STRTOG_Normal: case STRTOG_Denormal: case STRTOG_NaNbits: L[_2] = bits[0]; L[_1] = bits[1]; L[_0] = (exp + 0x3fff + 63) << 16; break; case STRTOG_Infinite: L[_0] = 0x7fff << 16; L[_1] = L[_2] = 0; break; case STRTOG_NaN: L[0] = ld_QNAN0; L[1] = ld_QNAN1; L[2] = ld_QNAN2; } if (k & STRTOG_Neg) L[_0] |= 0x80000000L; return k; }
strtopd(CONST char *s, char **sp, double *d) #endif { static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; ULong bits[2]; Long expt; int k; #ifdef Honor_FLT_ROUNDS #include "gdtoa_fltrnds.h" #else #define fpi &fpi0 #endif k = strtodg(s, sp, fpi, &expt, bits); if (k == STRTOG_NoMemory) return k; ULtod((ULong*)d, bits, expt, k); return k; }
strtorf(CONST char *s, char **sp, int rounding, float *f) #endif { static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; FPI *fpi, fpi1; ULong bits[1]; Long exp; int k; fpi = &fpi0; if (rounding != FPI_Round_near) { fpi1 = fpi0; fpi1.rounding = rounding; fpi = &fpi1; } k = strtodg(s, sp, fpi, &exp, bits); ULtof((ULong*)f, bits, exp, k); return k; }
strtopf(CONST char *s, char **sp, float *f) #endif { static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; ULong bits[1], *L; Long expt; int k; #ifdef Honor_FLT_ROUNDS #include "gdtoa_fltrnds.h" #else #define fpi &fpi0 #endif k = strtodg(s, sp, fpi, &expt, bits); if (k == STRTOG_NoMemory) return k; L = (ULong*)f; switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: L[0] = 0; break; case STRTOG_Normal: case STRTOG_NaNbits: L[0] = (bits[0] & 0x7fffff) | ((expt + 0x7f + 23) << 23); break; case STRTOG_Denormal: L[0] = bits[0]; break; case STRTOG_Infinite: L[0] = 0x7f800000; break; case STRTOG_NaN: L[0] = f_QNAN; } if (k & STRTOG_Neg) L[0] |= 0x80000000L; return k; }
strtorQ(CONST char *s, char **sp, int rounding, void *L) #endif { static FPI fpi0 = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; FPI *fpi, fpi1; ULong bits[4]; Long exp; int k; fpi = &fpi0; if (rounding != FPI_Round_near) { fpi1 = fpi0; fpi1.rounding = rounding; fpi = &fpi1; } k = strtodg(s, sp, fpi, &exp, bits); ULtoQ((ULong*)L, bits, exp, k); return k; }
strtof(CONST char *s, char **sp) #endif { static CONST FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; ULong bits[1]; Long expt; int k; union { ULong L[1]; float f; } u = { { 0 } }; k = strtodg(s, sp, &fpi, &expt, bits); if (k == STRTOG_NoMemory) { errno = ERANGE; return HUGE_VALF; } switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: u.L[0] = 0; break; case STRTOG_Normal: case STRTOG_NaNbits: u.L[0] = (bits[0] & 0x7fffff) | ((expt + 0x7f + 23) << 23); break; case STRTOG_Denormal: u.L[0] = bits[0]; break; case STRTOG_Infinite: u.L[0] = 0x7f800000; break; case STRTOG_NaN: u.L[0] = f_QNAN; } if (k & STRTOG_Neg) u.L[0] |= 0x80000000L; return u.f; }
int strtord(CONST char *s, char **sp, int rounding, double *d, locale_t loc) { static CONST FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; CONST FPI *fpi; FPI fpi1; ULong bits[2]; Long expt; int k; fpi = &fpi0; if (rounding != FPI_Round_near) { fpi1 = fpi0; fpi1.rounding = rounding; fpi = &fpi1; } k = strtodg(s, sp, fpi, &expt, bits, loc); if (k == STRTOG_NoMemory) return k; ULtod((/* LINTED */(U*)d)->L, bits, expt, k); return k; }
strtopf(CONST char *s, char **sp, float *f) #endif { static CONST FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; ULong bits[1], *L; Long exp; int k; k = strtodg(s, sp, &fpi, &exp, bits); L = (ULong*)f; switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: L[0] = 0; break; case STRTOG_Normal: case STRTOG_NaNbits: L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; break; case STRTOG_Denormal: L[0] = bits[0]; break; case STRTOG_Infinite: L[0] = 0x7f800000; break; case STRTOG_NaN: L[0] = f_QNAN; } if (k & STRTOG_Neg) L[0] |= 0x80000000L; return k; }
strtoIg(CONST char *s00, char **se, FPI *fpi, Long *exp, Bigint **B, int *rvp) #endif { Bigint *b, *b1; int i, nb, nw, nw1, rv, rv1, swap; unsigned int nb1, nb11; Long e1; b = *B; rv = strtodg(s00, se, fpi, exp, b->x); if (rv == STRTOG_NoMemory) return rv; if (!(rv & STRTOG_Inexact)) { B[1] = 0; return *rvp = rv; } e1 = exp[0]; rv1 = rv ^ STRTOG_Inexact; b1 = Balloc(b->k); if (b1 == NULL) return STRTOG_NoMemory; Bcopy(b1, b); nb = fpi->nbits; nb1 = nb & 31; nb11 = (nb1 - 1) & 31; nw = b->wds; nw1 = nw - 1; if (rv & STRTOG_Inexlo) { swap = 0; b1 = increment(b1); if (fpi->sudden_underflow && (rv & STRTOG_Retmask) == STRTOG_Zero) { b1->x[0] = 0; b1->x[nw1] = 1L << nb11; rv1 += STRTOG_Normal - STRTOG_Zero; rv1 &= ~STRTOG_Underflow; goto swapcheck; } if (b1->wds > nw || nb1 && b1->x[nw1] & 1L << nb1) { if (++e1 > fpi->emax) rv1 = STRTOG_Infinite | STRTOG_Inexhi; rshift(b1, 1); } else if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { if (b1->x[nw1] & 1L << nb11) { rv1 += STRTOG_Normal - STRTOG_Denormal; rv1 &= ~STRTOG_Underflow; } } } else { swap = STRTOG_Neg; if ((rv & STRTOG_Retmask) == STRTOG_Infinite) { b1 = set_ones(b1, nb); e1 = fpi->emax; rv1 = STRTOG_Normal | STRTOG_Inexlo; goto swapcheck; } decrement(b1); if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { for(i = nw1; !b1->x[i]; --i) if (!i) { rv1 = STRTOG_Zero | STRTOG_Inexlo; break; } goto swapcheck; } if (!(b1->x[nw1] & 1L << nb11)) { if (e1 == fpi->emin) { if (fpi->sudden_underflow) rv1 += STRTOG_Zero - STRTOG_Normal; else rv1 += STRTOG_Denormal - STRTOG_Normal; rv1 |= STRTOG_Underflow; } else { b1 = lshift(b1, 1); b1->x[0] |= 1; --e1; } } } swapcheck: if (swap ^ (rv & STRTOG_Neg)) { rvp[0] = rv1; rvp[1] = rv; B[0] = b1; B[1] = b; exp[1] = exp[0]; exp[0] = e1; } else { rvp[0] = rv; rvp[1] = rv1; B[1] = b1; exp[1] = e1; } return rv; }
strtodI(CONST char *s, char **sp, double *dd) #endif { static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; ULong bits[2], sign; Long exp; int j, k; U *u; k = strtodg(s, sp, &fpi, &exp, bits); u = (U*)dd; sign = k & STRTOG_Neg ? 0x80000000L : 0; switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: dval(&u[0]) = dval(&u[1]) = 0.; break; case STRTOG_Zero: 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; #endif case STRTOG_Denormal: word1(&u[0]) = bits[0]; word0(&u[0]) = bits[1]; goto contain; case STRTOG_Normal: word1(&u[0]) = bits[0]; word0(&u[0]) = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); contain: j = k & STRTOG_Inexact; if (sign) { word0(&u[0]) |= sign; j = STRTOG_Inexact - j; } switch(j) { 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]); break; case STRTOG_Inexhi: 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); break; default: dval(&u[1]) = dval(&u[0]); } break; case STRTOG_Infinite: word0(&u[0]) = word0(&u[1]) = sign | 0x7ff00000; word1(&u[0]) = word1(&u[1]) = 0; if (k & STRTOG_Inexact) { if (sign) { word0(&u[1]) = 0xffefffffL; word1(&u[1]) = 0xffffffffL; } else { word0(&u[0]) = 0x7fefffffL; word1(&u[0]) = 0xffffffffL; } } break; case STRTOG_NaN: u->L[0] = (u+1)->L[0] = d_QNAN0; u->L[1] = (u+1)->L[1] = d_QNAN1; break; case STRTOG_NaNbits: word0(&u[0]) = word0(&u[1]) = 0x7ff00000 | sign | bits[1]; word1(&u[0]) = word1(&u[1]) = bits[0]; } return k; }