xref: /netbsd-src/lib/libc/gdtoa/smisc.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /* $NetBSD: smisc.c,v 1.3 2008/03/21 23:13:48 christos 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 	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
85 ratio
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
124 match
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
147 copybits(c, n, b) ULong *c; int n; Bigint *b;
148 #else
149 copybits(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
177 any_on(b, k) Bigint *b; int k;
178 #else
179 any_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