smisc.c revision 1.4
1/* $NetBSD: smisc.c,v 1.4 2011/03/20 23:15:35 christos Exp $ */
2
3/****************************************************************
4
5The author of this software is David M. Gay.
6
7Copyright (C) 1998, 1999 by Lucent Technologies
8All Rights Reserved
9
10Permission to use, copy, modify, and distribute this software and
11its documentation for any purpose and without fee is hereby
12granted, provided that the above copyright notice appear in all
13copies and that both that the copyright notice and this
14permission notice and warranty disclaimer appear in supporting
15documentation, and that the name of Lucent or any of its entities
16not be used in advertising or publicity pertaining to
17distribution of the software without specific, written prior
18permission.
19
20LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
22IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
23SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
24WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
25IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
26ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
27THIS SOFTWARE.
28
29****************************************************************/
30
31/* Please send bug reports to David M. Gay (dmg at acm dot org,
32 * with " at " changed at "@" and " dot " changed to ".").	*/
33
34#include "gdtoaimp.h"
35
36 Bigint *
37s2b
38#ifdef KR_headers
39	(s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9;
40#else
41	(CONST char *s, int nd0, int nd, ULong y9, int dplen)
42#endif
43{
44	Bigint *b;
45	int i, k;
46	Long x, y;
47
48	x = (nd + 8) / 9;
49	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
50#ifdef Pack_32
51	b = Balloc(k);
52	if (b == NULL)
53		return NULL;
54	b->x[0] = y9;
55	b->wds = 1;
56#else
57	b = Balloc(k+1);
58	if (b == NULL)
59		return NULL;
60	b->x[0] = y9 & 0xffff;
61	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
62#endif
63
64	i = 9;
65	if (9 < nd0) {
66		s += 9;
67		do {
68			b = multadd(b, 10, *s++ - '0');
69			if (b == NULL)
70				return NULL;
71			} while(++i < nd0);
72		s += dplen;
73		}
74	else
75		s += dplen + 9;
76	for(; i < nd; i++) {
77		b = multadd(b, 10, *s++ - '0');
78		if (b == NULL)
79			return NULL;
80		}
81	return b;
82	}
83 double
84ratio
85#ifdef KR_headers
86	(a, b) Bigint *a, *b;
87#else
88	(Bigint *a, Bigint *b)
89#endif
90{
91	U da, db;
92	int k, ka, kb;
93
94	dval(&da) = b2d(a, &ka);
95	dval(&db) = b2d(b, &kb);
96	k = ka - kb + ULbits*(a->wds - b->wds);
97#ifdef IBM
98	if (k > 0) {
99		word0(&da) += (k >> 2)*Exp_msk1;
100		if (k &= 3)
101			dval(&da) *= 1 << k;
102		}
103	else {
104		k = -k;
105		word0(&db) += (k >> 2)*Exp_msk1;
106		if (k &= 3)
107			dval(&db) *= 1 << k;
108		}
109#else
110	if (k > 0)
111		word0(&da) += k*Exp_msk1;
112	else {
113		k = -k;
114		word0(&db) += k*Exp_msk1;
115		}
116#endif
117	return dval(&da) / dval(&db);
118	}
119
120#ifdef INFNAN_CHECK
121
122 int
123match
124#ifdef KR_headers
125	(sp, t) CONST char **sp, *t;
126#else
127	(CONST char **sp, CONST char *t)
128#endif
129{
130	int c, d;
131	CONST char *s = *sp;
132
133	while( (d = *t++) !=0) {
134		if ((c = *++s) >= 'A' && c <= 'Z')
135			c += 'a' - 'A';
136		if (c != d)
137			return 0;
138		}
139	*sp = s + 1;
140	return 1;
141	}
142#endif /* INFNAN_CHECK */
143
144 void
145#ifdef KR_headers
146copybits(c, n, b) ULong *c; int n; Bigint *b;
147#else
148copybits(ULong *c, int n, Bigint *b)
149#endif
150{
151	ULong *ce, *x, *xe;
152#ifdef Pack_16
153	int nw, nw1;
154#endif
155
156	ce = c + ((unsigned int)(n-1) >> kshift) + 1;
157	x = b->x;
158#ifdef Pack_32
159	xe = x + b->wds;
160	while(x < xe)
161		*c++ = *x++;
162#else
163	nw = b->wds;
164	nw1 = nw & 1;
165	for(xe = x + (nw - nw1); x < xe; x += 2)
166		Storeinc(c, x[1], x[0]);
167	if (nw1)
168		*c++ = *x;
169#endif
170	while(c < ce)
171		*c++ = 0;
172	}
173
174 ULong
175#ifdef KR_headers
176any_on(b, k) Bigint *b; int k;
177#else
178any_on(Bigint *b, int k)
179#endif
180{
181	int n, nwds;
182	ULong *x, *x0, x1, x2;
183
184	x = b->x;
185	nwds = b->wds;
186	n = (unsigned int)k >> kshift;
187	if (n > nwds)
188		n = nwds;
189	else if (n < nwds && (k &= kmask)) {
190		x1 = x2 = x[n];
191		x1 >>= k;
192		x1 <<= k;
193		if (x1 != x2)
194			return 1;
195		}
196	x0 = x;
197	x += n;
198	while(x > x0)
199		if (*--x)
200			return 1;
201	return 0;
202	}
203