1 |
|
|
/**************************************************************** |
2 |
|
|
|
3 |
|
|
The author of this software is David M. Gay. |
4 |
|
|
|
5 |
|
|
Copyright (C) 1998, 1999 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 |
|
|
Bigint * |
35 |
|
|
s2b |
36 |
|
|
#ifdef KR_headers |
37 |
|
|
(s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9; |
38 |
|
|
#else |
39 |
|
|
(CONST char *s, int nd0, int nd, ULong y9, int dplen) |
40 |
|
|
#endif |
41 |
|
|
{ |
42 |
|
|
Bigint *b; |
43 |
|
|
int i, k; |
44 |
|
|
Long x, y; |
45 |
|
|
|
46 |
|
|
x = (nd + 8) / 9; |
47 |
|
|
for(k = 0, y = 1; x > y; y <<= 1, k++) ; |
48 |
|
|
#ifdef Pack_32 |
49 |
|
|
b = Balloc(k); |
50 |
|
|
if (b == NULL) |
51 |
|
|
return (NULL); |
52 |
|
|
b->x[0] = y9; |
53 |
|
|
b->wds = 1; |
54 |
|
|
#else |
55 |
|
|
b = Balloc(k+1); |
56 |
|
|
if (b == NULL) |
57 |
|
|
return (NULL); |
58 |
|
|
b->x[0] = y9 & 0xffff; |
59 |
|
|
b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; |
60 |
|
|
#endif |
61 |
|
|
|
62 |
|
|
i = 9; |
63 |
|
|
if (9 < nd0) { |
64 |
|
|
s += 9; |
65 |
|
|
do { |
66 |
|
|
b = multadd(b, 10, *s++ - '0'); |
67 |
|
|
if (b == NULL) |
68 |
|
|
return (NULL); |
69 |
|
|
} while(++i < nd0); |
70 |
|
|
s += dplen; |
71 |
|
|
} |
72 |
|
|
else |
73 |
|
|
s += dplen + 9; |
74 |
|
|
for(; i < nd; i++) { |
75 |
|
|
b = multadd(b, 10, *s++ - '0'); |
76 |
|
|
if (b == NULL) |
77 |
|
|
return (NULL); |
78 |
|
|
} |
79 |
|
|
return b; |
80 |
|
|
} |
81 |
|
|
|
82 |
|
|
double |
83 |
|
|
ratio |
84 |
|
|
#ifdef KR_headers |
85 |
|
|
(a, b) Bigint *a, *b; |
86 |
|
|
#else |
87 |
|
|
(Bigint *a, Bigint *b) |
88 |
|
|
#endif |
89 |
|
|
{ |
90 |
|
|
U da, db; |
91 |
|
|
int k, ka, kb; |
92 |
|
|
|
93 |
|
|
dval(&da) = b2d(a, &ka); |
94 |
|
|
dval(&db) = b2d(b, &kb); |
95 |
|
|
k = ka - kb + ULbits*(a->wds - b->wds); |
96 |
|
|
#ifdef IBM |
97 |
|
|
if (k > 0) { |
98 |
|
|
word0(&da) += (k >> 2)*Exp_msk1; |
99 |
|
|
if (k &= 3) |
100 |
|
|
dval(&da) *= 1 << k; |
101 |
|
|
} |
102 |
|
|
else { |
103 |
|
|
k = -k; |
104 |
|
|
word0(&db) += (k >> 2)*Exp_msk1; |
105 |
|
|
if (k &= 3) |
106 |
|
|
dval(&db) *= 1 << k; |
107 |
|
|
} |
108 |
|
|
#else |
109 |
|
|
if (k > 0) |
110 |
|
|
word0(&da) += k*Exp_msk1; |
111 |
|
|
else { |
112 |
|
|
k = -k; |
113 |
|
|
word0(&db) += k*Exp_msk1; |
114 |
|
|
} |
115 |
|
|
#endif |
116 |
|
|
return dval(&da) / dval(&db); |
117 |
|
|
} |
118 |
|
|
|
119 |
|
|
#ifdef INFNAN_CHECK |
120 |
|
|
|
121 |
|
|
int |
122 |
|
|
match |
123 |
|
|
#ifdef KR_headers |
124 |
|
|
(sp, t) char **sp, *t; |
125 |
|
|
#else |
126 |
|
|
(CONST char **sp, char *t) |
127 |
|
|
#endif |
128 |
|
|
{ |
129 |
|
|
int c, d; |
130 |
|
|
CONST char *s = *sp; |
131 |
|
|
|
132 |
|
|
while( (d = *t++) !=0) { |
133 |
|
|
if ((c = *++s) >= 'A' && c <= 'Z') |
134 |
|
|
c += 'a' - 'A'; |
135 |
|
|
if (c != d) |
136 |
|
|
return 0; |
137 |
|
|
} |
138 |
|
|
*sp = s + 1; |
139 |
|
|
return 1; |
140 |
|
|
} |
141 |
|
|
#endif /* INFNAN_CHECK */ |
142 |
|
|
|
143 |
|
|
void |
144 |
|
|
#ifdef KR_headers |
145 |
|
|
copybits(c, n, b) ULong *c; int n; Bigint *b; |
146 |
|
|
#else |
147 |
|
|
copybits(ULong *c, int n, Bigint *b) |
148 |
|
|
#endif |
149 |
|
|
{ |
150 |
|
|
ULong *ce, *x, *xe; |
151 |
|
|
#ifdef Pack_16 |
152 |
|
|
int nw, nw1; |
153 |
|
|
#endif |
154 |
|
|
|
155 |
|
|
ce = c + ((n-1) >> kshift) + 1; |
156 |
|
|
x = b->x; |
157 |
|
|
#ifdef Pack_32 |
158 |
|
|
xe = x + b->wds; |
159 |
|
|
while(x < xe) |
160 |
|
|
*c++ = *x++; |
161 |
|
|
#else |
162 |
|
|
nw = b->wds; |
163 |
|
|
nw1 = nw & 1; |
164 |
|
|
for(xe = x + (nw - nw1); x < xe; x += 2) |
165 |
|
|
Storeinc(c, x[1], x[0]); |
166 |
|
|
if (nw1) |
167 |
|
|
*c++ = *x; |
168 |
|
|
#endif |
169 |
|
|
while(c < ce) |
170 |
|
|
*c++ = 0; |
171 |
|
|
} |
172 |
|
|
|
173 |
|
|
ULong |
174 |
|
|
#ifdef KR_headers |
175 |
|
|
any_on(b, k) Bigint *b; int k; |
176 |
|
|
#else |
177 |
|
|
any_on(Bigint *b, int k) |
178 |
|
|
#endif |
179 |
|
|
{ |
180 |
|
|
int n, nwds; |
181 |
|
|
ULong *x, *x0, x1, x2; |
182 |
|
|
|
183 |
|
|
x = b->x; |
184 |
|
|
nwds = b->wds; |
185 |
|
|
n = k >> kshift; |
186 |
|
|
if (n > nwds) |
187 |
|
|
n = nwds; |
188 |
|
|
else if (n < nwds && (k &= kmask)) { |
189 |
|
|
x1 = x2 = x[n]; |
190 |
|
|
x1 >>= k; |
191 |
|
|
x1 <<= k; |
192 |
|
|
if (x1 != x2) |
193 |
|
|
return 1; |
194 |
|
|
} |
195 |
|
|
x0 = x; |
196 |
|
|
x += n; |
197 |
|
|
while(x > x0) |
198 |
|
|
if (*--x) |
199 |
|
|
return 1; |
200 |
|
|
return 0; |
201 |
|
|
} |