]>
git.saurik.com Git - apple/libc.git/blob - gdtoa/FreeBSD/gdtoa-strtodg.c
1 /****************************************************************
3 The author of this software is David M. Gay.
5 Copyright (C) 1998-2001 by Lucent Technologies
8 Permission to use, copy, modify, and distribute this software and
9 its documentation for any purpose and without fee is hereby
10 granted, provided that the above copyright notice appear in all
11 copies and that both that the copyright notice and this
12 permission notice and warranty disclaimer appear in supporting
13 documentation, and that the name of Lucent or any of its entities
14 not be used in advertising or publicity pertaining to
15 distribution of the software without specific, written prior
18 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
27 ****************************************************************/
29 /* Please send bug reports to David M. Gay (dmg at acm dot org,
30 * with " at " changed at "@" and " dot " changed to "."). */
39 fivesbits
[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21,
40 24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
49 increment(b
) Bigint
*b
;
64 if (*x
< (ULong
)0xffffffffL
) {
81 if (b
->wds
>= b
->maxwds
) {
94 decrement(b
) Bigint
*b
;
118 borrow
= (y
& 0x10000) >> 16;
120 } while(borrow
&& x
< xe
);
126 all_on(b
, n
) Bigint
*b
; int n
;
128 all_on(Bigint
*b
, int n
)
134 xe
= x
+ (n
>> kshift
);
136 if ((*x
++ & ALL_ON
) != ALL_ON
)
139 return ((*x
| (ALL_ON
<< n
)) & ALL_ON
) == ALL_ON
;
145 set_ones(b
, n
) Bigint
*b
; int n
;
147 set_ones(Bigint
*b
, int n
)
153 k
= (n
+ ((1 << kshift
) - 1)) >> kshift
;
167 x
[-1] >>= ULbits
- n
;
174 (d
, fpi
, exp
, bits
, exact
, rd
, irv
)
175 double d
; FPI
*fpi
; Long
*exp
; ULong
*bits
; int exact
, rd
, *irv
;
177 (double d
, FPI
*fpi
, Long
*exp
, ULong
*bits
, int exact
, int rd
, int *irv
)
181 ULong carry
, inex
, lostbits
;
182 int bdif
, e
, j
, k
, k1
, nb
, rv
;
185 b
= d2b(d
, &e
, &bdif
);
186 bdif
-= nb
= fpi
->nbits
;
195 #ifndef IMPRECISE_INEXACT
208 case 1: /* round down (toward -Infinity) */
210 case 2: /* round up (toward +Infinity) */
212 default: /* round near */
223 if (b
->x
[k
>>kshift
] & ((ULong
)1 << (k
& kmask
)))
227 /* "break" cases: round up 1 bit, then truncate; bdif > 0 */
232 if ( (lostbits
= any_on(b
, bdif
)) !=0)
233 inex
= STRTOG_Inexlo
;
236 inex
= STRTOG_Inexhi
;
238 if ( (j
= nb
& kmask
) !=0)
240 if (hi0bits(b
->x
[b
->wds
- 1]) != j
) {
242 lostbits
= b
->x
[0] & 1;
249 b
= lshift(b
, -bdif
);
253 if (k
> nb
|| fpi
->sudden_underflow
) {
255 *irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
259 if (k1
> 0 && !lostbits
)
260 lostbits
= any_on(b
, k1
);
261 if (!lostbits
&& !exact
)
264 carry
= b
->x
[k1
>>kshift
] & (1 << (k1
& kmask
));
266 *irv
= STRTOG_Denormal
;
269 inex
= STRTOG_Inexhi
| STRTOG_Underflow
;
272 inex
= STRTOG_Inexlo
| STRTOG_Underflow
;
275 else if (e
> fpi
->emax
) {
277 *irv
= STRTOG_Infinite
| STRTOG_Overflow
| STRTOG_Inexhi
;
284 copybits(bits
, nb
, b
);
294 mantbits(d
) double d
;
301 L
= word1(d
) << 16 | word1(d
) >> 16;
304 if ( (L
= word1(d
)) !=0)
306 return P
- lo0bits(&L
);
308 L
= word0(d
) << 16 | word0(d
) >> 16 | Exp_msk11
;
310 L
= word0(d
) | Exp_msk1
;
312 return P
- 32 - lo0bits(&L
);
318 (s00
, se
, fpi
, exp
, bits
)
319 CONST
char *s00
; char **se
; FPI
*fpi
; Long
*exp
; ULong
*bits
;
321 (CONST
char *s00
, char **se
, FPI
*fpi
, Long
*exp
, ULong
*bits
)
324 int abe
, abits
, asub
;
325 int bb0
, bb2
, bb5
, bbe
, bd2
, bd5
, bbbits
, bs2
, c
, decpt
, denorm
;
326 int dsign
, e
, e1
, e2
, emin
, esign
, finished
, i
, inex
, irv
;
327 int j
, k
, nbits
, nd
, nd0
, nf
, nz
, nz0
, rd
, rvbits
, rve
, rve1
, sign
;
328 int sudden_underflow
;
329 CONST
char *s
, *s0
, *s1
;
330 double adj
, adj0
, rv
, tol
;
333 Bigint
*ab
, *bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
, *rvb
, *rvb0
;
335 #ifdef NO_LOCALE_CACHE
336 char *decimalpoint
= localeconv()->decimal_point
;
339 static char *decimalpoint_cache
;
340 if (!(s0
= decimalpoint_cache
)) {
341 s0
= localeconv()->decimal_point
;
342 if ((decimalpoint_cache
= (char*)malloc(strlen(s0
) + 1))) {
343 strcpy(decimalpoint_cache
, s0
);
344 s0
= decimalpoint_cache
;
347 decimalpoint
= (char*)s0
;
352 denorm
= sign
= nz0
= nz
= 0;
356 for(s
= s00
;;s
++) switch(*s
) {
366 irv
= STRTOG_NoNumber
;
385 irv
= gethex(&s
, fpi
, exp
, &rvb
, sign
);
386 if (irv
== STRTOG_NoNumber
) {
398 sudden_underflow
= fpi
->sudden_underflow
;
401 for(decpt
= nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
408 if (c
== *decimalpoint
) {
409 for(i
= 1; decimalpoint
[i
]; ++i
)
410 if (s
[i
] != decimalpoint
[i
])
420 for(; c
== '0'; c
= *++s
)
422 if (c
> '0' && c
<= '9') {
430 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
435 for(i
= 1; i
< nz
; i
++)
438 else if (nd
<= DBL_DIG
+ 1)
442 else if (nd
<= DBL_DIG
+ 1)
450 if (c
== 'e' || c
== 'E') {
451 if (!nd
&& !nz
&& !nz0
) {
452 irv
= STRTOG_NoNumber
;
464 if (c
>= '0' && c
<= '9') {
467 if (c
> '0' && c
<= '9') {
470 while((c
= *++s
) >= '0' && c
<= '9')
472 if (s
- s1
> 8 || L
> 19999)
473 /* Avoid confusion from exponents
474 * so large that e might overflow.
476 e
= 19999; /* safe for 16 bit ints */
491 /* Check for Nan and Infinity */
496 if (match(&s
,"nf")) {
498 if (!match(&s
,"inity"))
500 irv
= STRTOG_Infinite
;
506 if (match(&s
, "an")) {
508 *exp
= fpi
->emax
+ 1;
511 irv
= hexnan(&s
, fpi
, bits
);
516 #endif /* INFNAN_CHECK */
517 irv
= STRTOG_NoNumber
;
526 switch(fpi
->rounding
& 3) {
537 /* Now we have nd0 digits, starting at s0, followed by a
538 * decimal point, followed by nd-nd0 digits. The number we're
539 * after is the integer represented by those digits times
544 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
547 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
549 if (nbits
<= P
&& nd
<= DBL_DIG
) {
551 if (rvOK(dval(rv
), fpi
, exp
, bits
, 1, rd
, &irv
))
559 i
= fivesbits
[e
] + mantbits(dval(rv
)) <= P
;
560 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
561 if (rvOK(dval(rv
), fpi
, exp
, bits
, i
, rd
, &irv
))
568 if (e
<= Ten_pmax
+ i
) {
569 /* A fancier test would sometimes let us do
570 * this for larger i values.
576 /* VAX exponent range is so narrow we must
577 * worry about overflow here...
580 dval(adj
) = dval(rv
);
581 word0(adj
) -= P
*Exp_msk1
;
582 /* adj = */ rounded_product(dval(adj
), tens
[e2
]);
583 if ((word0(adj
) & Exp_mask
)
584 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
586 word0(adj
) += P
*Exp_msk1
;
587 dval(rv
) = dval(adj
);
589 /* rv = */ rounded_product(dval(rv
), tens
[e2
]);
591 if (rvOK(dval(rv
), fpi
, exp
, bits
, 0, rd
, &irv
))
596 #ifndef Inaccurate_Divide
597 else if (e
>= -Ten_pmax
) {
598 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
599 if (rvOK(dval(rv
), fpi
, exp
, bits
, 0, rd
, &irv
))
608 /* Get starting approximation = rv * 10**e1 */
612 if ( (i
= e1
& 15) !=0)
616 while(e1
>= (1 << n_bigtens
-1)) {
617 e2
+= ((word0(rv
) & Exp_mask
)
618 >> Exp_shift1
) - Bias
;
619 word0(rv
) &= ~Exp_mask
;
620 word0(rv
) |= Bias
<< Exp_shift1
;
621 dval(rv
) *= bigtens
[n_bigtens
-1];
622 e1
-= 1 << n_bigtens
-1;
624 e2
+= ((word0(rv
) & Exp_mask
) >> Exp_shift1
) - Bias
;
625 word0(rv
) &= ~Exp_mask
;
626 word0(rv
) |= Bias
<< Exp_shift1
;
627 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
629 dval(rv
) *= bigtens
[j
];
634 if ( (i
= e1
& 15) !=0)
638 while(e1
>= (1 << n_bigtens
-1)) {
639 e2
+= ((word0(rv
) & Exp_mask
)
640 >> Exp_shift1
) - Bias
;
641 word0(rv
) &= ~Exp_mask
;
642 word0(rv
) |= Bias
<< Exp_shift1
;
643 dval(rv
) *= tinytens
[n_bigtens
-1];
644 e1
-= 1 << n_bigtens
-1;
646 e2
+= ((word0(rv
) & Exp_mask
) >> Exp_shift1
) - Bias
;
647 word0(rv
) &= ~Exp_mask
;
648 word0(rv
) |= Bias
<< Exp_shift1
;
649 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
651 dval(rv
) *= tinytens
[j
];
655 /* e2 is a correction to the (base 2) exponent of the return
656 * value, reflecting adjustments above to avoid overflow in the
657 * native arithmetic. For native IBM (base 16) arithmetic, we
658 * must multiply e2 by 4 to change from base 16 to 2.
662 rvb
= d2b(dval(rv
), &rve
, &rvbits
); /* rv = rvb * 2^rve */
664 if ((j
= rvbits
- nbits
) > 0) {
669 bb0
= 0; /* trailing zero bits in rvb */
670 e2
= rve
+ rvbits
- nbits
;
671 if (e2
> fpi
->emax
+ 1)
673 rve1
= rve
+ rvbits
- nbits
;
674 if (e2
< (emin
= fpi
->emin
)) {
678 rvb
= lshift(rvb
, j
);
689 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
692 rvb
->x
[0] = rvb
->wds
= rvbits
= 1;
698 if (sudden_underflow
&& e2
+ 1 < emin
)
702 /* Now the hard part -- adjusting rv to the correct value.*/
704 /* Put digits into bd: true value = bd * 10^e */
706 bd0
= s2b(s0
, nd0
, nd
, y
);
713 bbbits
= rvbits
- bb0
;
730 j
= nbits
+ 1 - bbbits
;
731 i
= bbe
+ bbbits
- nbits
;
732 if (i
< emin
) /* denormal */
736 i
= bb2
< bd2
? bb2
: bd2
;
745 bs
= pow5mult(bs
, bb5
);
752 bb
= lshift(bb
, bb2
);
756 bd
= pow5mult(bd
, bd5
);
758 bd
= lshift(bd
, bd2
);
760 bs
= lshift(bs
, bs2
);
762 inex
= STRTOG_Inexhi
;
763 delta
= diff(bb
, bd
);
764 if (delta
->wds
<= 1 && !delta
->x
[0])
767 delta
->sign
= finished
= 0;
772 if ( (finished
= dsign
^ (rd
&1)) !=0) {
774 irv
|= STRTOG_Inexhi
;
777 irv
|= STRTOG_Inexlo
;
780 for(i
= 0, j
= nbits
; j
>= ULbits
;
782 if (rvb
->x
[i
] & ALL_ON
)
785 if (j
> 1 && lo0bits(rvb
->x
+ i
) < j
- 1)
788 rvb
= set_ones(rvb
, rvbits
= nbits
);
791 irv
|= dsign
? STRTOG_Inexlo
: STRTOG_Inexhi
;
795 /* Error is less than half an ulp -- check for
796 * special case of mantissa a power of two.
799 ? STRTOG_Normal
| STRTOG_Inexlo
800 : STRTOG_Normal
| STRTOG_Inexhi
;
801 if (dsign
|| bbbits
> 1 || denorm
|| rve1
== emin
)
803 delta
= lshift(delta
,1);
804 if (cmp(delta
, bs
) > 0) {
805 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
811 /* exactly half-way between */
813 if (denorm
&& all_on(rvb
, rvbits
)) {
814 /*boundary case -- increment exponent*/
817 rve
= emin
+ nbits
- (rvbits
= 1);
818 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
822 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
824 else if (bbbits
== 1) {
827 /* boundary case -- decrement exponent */
829 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
830 if (rvb
->wds
== 1 && rvb
->x
[0] == 1)
831 sudden_underflow
= 1;
835 rvb
= set_ones(rvb
, rvbits
= nbits
);
839 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
840 if (bbbits
< nbits
&& !denorm
|| !(rvb
->x
[0] & 1))
843 rvb
= increment(rvb
);
844 j
= kmask
& (ULbits
- (rvbits
& kmask
));
845 if (hi0bits(rvb
->x
[rvb
->wds
- 1]) != j
)
847 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
853 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
857 if ((dval(adj
) = ratio(delta
, bs
)) <= 2.) {
859 inex
= STRTOG_Inexlo
;
862 inex
= STRTOG_Inexhi
;
864 else if (denorm
&& bbbits
<= 1) {
868 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
871 adj0
= dval(adj
) = 1.;
874 adj0
= dval(adj
) *= 0.5;
877 inex
= STRTOG_Inexlo
;
879 if (dval(adj
) < 2147483647.) {
888 if (asub
&& adj0
> 0.)
892 if (!asub
&& adj0
> 0.) {
895 inex
= STRTOG_Inexact
- inex
;
903 /* adj *= ulp(dval(rv)); */
904 /* if (asub) rv -= adj; else rv += adj; */
906 if (!denorm
&& rvbits
< nbits
) {
907 rvb
= lshift(rvb
, j
= nbits
- rvbits
);
911 ab
= d2b(dval(adj
), &abe
, &abits
);
915 ab
= lshift(ab
, abe
);
919 j
= hi0bits(rvb
->x
[rvb
->wds
-1]);
924 else if (rvb
->wds
<= k
925 || hi0bits( rvb
->x
[k
]) >
926 hi0bits(rvb0
->x
[k
])) {
927 /* unlikely; can only have lost 1 high bit */
933 rvb
= lshift(rvb
, 1);
944 || hi0bits(rvb
->x
[k
]) < hi0bits(rvb0
->x
[k
])) {
946 if (++rvbits
== nbits
)
964 /* Can we stop now? */
965 tol
= dval(adj
) * 5e-16; /* > max rel error */
966 dval(adj
) = adj0
- .5;
967 if (dval(adj
) < -tol
) {
973 else if (dval(adj
) > tol
&& adj0
< 1. - tol
) {
978 bb0
= denorm
? 0 : trailz(rvb
);
984 if (!denorm
&& (j
= nbits
- rvbits
)) {
986 rvb
= lshift(rvb
, j
);
997 if (rve
> fpi
->emax
) {
998 switch(fpi
->rounding
& 3) {
1005 case FPI_Round_down
:
1009 /* Round to largest representable magnitude */
1012 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
1015 be
= b
+ ((fpi
->nbits
+ 31) >> 5);
1018 if ((j
= fpi
->nbits
& 0x1f))
1023 irv
= STRTOG_Infinite
| STRTOG_Overflow
| STRTOG_Inexhi
;
1028 *exp
= fpi
->emax
+ 1;
1032 if (sudden_underflow
) {
1034 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
1040 irv
= (irv
& ~STRTOG_Retmask
) |
1041 (rvb
->wds
> 0 ? STRTOG_Denormal
: STRTOG_Zero
);
1042 if (irv
& STRTOG_Inexact
) {
1043 irv
|= STRTOG_Underflow
;
1055 copybits(bits
, nbits
, rvb
);