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