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 *
s2b(s,nd0,nd,y9,dplen)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
ratio(a,b)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
match(sp,t)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
copybits(c,n,b)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
any_on(b,k)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 	}
202