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