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