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