]>
git.saurik.com Git - apple/libc.git/blob - gdtoa/FreeBSD/gdtoa-strtodg.c
bf30e33ecf57f970326b8a387091dec37a952f8a
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
41 fivesbits
[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21,
42 24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
51 increment(b
) Bigint
*b
;
66 if (*x
< (ULong
)0xffffffffL
) {
83 if (b
->wds
>= b
->maxwds
) {
96 decrement(b
) Bigint
*b
;
120 borrow
= (y
& 0x10000) >> 16;
122 } while(borrow
&& x
< xe
);
124 return STRTOG_Inexlo
;
129 all_on(b
, n
) Bigint
*b
; int n
;
131 all_on(Bigint
*b
, int n
)
137 xe
= x
+ (n
>> kshift
);
139 if ((*x
++ & ALL_ON
) != ALL_ON
)
142 return ((*x
| (ALL_ON
<< n
)) & ALL_ON
) == ALL_ON
;
148 set_ones(b
, n
) Bigint
*b
; int n
;
150 set_ones(Bigint
*b
, int n
)
156 k
= (n
+ ((1 << kshift
) - 1)) >> kshift
;
170 x
[-1] >>= ULbits
- n
;
177 (d
, fpi
, exp
, bits
, exact
, rd
, irv
)
178 double d
; FPI
*fpi
; Long
*exp
; ULong
*bits
; int exact
, rd
, *irv
;
180 (double d
, FPI
*fpi
, Long
*exp
, ULong
*bits
, int exact
, int rd
, int *irv
)
184 ULong carry
, inex
, lostbits
;
185 int bdif
, e
, j
, k
, k1
, nb
, rv
;
188 b
= d2b(d
, &e
, &bdif
);
189 bdif
-= nb
= fpi
->nbits
;
198 #ifndef IMPRECISE_INEXACT
215 default: /* round near */
226 if (b
->x
[k
>>kshift
] & ((ULong
)1 << (k
& kmask
)))
230 /* "break" cases: round up 1 bit, then truncate; bdif > 0 */
235 if ( (lostbits
= any_on(b
, bdif
)) !=0)
236 inex
= STRTOG_Inexlo
;
239 inex
= STRTOG_Inexhi
;
241 if ( (j
= nb
& kmask
) !=0)
243 if (hi0bits(b
->x
[b
->wds
- 1]) != j
) {
245 lostbits
= b
->x
[0] & 1;
252 b
= lshift(b
, -bdif
);
256 if (k
> nb
|| fpi
->sudden_underflow
) {
258 *irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
262 if (k1
> 0 && !lostbits
)
263 lostbits
= any_on(b
, k1
);
264 if (!lostbits
&& !exact
)
267 carry
= b
->x
[k1
>>kshift
] & (1 << (k1
& kmask
));
269 *irv
= STRTOG_Denormal
;
272 inex
= STRTOG_Inexhi
| STRTOG_Underflow
;
275 inex
= STRTOG_Inexlo
| STRTOG_Underflow
;
278 else if (e
> fpi
->emax
) {
280 *irv
= STRTOG_Infinite
| STRTOG_Overflow
| STRTOG_Inexhi
;
287 copybits(bits
, nb
, b
);
297 mantbits(d
) double d
;
304 L
= word1(d
) << 16 | word1(d
) >> 16;
307 if ( (L
= word1(d
)) !=0)
309 return P
- lo0bits(&L
);
311 L
= word0(d
) << 16 | word0(d
) >> 16 | Exp_msk11
;
313 L
= word0(d
) | Exp_msk1
;
315 return P
- 32 - lo0bits(&L
);
321 (s00
, se
, fpi
, exp
, bits
)
322 CONST
char *s00
; char **se
; FPI
*fpi
; Long
*exp
; ULong
*bits
;
324 (CONST
char *s00
, char **se
, FPI
*fpi
, Long
*exp
, ULong
*bits
)
327 int abe
, abits
, asub
;
328 int bb0
, bb2
, bb5
, bbe
, bd2
, bd5
, bbbits
, bs2
;
329 int c
, denorm
, dsign
, e
, e1
, e2
, emin
, esign
, finished
, i
, inex
, irv
;
330 int j
, k
, nbits
, nd
, nd0
, nf
, nz
, nz0
, rd
, rvbits
, rve
, rve1
, sign
;
331 int sudden_underflow
;
332 CONST
char *s
, *s0
, *s1
;
333 double adj
, adj0
, rv
, tol
;
336 Bigint
*ab
, *bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
, *rvb
, *rvb0
;
339 denorm
= sign
= nz0
= nz
= 0;
343 for(s
= s00
;;s
++) switch(*s
) {
353 irv
= STRTOG_NoNumber
;
372 irv
= gethex(&s
, fpi
, exp
, &rvb
, sign
);
373 if (irv
== STRTOG_NoNumber
) {
385 sudden_underflow
= fpi
->sudden_underflow
;
388 for(nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
395 if (c
== *localeconv()->decimal_point
)
402 for(; c
== '0'; c
= *++s
)
404 if (c
> '0' && c
<= '9') {
412 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
417 for(i
= 1; i
< nz
; i
++)
420 else if (nd
<= DBL_DIG
+ 1)
424 else if (nd
<= DBL_DIG
+ 1)
432 if (c
== 'e' || c
== 'E') {
433 if (!nd
&& !nz
&& !nz0
) {
434 irv
= STRTOG_NoNumber
;
446 if (c
>= '0' && c
<= '9') {
449 if (c
> '0' && c
<= '9') {
452 while((c
= *++s
) >= '0' && c
<= '9')
454 if (s
- s1
> 8 || L
> 19999)
455 /* Avoid confusion from exponents
456 * so large that e might overflow.
458 e
= 19999; /* safe for 16 bit ints */
473 /* Check for Nan and Infinity */
477 if (match(&s
,"nf")) {
479 if (!match(&s
,"inity"))
481 irv
= STRTOG_Infinite
;
487 if (match(&s
, "an")) {
489 *exp
= fpi
->emax
+ 1;
492 irv
= hexnan(&s
, fpi
, bits
);
497 #endif /* INFNAN_CHECK */
498 irv
= STRTOG_NoNumber
;
507 switch(fpi
->rounding
& 3) {
518 /* Now we have nd0 digits, starting at s0, followed by a
519 * decimal point, followed by nd-nd0 digits. The number we're
520 * after is the integer represented by those digits times
525 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
528 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
530 if (nbits
<= P
&& nd
<= DBL_DIG
) {
532 if (rvOK(dval(rv
), fpi
, exp
, bits
, 1, rd
, &irv
))
540 i
= fivesbits
[e
] + mantbits(dval(rv
)) <= P
;
541 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
542 if (rvOK(dval(rv
), fpi
, exp
, bits
, i
, rd
, &irv
))
549 if (e
<= Ten_pmax
+ i
) {
550 /* A fancier test would sometimes let us do
551 * this for larger i values.
557 /* VAX exponent range is so narrow we must
558 * worry about overflow here...
561 dval(adj
) = dval(rv
);
562 word0(adj
) -= P
*Exp_msk1
;
563 /* adj = */ rounded_product(dval(adj
), tens
[e2
]);
564 if ((word0(adj
) & Exp_mask
)
565 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
567 word0(adj
) += P
*Exp_msk1
;
568 dval(rv
) = dval(adj
);
570 /* rv = */ rounded_product(dval(rv
), tens
[e2
]);
572 if (rvOK(dval(rv
), fpi
, exp
, bits
, 0, rd
, &irv
))
577 #ifndef Inaccurate_Divide
578 else if (e
>= -Ten_pmax
) {
579 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
580 if (rvOK(dval(rv
), fpi
, exp
, bits
, 0, rd
, &irv
))
589 /* Get starting approximation = rv * 10**e1 */
593 if ( (i
= e1
& 15) !=0)
597 while(e1
>= (1 << n_bigtens
-1)) {
598 e2
+= ((word0(rv
) & Exp_mask
)
599 >> Exp_shift1
) - Bias
;
600 word0(rv
) &= ~Exp_mask
;
601 word0(rv
) |= Bias
<< Exp_shift1
;
602 dval(rv
) *= bigtens
[n_bigtens
-1];
603 e1
-= 1 << n_bigtens
-1;
605 e2
+= ((word0(rv
) & Exp_mask
) >> Exp_shift1
) - Bias
;
606 word0(rv
) &= ~Exp_mask
;
607 word0(rv
) |= Bias
<< Exp_shift1
;
608 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
610 dval(rv
) *= bigtens
[j
];
615 if ( (i
= e1
& 15) !=0)
619 while(e1
>= (1 << n_bigtens
-1)) {
620 e2
+= ((word0(rv
) & Exp_mask
)
621 >> Exp_shift1
) - Bias
;
622 word0(rv
) &= ~Exp_mask
;
623 word0(rv
) |= Bias
<< Exp_shift1
;
624 dval(rv
) *= tinytens
[n_bigtens
-1];
625 e1
-= 1 << n_bigtens
-1;
627 e2
+= ((word0(rv
) & Exp_mask
) >> Exp_shift1
) - Bias
;
628 word0(rv
) &= ~Exp_mask
;
629 word0(rv
) |= Bias
<< Exp_shift1
;
630 for(j
= 0; e1
> 0; j
++, e1
>>= 1)
632 dval(rv
) *= tinytens
[j
];
636 rvb
= d2b(dval(rv
), &rve
, &rvbits
); /* rv = rvb * 2^rve */
638 if ((j
= rvbits
- nbits
) > 0) {
643 bb0
= 0; /* trailing zero bits in rvb */
644 e2
= rve
+ rvbits
- nbits
;
645 if (e2
> fpi
->emax
) {
647 irv
= STRTOG_Infinite
| STRTOG_Overflow
| STRTOG_Inexhi
;
652 *exp
= fpi
->emax
+ 1;
655 rve1
= rve
+ rvbits
- nbits
;
656 if (e2
< (emin
= fpi
->emin
)) {
660 rvb
= lshift(rvb
, j
);
671 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
674 rvb
->x
[0] = rvb
->wds
= rvbits
= 1;
680 if (sudden_underflow
&& e2
+ 1 < emin
)
684 /* Now the hard part -- adjusting rv to the correct value.*/
686 /* Put digits into bd: true value = bd * 10^e */
688 bd0
= s2b(s0
, nd0
, nd
, y
);
695 bbbits
= rvbits
- bb0
;
712 j
= nbits
+ 1 - bbbits
;
713 i
= bbe
+ bbbits
- nbits
;
714 if (i
< emin
) /* denormal */
718 i
= bb2
< bd2
? bb2
: bd2
;
727 bs
= pow5mult(bs
, bb5
);
734 bb
= lshift(bb
, bb2
);
738 bd
= pow5mult(bd
, bd5
);
740 bd
= lshift(bd
, bd2
);
742 bs
= lshift(bs
, bs2
);
744 inex
= STRTOG_Inexhi
;
745 delta
= diff(bb
, bd
);
746 if (delta
->wds
<= 1 && !delta
->x
[0])
749 delta
->sign
= finished
= 0;
754 if ( (finished
= dsign
^ (rd
&1)) !=0) {
756 irv
|= STRTOG_Inexhi
;
759 irv
|= STRTOG_Inexlo
;
762 for(i
= 0, j
= nbits
; j
>= ULbits
;
764 if (rvb
->x
[i
] & ALL_ON
)
767 if (j
> 1 && lo0bits(rvb
->x
+ i
) < j
- 1)
770 rvb
= set_ones(rvb
, rvbits
= nbits
);
773 irv
|= dsign
? STRTOG_Inexlo
: STRTOG_Inexhi
;
777 /* Error is less than half an ulp -- check for
778 * special case of mantissa a power of two.
781 ? STRTOG_Normal
| STRTOG_Inexlo
782 : STRTOG_Normal
| STRTOG_Inexhi
;
783 if (dsign
|| bbbits
> 1 || denorm
|| rve1
== emin
)
785 delta
= lshift(delta
,1);
786 if (cmp(delta
, bs
) > 0) {
787 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
793 /* exactly half-way between */
795 if (denorm
&& all_on(rvb
, rvbits
)) {
796 /*boundary case -- increment exponent*/
799 rve
= emin
+ nbits
- (rvbits
= 1);
800 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
804 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
806 else if (bbbits
== 1) {
809 /* boundary case -- decrement exponent */
811 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
812 if (rvb
->wds
== 1 && rvb
->x
[0] == 1)
813 sudden_underflow
= 1;
817 rvb
= set_ones(rvb
, rvbits
= nbits
);
821 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
822 if (bbbits
< nbits
&& !denorm
|| !(rvb
->x
[0] & 1))
825 rvb
= increment(rvb
);
826 if ( (j
= rvbits
>> kshift
) !=0)
828 if (hi0bits(rvb
->x
[(rvb
->wds
- 1) >> kshift
])
831 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
837 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
841 if ((dval(adj
) = ratio(delta
, bs
)) <= 2.) {
843 inex
= STRTOG_Inexlo
;
846 inex
= STRTOG_Inexhi
;
848 else if (denorm
&& bbbits
<= 1) {
852 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
855 adj0
= dval(adj
) = 1.;
858 adj0
= dval(adj
) *= 0.5;
861 inex
= STRTOG_Inexlo
;
863 if (dval(adj
) < 2147483647.) {
872 if (asub
&& adj0
> 0.)
876 if (!asub
&& adj0
> 0.) {
879 inex
= STRTOG_Inexact
- inex
;
887 /* adj *= ulp(dval(rv)); */
888 /* if (asub) rv -= adj; else rv += adj; */
890 if (!denorm
&& rvbits
< nbits
) {
891 rvb
= lshift(rvb
, j
= nbits
- rvbits
);
895 ab
= d2b(dval(adj
), &abe
, &abits
);
899 ab
= lshift(ab
, abe
);
903 j
= hi0bits(rvb
->x
[rvb
->wds
-1]);
908 else if (rvb
->wds
<= k
909 || hi0bits( rvb
->x
[k
]) >
910 hi0bits(rvb0
->x
[k
])) {
911 /* unlikely; can only have lost 1 high bit */
917 rvb
= lshift(rvb
, 1);
928 || hi0bits(rvb
->x
[k
]) < hi0bits(rvb0
->x
[k
])) {
930 if (++rvbits
== nbits
)
948 /* Can we stop now? */
949 tol
= dval(adj
) * 5e-16; /* > max rel error */
950 dval(adj
) = adj0
- .5;
951 if (dval(adj
) < -tol
) {
957 else if (dval(adj
) > tol
&& adj0
< 1. - tol
) {
962 bb0
= denorm
? 0 : trailz(rvb
);
968 if (!denorm
&& rvbits
< nbits
) {
970 rvb
= lshift(rvb
, j
);
981 if (sudden_underflow
) {
983 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
986 irv
= (irv
& ~STRTOG_Retmask
) |
987 (rvb
->wds
> 0 ? STRTOG_Denormal
: STRTOG_Zero
);
988 if (irv
& STRTOG_Inexact
)
989 irv
|= STRTOG_Underflow
;
997 copybits(bits
, nbits
, rvb
);