]>
git.proxmox.com Git - mirror_edk2.git/blob - StdLib/LibC/gdtoa/strtodg.c
3 Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials are licensed and made available under
5 the terms and conditions of the BSD License that accompanies this distribution.
6 The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *****************************************************************
14 The author of this software is David M. Gay.
16 Copyright (C) 1998-2001 by Lucent Technologies
19 Permission to use, copy, modify, and distribute this software and
20 its documentation for any purpose and without fee is hereby
21 granted, provided that the above copyright notice appear in all
22 copies and that both that the copyright notice and this
23 permission notice and warranty disclaimer appear in supporting
24 documentation, and that the name of Lucent or any of its entities
25 not be used in advertising or publicity pertaining to
26 distribution of the software without specific, written prior
29 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
30 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
31 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
32 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
33 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
34 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
35 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
39 Please send bug reports to David M. Gay (dmg at acm dot org,
40 with " at " changed at "@" and " dot " changed to ".").
42 *****************************************************************
44 NetBSD: strtodg.c,v 1.5.14.1 2008/04/08 21:10:55 jdc Exp
46 #include <LibConfig.h>
55 // Disable warnings about assignment within conditional expressions.
56 #pragma warning ( disable : 4706 )
60 fivesbits
[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21,
61 24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
70 increment(b
) Bigint
*b
;
85 if (*x
< (ULong
)0xffffffffL
) {
102 if (b
->wds
>= b
->maxwds
) {
117 decrement(b
) Bigint
*b
;
141 borrow
= (y
& 0x10000) >> 16;
143 } while(borrow
&& x
< xe
);
145 return STRTOG_Inexlo
;
150 all_on(b
, n
) CONST Bigint
*b
; int n
;
152 all_on(CONST Bigint
*b
, int n
)
158 xe
= x
+ ((unsigned int)n
>> kshift
);
160 if ((*x
++ & ALL_ON
) != ALL_ON
)
163 return ((*x
| (ALL_ON
<< n
)) & ALL_ON
) == ALL_ON
;
169 set_ones(b
, n
) Bigint
*b
; int n
;
171 set_ones(Bigint
*b
, int n
)
177 k
= (unsigned int)(n
+ ((1 << kshift
) - 1)) >> kshift
;
184 k
= (unsigned int)n
>> kshift
;
193 x
[-1] >>= ULbits
- n
;
200 (d
, fpi
, expt
, bits
, exact
, rd
, irv
)
201 double d
; CONST FPI
*fpi
; Long
*expt
; ULong
*bits
; int exact
, rd
, *irv
;
203 (double d
, CONST FPI
*fpi
, Long
*expt
, ULong
*bits
, int exact
, int rd
, int *irv
)
207 ULong carry
, inex
, lostbits
;
208 int bdif
, e
, j
, k
, k1
, nb
, rv
;
211 b
= d2b(d
, &e
, &bdif
);
212 bdif
-= nb
= fpi
->nbits
;
221 #ifndef IMPRECISE_INEXACT
238 default: /* round near */
247 if (b
->x
[(unsigned int)k
>>kshift
] & ((ULong
)1 << (k
& kmask
)))
251 /* "break" cases: round up 1 bit, then truncate; bdif > 0 */
256 if ( (lostbits
= any_on(b
, bdif
)) !=0)
257 inex
= STRTOG_Inexlo
;
260 inex
= STRTOG_Inexhi
;
262 if ( (j
= nb
& kmask
) !=0)
264 if (hi0bits(b
->x
[b
->wds
- 1]) != j
) {
266 lostbits
= b
->x
[0] & 1;
273 b
= lshift(b
, -bdif
);
277 if (k
> nb
|| fpi
->sudden_underflow
) {
279 *irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
283 if (k1
> 0 && !lostbits
)
284 lostbits
= any_on(b
, k1
);
285 if (!lostbits
&& !exact
)
288 carry
= b
->x
[(unsigned int)k1
>>kshift
] &
289 (ULong
)(1 << ((unsigned int)k1
& kmask
));
291 *irv
= STRTOG_Denormal
;
294 inex
= STRTOG_Inexhi
| STRTOG_Underflow
;
297 inex
= STRTOG_Inexlo
| STRTOG_Underflow
;
300 else if (e
> fpi
->emax
) {
302 *irv
= STRTOG_Infinite
| STRTOG_Overflow
| STRTOG_Inexhi
;
309 copybits(bits
, nb
, b
);
320 mantbits(d
) double d
;
327 L
= word1(d
) << 16 | word1(d
) >> 16;
330 if ( (L
= word1(d
)) !=0)
332 return P
- lo0bits(&L
);
334 L
= word0(d
) << 16 | word0(d
) >> 16 | Exp_msk11
;
336 L
= word0(d
) | Exp_msk1
;
338 return P
- 32 - lo0bits(&L
);
345 (s00
, se
, fpi
, expt
, bits
)
346 CONST
char *s00
; char **se
; CONST FPI
*fpi
; Long
*expt
; ULong
*bits
;
348 (CONST
char *s00
, char **se
, CONST FPI
*fpi
, Long
*expt
, ULong
*bits
)
351 int abe
, abits
, asub
;
352 int bb0
, bb2
, bb5
, bbe
, bd2
, bd5
, bbbits
, bs2
, c
, decpt
, denorm
;
353 int dsign
, e
, e1
, e2
, emin
, esign
, finished
, i
, inex
, irv
;
354 int j
, k
, nbits
, nd
, nd0
, nf
, nz
, nz0
, rd
, rvbits
, rve
, rve1
, sign
;
355 int sudden_underflow
= 0; /* pacify gcc */
356 CONST
char *s
, *s0
, *s1
;
357 double adj
, adj0
, rv
, tol
;
360 Bigint
*ab
, *bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
, *rvb
, *rvb0
;
362 e2
= 0; /* XXX gcc */
365 denorm
= sign
= nz0
= nz
= 0;
369 for(s
= s00
;;s
++) switch(*s
) {
379 irv
= STRTOG_NoNumber
;
398 irv
= gethex(&s
, fpi
, expt
, &rvb
, sign
);
399 if (irv
== STRTOG_NoNumber
) {
411 sudden_underflow
= fpi
->sudden_underflow
;
414 for(decpt
= nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
421 if (c
== *localeconv()->decimal_point
)
429 for(; c
== '0'; c
= *++s
)
431 if (c
> '0' && c
<= '9') {
439 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
444 for(i
= 1; i
< nz
; i
++)
447 else if (nd
<= DBL_DIG
+ 1)
451 else if (nd
<= DBL_DIG
+ 1)
459 if (c
== 'e' || c
== 'E') {
460 if (!nd
&& !nz
&& !nz0
) {
461 irv
= STRTOG_NoNumber
;
474 if (c
>= '0' && c
<= '9') {
477 if (c
> '0' && c
<= '9') {
480 while((c
= *++s
) >= '0' && c
<= '9')
482 if (s
- s1
> 8 || L
> 19999)
483 /* Avoid confusion from exponents
484 * so large that e might overflow.
486 e
= 19999; /* safe for 16 bit ints */
501 /* Check for Nan and Infinity */
506 if (match(&s
,"nf")) {
508 if (!match(&s
,"inity"))
510 irv
= STRTOG_Infinite
;
516 if (match(&s
, "an")) {
518 *expt
= fpi
->emax
+ 1;
521 irv
= hexnan(&s
, fpi
, bits
);
526 #endif /* INFNAN_CHECK */
527 irv
= STRTOG_NoNumber
;
536 switch(fpi
->rounding
& 3) {
547 /* Now we have nd0 digits, starting at s0, followed by a
548 * decimal point, followed by nd-nd0 digits. The number we're
549 * after is the integer represented by those digits times
554 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
555 dval(rv
) = (double)y
;
557 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
559 if (nbits
<= P
&& nd
<= DBL_DIG
) {
561 if (rvOK(dval(rv
), fpi
, expt
, bits
, 1, rd
, &irv
))
569 i
= fivesbits
[e
] + mantbits(dval(rv
)) <= P
;
570 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
571 if (rvOK(dval(rv
), fpi
, expt
, bits
, i
, rd
, &irv
))
578 if (e
<= Ten_pmax
+ i
) {
579 /* A fancier test would sometimes let us do
580 * this for larger i values.
586 /* VAX exponent range is so narrow we must
587 * worry about overflow here...
590 dval(adj
) = dval(rv
);
591 word0(adj
) -= P
*Exp_msk1
;
592 /* adj = */ rounded_product(dval(adj
), tens
[e2
]);
593 if ((word0(adj
) & Exp_mask
)
594 > Exp_msk1
*(DBL_MAX_EXP
+Bias
-1-P
))
596 word0(adj
) += P
*Exp_msk1
;
597 dval(rv
) = dval(adj
);
599 /* rv = */ rounded_product(dval(rv
), tens
[e2
]);
601 if (rvOK(dval(rv
), fpi
, expt
, bits
, 0, rd
, &irv
))
606 #ifndef Inaccurate_Divide
607 else if (e
>= -Ten_pmax
) {
608 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
609 if (rvOK(dval(rv
), fpi
, expt
, bits
, 0, rd
, &irv
))
618 /* Get starting approximation = rv * 10**e1 */
622 if ( (i
= e1
& 15) !=0)
625 e1
= (unsigned int)e1
>> 4;
626 while(e1
>= (1 << (n_bigtens
-1))) {
627 e2
+= (unsigned int)((word0(rv
) & Exp_mask
)
628 >> Exp_shift1
) - Bias
;
629 word0(rv
) &= ~Exp_mask
;
630 word0(rv
) |= Bias
<< Exp_shift1
;
631 dval(rv
) *= bigtens
[n_bigtens
-1];
632 e1
-= 1 << (n_bigtens
-1);
634 e2
+= (unsigned int)((word0(rv
) & Exp_mask
) >> Exp_shift1
) - Bias
;
635 word0(rv
) &= ~Exp_mask
;
636 word0(rv
) |= Bias
<< Exp_shift1
;
637 for(j
= 0; e1
> 0; j
++, e1
= (unsigned int)e1
>> 1)
639 dval(rv
) *= bigtens
[j
];
644 if ( (i
= e1
& 15) !=0)
647 e1
= (unsigned int)e1
>> 4;
648 while(e1
>= (1 << (n_bigtens
-1))) {
649 e2
+= (unsigned int)((word0(rv
) & Exp_mask
)
650 >> Exp_shift1
) - Bias
;
651 word0(rv
) &= ~Exp_mask
;
652 word0(rv
) |= Bias
<< Exp_shift1
;
653 dval(rv
) *= tinytens
[n_bigtens
-1];
654 e1
-= 1 << (n_bigtens
-1);
656 e2
+= (unsigned int)((word0(rv
) & Exp_mask
) >> Exp_shift1
) - Bias
;
657 word0(rv
) &= ~Exp_mask
;
658 word0(rv
) |= Bias
<< Exp_shift1
;
659 for(j
= 0; e1
> 0; j
++, e1
= (unsigned int)e1
>> 1)
661 dval(rv
) *= tinytens
[j
];
665 /* e2 is a correction to the (base 2) exponent of the return
666 * value, reflecting adjustments above to avoid overflow in the
667 * native arithmetic. For native IBM (base 16) arithmetic, we
668 * must multiply e2 by 4 to change from base 16 to 2.
672 rvb
= d2b(dval(rv
), &rve
, &rvbits
); /* rv = rvb * 2^rve */
674 return STRTOG_NoMemory
;
676 if ((j
= rvbits
- nbits
) > 0) {
681 bb0
= 0; /* trailing zero bits in rvb */
682 e2
= rve
+ rvbits
- nbits
;
683 if (e2
> fpi
->emax
+ 1)
685 rve1
= rve
+ rvbits
- nbits
;
686 if (e2
< (emin
= fpi
->emin
)) {
690 rvb
= lshift(rvb
, j
);
701 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
704 rvb
->x
[0] = rvb
->wds
= rvbits
= 1;
710 if (sudden_underflow
&& e2
+ 1 < emin
)
714 /* Now the hard part -- adjusting rv to the correct value.*/
716 /* Put digits into bd: true value = bd * 10^e */
718 bd0
= s2b(s0
, nd0
, nd
, y
);
723 return STRTOG_NoMemory
;
727 return STRTOG_NoMemory
;
729 bbbits
= rvbits
- bb0
;
733 return STRTOG_NoMemory
;
748 j
= nbits
+ 1 - bbbits
;
749 i
= bbe
+ bbbits
- nbits
;
750 if (i
< emin
) /* denormal */
754 i
= bb2
< bd2
? bb2
: bd2
;
763 bs
= pow5mult(bs
, bb5
);
765 return STRTOG_NoMemory
;
768 return STRTOG_NoMemory
;
774 bb
= lshift(bb
, bb2
);
776 return STRTOG_NoMemory
;
781 bd
= pow5mult(bd
, bd5
);
783 return STRTOG_NoMemory
;
786 bd
= lshift(bd
, bd2
);
788 return STRTOG_NoMemory
;
791 bs
= lshift(bs
, bs2
);
793 return STRTOG_NoMemory
;
796 inex
= STRTOG_Inexhi
;
797 delta
= diff(bb
, bd
);
799 return STRTOG_NoMemory
;
800 if (delta
->wds
<= 1 && !delta
->x
[0])
803 delta
->sign
= finished
= 0;
808 if ( (finished
= dsign
^ (rd
&1)) !=0) {
810 irv
|= STRTOG_Inexhi
;
813 irv
|= STRTOG_Inexlo
;
816 for(i
= 0, j
= nbits
; j
>= ULbits
;
818 if (rvb
->x
[i
] & ALL_ON
)
821 if (j
> 1 && lo0bits(rvb
->x
+ i
) < j
- 1)
824 rvb
= set_ones(rvb
, rvbits
= nbits
);
826 return STRTOG_NoMemory
;
829 irv
|= dsign
? STRTOG_Inexlo
: STRTOG_Inexhi
;
833 /* Error is less than half an ulp -- check for
834 * special case of mantissa a power of two.
837 ? STRTOG_Normal
| STRTOG_Inexlo
838 : STRTOG_Normal
| STRTOG_Inexhi
;
839 if (dsign
|| bbbits
> 1 || denorm
|| rve1
== emin
)
841 delta
= lshift(delta
,1);
843 return STRTOG_NoMemory
;
844 if (cmp(delta
, bs
) > 0) {
845 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
851 /* exactly half-way between */
853 if (denorm
&& all_on(rvb
, rvbits
)) {
854 /*boundary case -- increment exponent*/
857 rve
= emin
+ nbits
- (rvbits
= 1);
858 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
862 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
864 else if (bbbits
== 1) {
867 /* boundary case -- decrement exponent */
869 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
870 if (rvb
->wds
== 1 && rvb
->x
[0] == 1)
871 sudden_underflow
= 1;
875 rvb
= set_ones(rvb
, rvbits
= nbits
);
877 return STRTOG_NoMemory
;
881 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
882 if ((bbbits
< nbits
&& !denorm
) || !(rvb
->x
[0] & 1))
885 rvb
= increment(rvb
);
887 return STRTOG_NoMemory
;
888 if ( (j
= rvbits
& kmask
) !=0)
890 if (hi0bits(rvb
->x
[(unsigned int)(rvb
->wds
- 1)
894 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
900 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
904 if ((dval(adj
) = ratio(delta
, bs
)) <= 2.) {
906 inex
= STRTOG_Inexlo
;
909 inex
= STRTOG_Inexhi
;
911 else if (denorm
&& bbbits
<= 1) {
915 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
918 adj0
= dval(adj
) = 1.;
921 adj0
= dval(adj
) *= 0.5;
924 inex
= STRTOG_Inexlo
;
926 if (dval(adj
) < 2147483647.) {
935 if (asub
&& adj0
> 0.)
939 if (!asub
&& adj0
> 0.) {
942 inex
= STRTOG_Inexact
- inex
;
945 dval(adj
) = (double)L
;
950 /* adj *= ulp(dval(rv)); */
951 /* if (asub) rv -= adj; else rv += adj; */
953 if (!denorm
&& rvbits
< nbits
) {
954 rvb
= lshift(rvb
, j
= nbits
- rvbits
);
956 return STRTOG_NoMemory
;
960 ab
= d2b(dval(adj
), &abe
, &abits
);
962 return STRTOG_NoMemory
;
966 ab
= lshift(ab
, abe
);
970 j
= hi0bits(rvb
->x
[rvb
->wds
-1]);
973 return STRTOG_NoMemory
;
977 else if (rvb
->wds
<= k
978 || hi0bits( rvb
->x
[k
]) >
979 hi0bits(rvb0
->x
[k
])) {
980 /* unlikely; can only have lost 1 high bit */
986 rvb
= lshift(rvb
, 1);
988 return STRTOG_NoMemory
;
998 return STRTOG_NoMemory
;
1001 || hi0bits(rvb
->x
[k
]) < hi0bits(rvb0
->x
[k
])) {
1003 if (++rvbits
== nbits
)
1021 /* Can we stop now? */
1022 tol
= dval(adj
) * 5e-16; /* > max rel error */
1023 dval(adj
) = adj0
- .5;
1024 if (dval(adj
) < -tol
) {
1030 else if (dval(adj
) > tol
&& adj0
< 1. - tol
) {
1035 bb0
= denorm
? 0 : trailz(rvb
);
1041 if (!denorm
&& (j
= nbits
- rvbits
)) {
1043 rvb
= lshift(rvb
, j
);
1054 if (rve
> fpi
->emax
) {
1057 irv
= STRTOG_Infinite
| STRTOG_Overflow
| STRTOG_Inexhi
;
1064 *expt
= fpi
->emax
+ 1;
1068 if (sudden_underflow
) {
1070 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
1073 irv
= (irv
& ~STRTOG_Retmask
) |
1074 (rvb
->wds
> 0 ? STRTOG_Denormal
: STRTOG_Zero
);
1075 if (irv
& STRTOG_Inexact
)
1076 irv
|= STRTOG_Underflow
;
1084 copybits(bits
, nbits
, rvb
);