gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) #endif { Bigint *b; CONST unsigned char *decpt, *s0, *s, *s1; int esign, havedig, irv, k, n, nbits, up; ULong L, lostbits, *x; Long e, e1; #ifdef USE_LOCALE unsigned char decimalpoint = *localeconv()->decimal_point; #else #define decimalpoint '.' #endif #ifndef __SYMBIAN32__ if (!hexdig['0']) hexdig_init_D2A(); #endif //__SYMBIAN32__ havedig = 0; s0 = *(CONST unsigned char **)sp + 2; while(s0[havedig] == '0') havedig++; s0 += havedig; s = s0; decpt = 0; if (!hexdig[*s]) { if (*s == decimalpoint) { decpt = ++s; if (!hexdig[*s]) goto ret0; } else { ret0: *sp = (char*)s; return havedig ? STRTOG_Zero : STRTOG_NoNumber; } while(*s == '0') s++; havedig = 1; if (!hexdig[*s]) goto ret0; s0 = s; } while(hexdig[*s]) s++; if (*s == decimalpoint && !decpt) { decpt = ++s; while(hexdig[*s]) s++; } e = 0; if (decpt) e = -(((Long)(s-decpt)) << 2); s1 = s; switch(*s) { case 'p': case 'P': esign = 0; switch(*++s) { case '-': esign = 1; /* no break */ case '+': s++; } if ((n = hexdig[*s]) == 0 || n > 0x19) { s = s1; break; } e1 = n - 0x10; while((n = hexdig[*++s]) !=0 && n <= 0x19) e1 = 10*e1 + n - 0x10; if (esign) e1 = -e1; e += e1; } *sp = (char*)s; n = s1 - s0 - 1; for(k = 0; n > 7; n >>= 1) k++; b = Balloc(k); x = b->x; n = 0; L = 0; while(s1 > s0) { if (*--s1 == decimalpoint) continue; if (n == 32) { *x++ = L; L = 0; n = 0; } L |= (hexdig[*s1] & 0x0f) << n; n += 4; } *x++ = L; b->wds = n = x - b->x; n = 32*n - hi0bits(L); nbits = fpi->nbits; lostbits = 0; x = b->x; if (n > nbits) { n -= nbits; if (any_on(b,n)) { lostbits = 1; k = n - 1; if (x[k>>kshift] & 1 << (k & kmask)) { lostbits = 2; if (k > 1 && any_on(b,k-1)) lostbits = 3; } } rshift(b, n); e += n; }
int gethex( CONST char **sp, CONST FPI *fpi, Long *expt, Bigint **bp, int sign) { Bigint *b; CONST unsigned char *decpt, *s0, *s, *s1; int esign, havedig, irv, k, n, nbits, up, zret; ULong L, lostbits, *x; Long e, e1; #ifdef USE_LOCALE unsigned char decimalpoint = *localeconv()->decimal_point; #else #define decimalpoint '.' #endif if (!hexdig['0']) hexdig_init_D2A(); havedig = 0; s0 = *(CONST unsigned char **)sp + 2; while(s0[havedig] == '0') havedig++; s0 += havedig; s = s0; decpt = 0; zret = 0; e = 0; if (!hexdig[*s]) { zret = 1; if (*s != decimalpoint) goto pcheck; decpt = ++s; if (!hexdig[*s]) goto pcheck; while(*s == '0') s++; if (hexdig[*s]) zret = 0; havedig = 1; s0 = s; } while(hexdig[*s]) s++; if (*s == decimalpoint && !decpt) { decpt = ++s; while(hexdig[*s]) s++; } if (decpt) e = -(((Long)(s-decpt)) << 2); pcheck: s1 = s; switch(*s) { case 'p': case 'P': esign = 0; switch(*++s) { case '-': esign = 1; /* FALLTHROUGH */ case '+': s++; } if ((n = hexdig[*s]) == 0 || n > 0x19) { s = s1; break; } e1 = n - 0x10; while((n = hexdig[*++s]) !=0 && n <= 0x19) e1 = 10*e1 + n - 0x10; if (esign) e1 = -e1; e += e1; } *sp = __UNCONST(s); if (zret) return havedig ? STRTOG_Zero : STRTOG_NoNumber; n = (int)(s1 - s0 - 1); for(k = 0; n > 7; n = (unsigned int)n >> 1) k++; b = Balloc(k); if (b == NULL) return STRTOG_NoMemory; x = b->x; n = 0; L = 0; while(s1 > s0) { if (*--s1 == decimalpoint) continue; if (n == 32) { *x++ = L; L = 0; n = 0; } L |= (hexdig[*s1] & 0x0f) << n; n += 4; } *x++ = L; b->wds = n = (int)(x - b->x); n = 32*n - hi0bits(L); nbits = fpi->nbits; lostbits = 0; x = b->x; if (n > nbits) { n -= nbits; if (any_on(b,n)) { lostbits = 1; k = n - 1; if (x[(unsigned int)k>>kshift] & 1 << (k & kmask)) { lostbits = 2; if (k > 1 && any_on(b,k-1)) lostbits = 3; } } rshift(b, n); e += n; }
g_ddfmt(char *buf, double *dd0, int ndig, size_t bufsize) #endif { FPI fpi; char *b, *s, *se; ULong *L, bits0[4], *bits, *zx; int bx, by, decpt, ex, ey, i, j, mode; Bigint *x, *y, *z; U *dd, ddx[2]; #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 < ndig + 8) return 0; dd = (U*)dd0; L = dd->L; if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) { /* Infinity or NaN */ if (L[_0] & 0xfffff || L[_1]) { nanret: return strcp(buf, "NaN"); } if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { if (L[2+_0] & 0xfffff || L[2+_1]) goto nanret; if ((L[_0] ^ L[2+_0]) & 0x80000000L) goto nanret; /* Infinity - Infinity */ } infret: b = buf; if (L[_0] & 0x80000000L) *b++ = '-'; return strcp(b, "Infinity"); } if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { L += 2; if (L[_0] & 0xfffff || L[_1]) goto nanret; goto infret; } if (dval(&dd[0]) + dval(&dd[1]) == 0.) { b = buf; #ifndef IGNORE_ZERO_SIGN if (L[_0] & L[2+_0] & 0x80000000L) *b++ = '-'; #endif *b++ = '0'; *b = 0; return b; } if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) { dval(&ddx[1]) = dval(&dd[0]); dval(&ddx[0]) = dval(&dd[1]); dd = ddx; L = dd->L; } z = d2b(dval(&dd[0]), &ex, &bx); if (dval(&dd[1]) == 0.) goto no_y; x = z; y = d2b(dval(&dd[1]), &ey, &by); if ( (i = ex - ey) !=0) { if (i > 0) { x = lshift(x, i); ex = ey; } else y = lshift(y, -i); } if ((L[_0] ^ L[2+_0]) & 0x80000000L) { z = diff(x, y); if (L[_0] & 0x80000000L) z->sign = 1 - z->sign; } else { z = sum(x, y); if (L[_0] & 0x80000000L) z->sign = 1; } Bfree(x); Bfree(y); no_y: bits = zx = z->x; for(i = 0; !*zx; zx++) i += 32; i += lo0bits(zx); if (i) { rshift(z, i); ex += i; } fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]); if (fpi.nbits < 106) { fpi.nbits = 106; if (j < 3) { for(i = 0; i <= j; i++) bits0[i] = bits[i]; while(i < 4) bits0[i++] = 0; bits = bits0; } } mode = 2; if (ndig <= 0) { if (bufsize < (int)(fpi.nbits * .301029995664) + 10) { Bfree(z); return 0; } mode = 0; } fpi.emin = 1-1023-53+1; fpi.emax = 2046-1023-106+1; fpi.rounding = Rounding; fpi.sudden_underflow = 0; i = STRTOG_Normal; s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); b = g__fmt(buf, s, se, decpt, z->sign, bufsize); Bfree(z); return b; }
gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) #endif { Bigint *b; CONST unsigned char *decpt, *s0, *s, *s1; int big, esign, havedig, irv, j, k, n, n0, nbits, up, zret; ULong L, lostbits, *x; 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']) hexdig_init_D2A(); *bp = 0; havedig = 0; s0 = *(CONST unsigned char **)sp + 2; while(s0[havedig] == '0') havedig++; s0 += havedig; s = s0; decpt = 0; zret = 0; e = 0; if (hexdig[*s]) havedig++; else { zret = 1; #ifdef USE_LOCALE for(i = 0; decimalpoint[i]; ++i) { if (s[i] != decimalpoint[i]) goto pcheck; } decpt = s += i; #else if (*s != '.') goto pcheck; decpt = ++s; #endif if (!hexdig[*s]) goto pcheck; while(*s == '0') s++; if (hexdig[*s]) zret = 0; havedig = 1; s0 = s; } while(hexdig[*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) { decpt = ++s; #endif while(hexdig[*s]) s++; }/*}*/ if (decpt) e = -(((Long)(s-decpt)) << 2); pcheck: s1 = s; big = esign = 0; switch(*s) { case 'p': case 'P': switch(*++s) { case '-': esign = 1; /* no break */ case '+': s++; } if ((n = hexdig[*s]) == 0 || n > 0x19) { s = s1; break; } e1 = n - 0x10; while((n = hexdig[*++s]) !=0 && n <= 0x19) { if (e1 & 0xf8000000) big = 1; e1 = 10*e1 + n - 0x10; } if (esign) e1 = -e1; e += e1; } *sp = (char*)s; if (!havedig) *sp = (char*)s0 - 1; if (zret) return STRTOG_Zero; if (big) { if (esign) { switch(fpi->rounding) { case FPI_Round_up: if (sign) break; goto ret_tiny; case FPI_Round_down: if (!sign) break; goto ret_tiny; } goto retz; ret_tiny: b = Balloc(0); b->wds = 1; b->x[0] = 1; goto dret; } switch(fpi->rounding) { case FPI_Round_near: goto ovfl1; case FPI_Round_up: if (!sign) goto ovfl1; goto ret_big; case FPI_Round_down: if (sign) goto ovfl1; goto ret_big; } ret_big: nbits = fpi->nbits; n0 = n = nbits >> kshift; if (nbits & kmask) ++n; for(j = n, k = 0; j >>= 1; ++k); *bp = b = Balloc(k); b->wds = n; for(j = 0; j < n0; ++j) b->x[j] = ALL_ON; if (n > n0) b->x[j] = ULbits >> (ULbits - (nbits & kmask)); *exp = fpi->emin; return STRTOG_Normal | STRTOG_Inexlo; } n = s1 - s0 - 1; for(k = 0; n > 7; n >>= 1) k++; b = Balloc(k); x = b->x; n = 0; L = 0; #ifdef USE_LOCALE for(i = 0; decimalpoint[i+1]; ++i); #endif while(s1 > s0) { #ifdef USE_LOCALE if (*--s1 == decimalpoint[i]) { s1 -= i; continue; } #else if (*--s1 == '.') continue; #endif if (n == 32) { *x++ = L; L = 0; n = 0; } L |= (hexdig[*s1] & 0x0f) << n; n += 4; } *x++ = L; b->wds = n = x - b->x; n = 32*n - hi0bits(L); nbits = fpi->nbits; lostbits = 0; x = b->x; if (n > nbits) { n -= nbits; if (any_on(b,n)) { lostbits = 1; k = n - 1; if (x[k>>kshift] & 1 << (k & kmask)) { lostbits = 2; if (k > 0 && any_on(b,k)) lostbits = 3; } } rshift(b, n); e += n; } else if (n < nbits) {