]>
git.proxmox.com Git - mirror_edk2.git/blob - StdLib/LibC/gdtoa/strtodg.c
3 Copyright (c) 2012 - 2014, 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
38 Please send bug reports to David M. Gay (dmg at acm dot org,
39 with " at " changed at "@" and " dot " changed to ".").
41 *****************************************************************
43 NetBSD: strtodg.c,v 1.5.14.1 2008/04/08 21:10:55 jdc Exp
45 #include <LibConfig.h>
54 // Disable warnings about assignment within conditional expressions.
55 #pragma warning ( disable : 4706 )
59 fivesbits
[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21,
60 24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
80 if (*x
< (ULong
)0xffffffffL
) {
97 if (b
->wds
>= b
->maxwds
) {
132 borrow
= (y
& 0x10000) >> 16;
134 } while(borrow
&& x
< xe
);
136 return STRTOG_Inexlo
;
140 all_on(CONST Bigint
*b
, int n
)
145 xe
= x
+ ((unsigned int)n
>> kshift
);
147 if ((*x
++ & ALL_ON
) != ALL_ON
)
150 return ((*x
| (ALL_ON
<< n
)) & ALL_ON
) == ALL_ON
;
155 set_ones(Bigint
*b
, int n
)
160 k
= (unsigned int)(n
+ ((1 << kshift
) - 1)) >> kshift
;
167 k
= (unsigned int)n
>> kshift
;
176 x
[-1] >>= ULbits
- n
;
182 double d
, CONST FPI
*fpi
, Long
*expt
, ULong
*bits
, int exact
, int rd
, int *irv
186 ULong carry
, inex
, lostbits
;
187 int bdif
, e
, j
, k
, k1
, nb
, rv
;
190 b
= d2b(d
, &e
, &bdif
);
191 bdif
-= nb
= fpi
->nbits
;
200 #ifndef IMPRECISE_INEXACT
217 default: /* round near */
226 if (b
->x
[(unsigned int)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
[(unsigned int)k1
>>kshift
] &
268 (ULong
)(1 << ((unsigned int)k1
& kmask
));
270 *irv
= STRTOG_Denormal
;
273 inex
= STRTOG_Inexhi
| STRTOG_Underflow
;
276 inex
= STRTOG_Inexlo
| STRTOG_Underflow
;
279 else if (e
> fpi
->emax
) {
281 *irv
= STRTOG_Infinite
| STRTOG_Overflow
| STRTOG_Inexhi
;
288 copybits(bits
, nb
, b
);
300 if ( (L
= word1(d
)) !=0)
301 return P
- lo0bits(&L
);
302 L
= word0(d
) | Exp_msk1
;
303 return P
- 32 - lo0bits(&L
);
308 CONST
char *s00
, char **se
, CONST FPI
*fpi
, Long
*expt
, ULong
*bits
311 int abe
= 0, abits
= 0, asub
;
312 int bb0
, bb2
, bb5
, bbe
, bd2
, bd5
, bbbits
, bs2
, c
, decpt
, denorm
;
313 int dsign
, e
, e1
, e2
, emin
, esign
, finished
, i
, inex
, irv
;
314 int j
, k
, nbits
, nd
, nd0
, nf
, nz
, nz0
, rd
, rvbits
, rve
, rve1
, sign
;
315 int sudden_underflow
= 0; /* pacify gcc */
316 CONST
char *s
, *s0
, *s1
;
317 double adj
, adj0
, rv
, tol
;
320 Bigint
*ab
, *bb
, *bb1
, *bd
, *bd0
, *bs
, *delta
, *rvb
, *rvb0
;
322 e2
= 0; /* XXX gcc */
325 denorm
= sign
= nz0
= nz
= 0;
329 for(s
= s00
;;s
++) switch(*s
) {
339 irv
= STRTOG_NoNumber
;
358 irv
= gethex(&s
, fpi
, expt
, &rvb
, sign
);
359 if (irv
== STRTOG_NoNumber
) {
371 sudden_underflow
= fpi
->sudden_underflow
;
374 for(decpt
= nd
= nf
= 0; (c
= *s
) >= '0' && c
<= '9'; nd
++, s
++)
381 if (c
== *localeconv()->decimal_point
)
389 for(; c
== '0'; c
= *++s
)
391 if (c
> '0' && c
<= '9') {
399 for(; c
>= '0' && c
<= '9'; c
= *++s
) {
404 for(i
= 1; i
< nz
; i
++)
407 else if (nd
<= DBL_DIG
+ 1)
411 else if (nd
<= DBL_DIG
+ 1)
419 if (c
== 'e' || c
== 'E') {
420 if (!nd
&& !nz
&& !nz0
) {
421 irv
= STRTOG_NoNumber
;
434 if (c
>= '0' && c
<= '9') {
437 if (c
> '0' && c
<= '9') {
440 while((c
= *++s
) >= '0' && c
<= '9')
442 if (s
- s1
> 8 || L
> 19999)
443 /* Avoid confusion from exponents
444 * so large that e might overflow.
446 e
= 19999; /* safe for 16 bit ints */
461 /* Check for Nan and Infinity */
466 if (match(&s
,"nf")) {
468 if (!match(&s
,"inity"))
470 irv
= STRTOG_Infinite
;
476 if (match(&s
, "an")) {
478 *expt
= fpi
->emax
+ 1;
481 irv
= hexnan(&s
, fpi
, bits
);
486 #endif /* INFNAN_CHECK */
487 irv
= STRTOG_NoNumber
;
496 switch(fpi
->rounding
& 3) {
507 /* Now we have nd0 digits, starting at s0, followed by a
508 * decimal point, followed by nd-nd0 digits. The number we're
509 * after is the integer represented by those digits times
514 k
= nd
< DBL_DIG
+ 1 ? nd
: DBL_DIG
+ 1;
515 dval(rv
) = (double)y
;
517 dval(rv
) = tens
[k
- 9] * dval(rv
) + z
;
519 if (nbits
<= P
&& nd
<= DBL_DIG
) {
521 if (rvOK(dval(rv
), fpi
, expt
, bits
, 1, rd
, &irv
))
526 i
= fivesbits
[e
] + mantbits(dval(rv
)) <= P
;
527 /* rv = */ rounded_product(dval(rv
), tens
[e
]);
528 if (rvOK(dval(rv
), fpi
, expt
, bits
, i
, rd
, &irv
))
534 if (e
<= Ten_pmax
+ i
) {
535 /* A fancier test would sometimes let us do
536 * this for larger i values.
541 /* rv = */ rounded_product(dval(rv
), tens
[e2
]);
542 if (rvOK(dval(rv
), fpi
, expt
, bits
, 0, rd
, &irv
))
547 #ifndef Inaccurate_Divide
548 else if (e
>= -Ten_pmax
) {
549 /* rv = */ rounded_quotient(dval(rv
), tens
[-e
]);
550 if (rvOK(dval(rv
), fpi
, expt
, bits
, 0, rd
, &irv
))
559 /* Get starting approximation = rv * 10**e1 */
563 if ( (i
= e1
& 15) !=0)
566 e1
= (unsigned int)e1
>> 4;
567 while(e1
>= (1 << (n_bigtens
-1))) {
568 e2
+= (unsigned int)((word0(rv
) & Exp_mask
)
569 >> Exp_shift1
) - Bias
;
570 word0(rv
) &= ~Exp_mask
;
571 word0(rv
) |= Bias
<< Exp_shift1
;
572 dval(rv
) *= bigtens
[n_bigtens
-1];
573 e1
-= 1 << (n_bigtens
-1);
575 e2
+= (unsigned int)((word0(rv
) & Exp_mask
) >> Exp_shift1
) - Bias
;
576 word0(rv
) &= ~Exp_mask
;
577 word0(rv
) |= Bias
<< Exp_shift1
;
578 for(j
= 0; e1
> 0; j
++, e1
= (unsigned int)e1
>> 1)
580 dval(rv
) *= bigtens
[j
];
585 if ( (i
= e1
& 15) !=0)
588 e1
= (unsigned int)e1
>> 4;
589 while(e1
>= (1 << (n_bigtens
-1))) {
590 e2
+= (unsigned int)((word0(rv
) & Exp_mask
)
591 >> Exp_shift1
) - Bias
;
592 word0(rv
) &= ~Exp_mask
;
593 word0(rv
) |= Bias
<< Exp_shift1
;
594 dval(rv
) *= tinytens
[n_bigtens
-1];
595 e1
-= 1 << (n_bigtens
-1);
597 e2
+= (unsigned int)((word0(rv
) & Exp_mask
) >> Exp_shift1
) - Bias
;
598 word0(rv
) &= ~Exp_mask
;
599 word0(rv
) |= Bias
<< Exp_shift1
;
600 for(j
= 0; e1
> 0; j
++, e1
= (unsigned int)e1
>> 1)
602 dval(rv
) *= tinytens
[j
];
605 rvb
= d2b(dval(rv
), &rve
, &rvbits
); /* rv = rvb * 2^rve */
607 return STRTOG_NoMemory
;
609 if ((j
= rvbits
- nbits
) > 0) {
614 bb0
= 0; /* trailing zero bits in rvb */
615 e2
= rve
+ rvbits
- nbits
;
616 if (e2
> fpi
->emax
+ 1)
618 rve1
= rve
+ rvbits
- nbits
;
619 if (e2
< (emin
= fpi
->emin
)) {
623 rvb
= lshift(rvb
, j
);
634 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
637 rvb
->x
[0] = rvb
->wds
= rvbits
= 1;
643 if (sudden_underflow
&& e2
+ 1 < emin
)
647 /* Now the hard part -- adjusting rv to the correct value.*/
649 /* Put digits into bd: true value = bd * 10^e */
651 bd0
= s2b(s0
, nd0
, nd
, y
);
656 return STRTOG_NoMemory
;
660 return STRTOG_NoMemory
;
662 bbbits
= rvbits
- bb0
;
666 return STRTOG_NoMemory
;
681 j
= nbits
+ 1 - bbbits
;
682 i
= bbe
+ bbbits
- nbits
;
683 if (i
< emin
) /* denormal */
687 i
= bb2
< bd2
? bb2
: bd2
;
696 bs
= pow5mult(bs
, bb5
);
698 return STRTOG_NoMemory
;
701 return STRTOG_NoMemory
;
707 bb
= lshift(bb
, bb2
);
709 return STRTOG_NoMemory
;
714 bd
= pow5mult(bd
, bd5
);
716 return STRTOG_NoMemory
;
719 bd
= lshift(bd
, bd2
);
721 return STRTOG_NoMemory
;
724 bs
= lshift(bs
, bs2
);
726 return STRTOG_NoMemory
;
729 inex
= STRTOG_Inexhi
;
730 delta
= diff(bb
, bd
);
732 return STRTOG_NoMemory
;
733 if (delta
->wds
<= 1 && !delta
->x
[0])
736 delta
->sign
= finished
= 0;
741 if ( (finished
= dsign
^ (rd
&1)) !=0) {
743 irv
|= STRTOG_Inexhi
;
746 irv
|= STRTOG_Inexlo
;
749 for(i
= 0, j
= nbits
; j
>= ULbits
;
751 if (rvb
->x
[i
] & ALL_ON
)
754 if (j
> 1 && lo0bits(rvb
->x
+ i
) < j
- 1)
757 rvb
= set_ones(rvb
, rvbits
= nbits
);
759 return STRTOG_NoMemory
;
762 irv
|= dsign
? STRTOG_Inexlo
: STRTOG_Inexhi
;
766 /* Error is less than half an ulp -- check for
767 * special case of mantissa a power of two.
770 ? STRTOG_Normal
| STRTOG_Inexlo
771 : STRTOG_Normal
| STRTOG_Inexhi
;
772 if (dsign
|| bbbits
> 1 || denorm
|| rve1
== emin
)
774 delta
= lshift(delta
,1);
776 return STRTOG_NoMemory
;
777 if (cmp(delta
, bs
) > 0) {
778 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
784 /* exactly half-way between */
786 if (denorm
&& all_on(rvb
, rvbits
)) {
787 /*boundary case -- increment exponent*/
790 rve
= emin
+ nbits
- (rvbits
= 1);
791 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
795 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
797 else if (bbbits
== 1) {
800 /* boundary case -- decrement exponent */
802 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
803 if (rvb
->wds
== 1 && rvb
->x
[0] == 1)
804 sudden_underflow
= 1;
808 rvb
= set_ones(rvb
, rvbits
= nbits
);
810 return STRTOG_NoMemory
;
814 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
815 if ((bbbits
< nbits
&& !denorm
) || !(rvb
->x
[0] & 1))
818 rvb
= increment(rvb
);
820 return STRTOG_NoMemory
;
821 if ( (j
= rvbits
& kmask
) !=0)
823 if (hi0bits(rvb
->x
[(unsigned int)(rvb
->wds
- 1)
827 irv
= STRTOG_Normal
| STRTOG_Inexhi
;
833 irv
= STRTOG_Normal
| STRTOG_Inexlo
;
837 if ((dval(adj
) = ratio(delta
, bs
)) <= 2.) {
839 inex
= STRTOG_Inexlo
;
842 inex
= STRTOG_Inexhi
;
844 else if (denorm
&& bbbits
<= 1) {
848 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
851 adj0
= dval(adj
) = 1.;
854 adj0
= dval(adj
) *= 0.5;
857 inex
= STRTOG_Inexlo
;
859 if (dval(adj
) < 2147483647.) {
868 if (asub
&& adj0
> 0.)
872 if (!asub
&& adj0
> 0.) {
875 inex
= STRTOG_Inexact
- inex
;
878 dval(adj
) = (double)L
;
883 /* adj *= ulp(dval(rv)); */
884 /* if (asub) rv -= adj; else rv += adj; */
886 if (!denorm
&& rvbits
< nbits
) {
887 rvb
= lshift(rvb
, j
= nbits
- rvbits
);
889 return STRTOG_NoMemory
;
893 ab
= d2b(dval(adj
), &abe
, &abits
);
895 return STRTOG_NoMemory
;
899 ab
= lshift(ab
, abe
);
903 j
= hi0bits(rvb
->x
[rvb
->wds
-1]);
906 return STRTOG_NoMemory
;
910 else if (rvb
->wds
<= k
911 || hi0bits( rvb
->x
[k
]) >
912 hi0bits(rvb0
->x
[k
])) {
913 /* unlikely; can only have lost 1 high bit */
919 rvb
= lshift(rvb
, 1);
921 return STRTOG_NoMemory
;
931 return STRTOG_NoMemory
;
934 || hi0bits(rvb
->x
[k
]) < hi0bits(rvb0
->x
[k
])) {
936 if (++rvbits
== nbits
)
954 /* Can we stop now? */
955 tol
= dval(adj
) * 5e-16; /* > max rel error */
956 dval(adj
) = adj0
- .5;
957 if (dval(adj
) < -tol
) {
963 else if (dval(adj
) > tol
&& adj0
< 1. - tol
) {
968 bb0
= denorm
? 0 : trailz(rvb
);
974 if (!denorm
&& (j
= nbits
- rvbits
)) {
976 rvb
= lshift(rvb
, j
);
987 if (rve
> fpi
->emax
) {
990 irv
= STRTOG_Infinite
| STRTOG_Overflow
| STRTOG_Inexhi
;
997 *expt
= fpi
->emax
+ 1;
1001 if (sudden_underflow
) {
1003 irv
= STRTOG_Underflow
| STRTOG_Inexlo
;
1006 irv
= (irv
& ~STRTOG_Retmask
) |
1007 (rvb
->wds
> 0 ? STRTOG_Denormal
: STRTOG_Zero
);
1008 if (irv
& STRTOG_Inexact
)
1009 irv
|= STRTOG_Underflow
;
1017 copybits(bits
, nbits
, rvb
);