return b;
}
- int
+ void
#ifdef KR_headers
decrement(b) Bigint *b;
#else
*x++ = y & 0xffff;
} while(borrow && x < xe);
#endif
- return STRTOG_Inexlo;
}
static int
goto ret;
}
switch(rd) {
- case 1:
+ case 1: /* round down (toward -Infinity) */
goto trunc;
- case 2:
+ case 2: /* round up (toward +Infinity) */
break;
default: /* round near */
k = bdif - 1;
CONST char *s, *s0, *s1;
double adj, adj0, rv, tol;
Long L;
- ULong y, z;
+ ULong *b, *be, y, z;
Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0;
+#ifdef USE_LOCALE
+#ifdef NO_LOCALE_CACHE
+ char *decimalpoint = localeconv()->decimal_point;
+#else
+ char *decimalpoint;
+ static char *decimalpoint_cache;
+ if (!(s0 = decimalpoint_cache)) {
+ s0 = localeconv()->decimal_point;
+ if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) {
+ strcpy(decimalpoint_cache, s0);
+ s0 = decimalpoint_cache;
+ }
+ }
+ decimalpoint = (char*)s0;
+#endif
+#endif
irv = STRTOG_Zero;
denorm = sign = nz0 = nz = 0;
z = 10*z + c - '0';
nd0 = nd;
#ifdef USE_LOCALE
- if (c == *localeconv()->decimal_point)
+ 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;
#endif
- {
decpt = 1;
- c = *++s;
if (!nd) {
for(; c == '0'; c = *++s)
nz++;
nz = 0;
}
}
- }
+ }/*}*/
dig_done:
e = 0;
if (c == 'e' || c == 'E') {
break;
if (dsign) {
rvb = increment(rvb);
- if ( (j = rvbits & kmask) !=0)
- j = ULbits - j;
- if (hi0bits(rvb->x[(rvb->wds - 1) >> kshift])
- != j)
+ j = kmask & (ULbits - (rvbits & kmask));
+ if (hi0bits(rvb->x[rvb->wds - 1]) != j)
rvbits++;
irv = STRTOG_Normal | STRTOG_Inexhi;
}
Bfree(bd0);
Bfree(delta);
if (rve > fpi->emax) {
+ switch(fpi->rounding & 3) {
+ case FPI_Round_near:
+ goto huge;
+ case FPI_Round_up:
+ if (!sign)
+ goto huge;
+ break;
+ case FPI_Round_down:
+ if (sign)
+ goto huge;
+ }
+ /* Round to largest representable magnitude */
+ Bfree(rvb);
+ rvb = 0;
+ irv = STRTOG_Normal | STRTOG_Inexlo;
+ *exp = fpi->emax;
+ b = bits;
+ be = b + ((fpi->nbits + 31) >> 5);
+ while(b < be)
+ *b++ = -1;
+ if ((j = fpi->nbits & 0x1f))
+ *--be >>= (32 - j);
+ goto ret;
huge:
rvb->wds = 0;
irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
if (sudden_underflow) {
rvb->wds = 0;
irv = STRTOG_Underflow | STRTOG_Inexlo;
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
}
else {
irv = (irv & ~STRTOG_Retmask) |
(rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero);
- if (irv & STRTOG_Inexact)
+ if (irv & STRTOG_Inexact) {
irv |= STRTOG_Underflow;
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
+ }
}
}
if (se)