smisc.c revision 219557
1285809Sscottl/****************************************************************
2285809Sscottl
3285809SscottlThe author of this software is David M. Gay.
4285809Sscottl
5285809SscottlCopyright (C) 1998, 1999 by Lucent Technologies
6285809SscottlAll Rights Reserved
7285809Sscottl
8285809SscottlPermission to use, copy, modify, and distribute this software and
9285809Sscottlits documentation for any purpose and without fee is hereby
10285809Sscottlgranted, provided that the above copyright notice appear in all
11285809Sscottlcopies and that both that the copyright notice and this
12285809Sscottlpermission notice and warranty disclaimer appear in supporting
13285809Sscottldocumentation, and that the name of Lucent or any of its entities
14285809Sscottlnot be used in advertising or publicity pertaining to
15285809Sscottldistribution of the software without specific, written prior
16285809Sscottlpermission.
17285809Sscottl
18285809SscottlLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19285809SscottlINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20285809SscottlIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21285809SscottlSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22285809SscottlWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23285809SscottlIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24285809SscottlARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25285809SscottlTHIS SOFTWARE.
26285809Sscottl
27285809Sscottl****************************************************************/
28285809Sscottl
29285809Sscottl/* Please send bug reports to David M. Gay (dmg at acm dot org,
30285809Sscottl * with " at " changed at "@" and " dot " changed to ".").	*/
31285809Sscottl
32285809Sscottl#include "gdtoaimp.h"
33285809Sscottl
34285809Sscottl Bigint *
35285809Sscottls2b
36285809Sscottl#ifdef KR_headers
37285809Sscottl	(s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9;
38285809Sscottl#else
39285809Sscottl	(CONST char *s, int nd0, int nd, ULong y9, int dplen)
40285809Sscottl#endif
41285809Sscottl{
42285809Sscottl	Bigint *b;
43285809Sscottl	int i, k;
44285809Sscottl	Long x, y;
45285809Sscottl
46285809Sscottl	x = (nd + 8) / 9;
47285809Sscottl	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
48285809Sscottl#ifdef Pack_32
49285809Sscottl	b = Balloc(k);
50285809Sscottl	b->x[0] = y9;
51285809Sscottl	b->wds = 1;
52285809Sscottl#else
53285809Sscottl	b = Balloc(k+1);
54285809Sscottl	b->x[0] = y9 & 0xffff;
55285809Sscottl	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
56285809Sscottl#endif
57285809Sscottl
58285809Sscottl	i = 9;
59285809Sscottl	if (9 < nd0) {
60285809Sscottl		s += 9;
61285809Sscottl		do b = multadd(b, 10, *s++ - '0');
62285809Sscottl			while(++i < nd0);
63285809Sscottl		s += dplen;
64285809Sscottl		}
65285809Sscottl	else
66285809Sscottl		s += dplen + 9;
67285809Sscottl	for(; i < nd; i++)
68285809Sscottl		b = multadd(b, 10, *s++ - '0');
69285809Sscottl	return b;
70285809Sscottl	}
71285809Sscottl
72285809Sscottl double
73285809Sscottlratio
74285809Sscottl#ifdef KR_headers
75285809Sscottl	(a, b) Bigint *a, *b;
76285809Sscottl#else
77285809Sscottl	(Bigint *a, Bigint *b)
78285809Sscottl#endif
79285809Sscottl{
80285809Sscottl	U da, db;
81285809Sscottl	int k, ka, kb;
82285809Sscottl
83285809Sscottl	dval(&da) = b2d(a, &ka);
84285809Sscottl	dval(&db) = b2d(b, &kb);
85285809Sscottl	k = ka - kb + ULbits*(a->wds - b->wds);
86285809Sscottl#ifdef IBM
87285809Sscottl	if (k > 0) {
88285809Sscottl		word0(&da) += (k >> 2)*Exp_msk1;
89285809Sscottl		if (k &= 3)
90285809Sscottl			dval(&da) *= 1 << k;
91285809Sscottl		}
92285809Sscottl	else {
93285809Sscottl		k = -k;
94285809Sscottl		word0(&db) += (k >> 2)*Exp_msk1;
95285809Sscottl		if (k &= 3)
96285809Sscottl			dval(&db) *= 1 << k;
97285809Sscottl		}
98285809Sscottl#else
99285809Sscottl	if (k > 0)
100285809Sscottl		word0(&da) += k*Exp_msk1;
101285809Sscottl	else {
102285809Sscottl		k = -k;
103285809Sscottl		word0(&db) += k*Exp_msk1;
104285809Sscottl		}
105285809Sscottl#endif
106285809Sscottl	return dval(&da) / dval(&db);
107285809Sscottl	}
108285809Sscottl
109285809Sscottl#ifdef INFNAN_CHECK
110285809Sscottl
111285809Sscottl int
112285809Sscottlmatch
113285809Sscottl#ifdef KR_headers
114285809Sscottl	(sp, t) char **sp, *t;
115285809Sscottl#else
116285809Sscottl	(CONST char **sp, char *t)
117285809Sscottl#endif
118285809Sscottl{
119285809Sscottl	int c, d;
120285809Sscottl	CONST char *s = *sp;
121285809Sscottl
122285809Sscottl	while( (d = *t++) !=0) {
123285809Sscottl		if ((c = *++s) >= 'A' && c <= 'Z')
124285809Sscottl			c += 'a' - 'A';
125285809Sscottl		if (c != d)
126285809Sscottl			return 0;
127285809Sscottl		}
128285809Sscottl	*sp = s + 1;
129285809Sscottl	return 1;
130285809Sscottl	}
131285809Sscottl#endif /* INFNAN_CHECK */
132285809Sscottl
133285809Sscottl void
134285809Sscottl#ifdef KR_headers
135285809Sscottlcopybits(c, n, b) ULong *c; int n; Bigint *b;
136285809Sscottl#else
137285809Sscottlcopybits(ULong *c, int n, Bigint *b)
138285809Sscottl#endif
139285809Sscottl{
140285809Sscottl	ULong *ce, *x, *xe;
141285809Sscottl#ifdef Pack_16
142285809Sscottl	int nw, nw1;
143285809Sscottl#endif
144285809Sscottl
145285809Sscottl	ce = c + ((n-1) >> kshift) + 1;
146285809Sscottl	x = b->x;
147285809Sscottl#ifdef Pack_32
148285809Sscottl	xe = x + b->wds;
149285809Sscottl	while(x < xe)
150285809Sscottl		*c++ = *x++;
151285809Sscottl#else
152285809Sscottl	nw = b->wds;
153285809Sscottl	nw1 = nw & 1;
154285809Sscottl	for(xe = x + (nw - nw1); x < xe; x += 2)
155285809Sscottl		Storeinc(c, x[1], x[0]);
156285809Sscottl	if (nw1)
157285809Sscottl		*c++ = *x;
158285809Sscottl#endif
159285809Sscottl	while(c < ce)
160285809Sscottl		*c++ = 0;
161285809Sscottl	}
162
163 ULong
164#ifdef KR_headers
165any_on(b, k) Bigint *b; int k;
166#else
167any_on(Bigint *b, int k)
168#endif
169{
170	int n, nwds;
171	ULong *x, *x0, x1, x2;
172
173	x = b->x;
174	nwds = b->wds;
175	n = k >> kshift;
176	if (n > nwds)
177		n = nwds;
178	else if (n < nwds && (k &= kmask)) {
179		x1 = x2 = x[n];
180		x1 >>= k;
181		x1 <<= k;
182		if (x1 != x2)
183			return 1;
184		}
185	x0 = x;
186	x += n;
187	while(x > x0)
188		if (*--x)
189			return 1;
190	return 0;
191	}
192