]>
Commit | Line | Data |
---|---|---|
1 | /**************************************************************** | |
2 | ||
3 | The author of this software is David M. Gay. | |
4 | ||
5 | Copyright (C) 1998 by Lucent Technologies | |
6 | All Rights Reserved | |
7 | ||
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 | |
16 | permission. | |
17 | ||
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 | |
25 | THIS SOFTWARE. | |
26 | ||
27 | ****************************************************************/ | |
28 | ||
29 | /* Please send bug reports to David M. Gay (dmg at acm dot org, | |
30 | * with " at " changed at "@" and " dot " changed to "."). */ | |
31 | ||
32 | #include "gdtoaimp.h" | |
33 | ||
34 | int | |
35 | #ifdef KR_headers | |
36 | strtoIg(s00, se, fpi, exp, B, rvp) CONST char *s00; char **se; FPI *fpi; Long *exp; Bigint **B; int *rvp; | |
37 | #else | |
38 | strtoIg(CONST char *s00, char **se, FPI *fpi, Long *exp, Bigint **B, int *rvp) | |
39 | #endif | |
40 | { | |
41 | Bigint *b, *b1; | |
42 | int i, nb, nw, nw1, rv, rv1, swap; | |
43 | unsigned int nb1, nb11; | |
44 | Long e1; | |
45 | ||
46 | b = *B; | |
47 | rv = strtodg(s00, se, fpi, exp, b->x); | |
48 | if (!(rv & STRTOG_Inexact)) { | |
49 | B[1] = 0; | |
50 | return *rvp = rv; | |
51 | } | |
52 | e1 = exp[0]; | |
53 | rv1 = rv ^ STRTOG_Inexact; | |
54 | b1 = Balloc(b->k); | |
55 | Bcopy(b1, b); | |
56 | nb = fpi->nbits; | |
57 | nb1 = nb & 31; | |
58 | nb11 = (nb1 - 1) & 31; | |
59 | nw = b->wds; | |
60 | nw1 = nw - 1; | |
61 | if (rv & STRTOG_Inexlo) { | |
62 | swap = 0; | |
63 | b1 = increment(b1); | |
64 | if ((rv & STRTOG_Retmask) == STRTOG_Zero) { | |
65 | if (fpi->sudden_underflow) { | |
66 | b1->x[0] = 0; | |
67 | b1->x[nw1] = 1L << nb11; | |
68 | rv1 += STRTOG_Normal - STRTOG_Zero; | |
69 | rv1 &= ~STRTOG_Underflow; | |
70 | goto swapcheck; | |
71 | } | |
72 | rv1 &= STRTOG_Inexlo | STRTOG_Underflow | STRTOG_Zero; | |
73 | rv1 |= STRTOG_Inexhi | STRTOG_Denormal; | |
74 | goto swapcheck; | |
75 | } | |
76 | if (b1->wds > nw | |
77 | || (nb1 && b1->x[nw1] & 1L << nb1)) { | |
78 | if (++e1 > fpi->emax) | |
79 | rv1 = STRTOG_Infinite | STRTOG_Inexhi; | |
80 | rshift(b1, 1); | |
81 | } | |
82 | else if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { | |
83 | if (b1->x[nw1] & 1L << nb11) { | |
84 | rv1 += STRTOG_Normal - STRTOG_Denormal; | |
85 | rv1 &= ~STRTOG_Underflow; | |
86 | } | |
87 | } | |
88 | } | |
89 | else { | |
90 | swap = STRTOG_Neg; | |
91 | if ((rv & STRTOG_Retmask) == STRTOG_Infinite) { | |
92 | b1 = set_ones(b1, nb); | |
93 | e1 = fpi->emax; | |
94 | rv1 = STRTOG_Normal | STRTOG_Inexlo; | |
95 | goto swapcheck; | |
96 | } | |
97 | decrement(b1); | |
98 | if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { | |
99 | for(i = nw1; !b1->x[i]; --i) | |
100 | if (!i) { | |
101 | rv1 = STRTOG_Zero | STRTOG_Inexlo; | |
102 | break; | |
103 | } | |
104 | goto swapcheck; | |
105 | } | |
106 | if (!(b1->x[nw1] & 1L << nb11)) { | |
107 | if (e1 == fpi->emin) { | |
108 | if (fpi->sudden_underflow) | |
109 | rv1 += STRTOG_Zero - STRTOG_Normal; | |
110 | else | |
111 | rv1 += STRTOG_Denormal - STRTOG_Normal; | |
112 | rv1 |= STRTOG_Underflow; | |
113 | } | |
114 | else { | |
115 | b1 = lshift(b1, 1); | |
116 | b1->x[0] |= 1; | |
117 | --e1; | |
118 | } | |
119 | } | |
120 | } | |
121 | swapcheck: | |
122 | if (swap ^ (rv & STRTOG_Neg)) { | |
123 | rvp[0] = rv1; | |
124 | rvp[1] = rv; | |
125 | B[0] = b1; | |
126 | B[1] = b; | |
127 | exp[1] = exp[0]; | |
128 | exp[0] = e1; | |
129 | } | |
130 | else { | |
131 | rvp[0] = rv; | |
132 | rvp[1] = rv1; | |
133 | B[1] = b1; | |
134 | exp[1] = e1; | |
135 | } | |
136 | return rv; | |
137 | } |