smisc.c revision 1.3
1/* $NetBSD: smisc.c,v 1.3 2008/03/21 23:13:48 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) CONST char *s; int nd0, nd; ULong y9;
40#else
41	(CONST char *s, int nd0, int nd, ULong y9)
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++;
73		}
74	else
75		s += 10;
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
84 double
85ratio
86#ifdef KR_headers
87	(a, b) Bigint *a, *b;
88#else
89	(Bigint *a, Bigint *b)
90#endif
91{
92	double da, db;
93	int k, ka, kb;
94
95	dval(da) = b2d(a, &ka);
96	dval(db) = b2d(b, &kb);
97	k = ka - kb + ULbits*(a->wds - b->wds);
98#ifdef IBM
99	if (k > 0) {
100		word0(da) += (k >> 2)*Exp_msk1;
101		if (k &= 3)
102			dval(da) *= 1 << k;
103		}
104	else {
105		k = -k;
106		word0(db) += (k >> 2)*Exp_msk1;
107		if (k &= 3)
108			dval(db) *= 1 << k;
109		}
110#else
111	if (k > 0)
112		word0(da) += k*Exp_msk1;
113	else {
114		k = -k;
115		word0(db) += k*Exp_msk1;
116		}
117#endif
118	return dval(da) / dval(db);
119	}
120
121#ifdef INFNAN_CHECK
122
123 int
124match
125#ifdef KR_headers
126	(sp, t) CONST char **sp, *t;
127#else
128	(CONST char **sp, CONST char *t)
129#endif
130{
131	int c, d;
132	CONST char *s = *sp;
133
134	while( (d = *t++) !=0) {
135		if ((c = *++s) >= 'A' && c <= 'Z')
136			c += 'a' - 'A';
137		if (c != d)
138			return 0;
139		}
140	*sp = s + 1;
141	return 1;
142	}
143#endif /* INFNAN_CHECK */
144
145 void
146#ifdef KR_headers
147copybits(c, n, b) ULong *c; int n; Bigint *b;
148#else
149copybits(ULong *c, int n, Bigint *b)
150#endif
151{
152	ULong *ce, *x, *xe;
153#ifdef Pack_16
154	int nw, nw1;
155#endif
156
157	ce = c + ((unsigned int)(n-1) >> kshift) + 1;
158	x = b->x;
159#ifdef Pack_32
160	xe = x + b->wds;
161	while(x < xe)
162		*c++ = *x++;
163#else
164	nw = b->wds;
165	nw1 = nw & 1;
166	for(xe = x + (nw - nw1); x < xe; x += 2)
167		Storeinc(c, x[1], x[0]);
168	if (nw1)
169		*c++ = *x;
170#endif
171	while(c < ce)
172		*c++ = 0;
173	}
174
175 ULong
176#ifdef KR_headers
177any_on(b, k) Bigint *b; int k;
178#else
179any_on(Bigint *b, int k)
180#endif
181{
182	int n, nwds;
183	ULong *x, *x0, x1, x2;
184
185	x = b->x;
186	nwds = b->wds;
187	n = (unsigned int)k >> kshift;
188	if (n > nwds)
189		n = nwds;
190	else if (n < nwds && (k &= kmask)) {
191		x1 = x2 = x[n];
192		x1 >>= k;
193		x1 <<= k;
194		if (x1 != x2)
195			return 1;
196		}
197	x0 = x;
198	x += n;
199	while(x > x0)
200		if (*--x)
201			return 1;
202	return 0;
203	}
204