xref: /minix3/lib/libc/gdtoa/smisc.c (revision f14fb602092e015ff630df58e17c2a9cd57d29b3)
1 /* $NetBSD: smisc.c,v 1.5 2012/03/13 21:13:34 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 *
s2b(s,nd0,nd,y9,dplen)37 s2b
38 #ifdef KR_headers
39 	(s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9;
40 #else
41 	(CONST char *s, int nd0, int nd, ULong y9, size_t dplen)
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 += dplen;
73 		}
74 	else
75 		s += dplen + 9;
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  double
ratio(a,b)84 ratio
85 #ifdef KR_headers
86 	(a, b) Bigint *a, *b;
87 #else
88 	(Bigint *a, Bigint *b)
89 #endif
90 {
91 	U da, db;
92 	int k, ka, kb;
93 
94 	dval(&da) = b2d(a, &ka);
95 	dval(&db) = b2d(b, &kb);
96 	k = ka - kb + ULbits*(a->wds - b->wds);
97 #ifdef IBM
98 	if (k > 0) {
99 		word0(&da) += (k >> 2)*Exp_msk1;
100 		if (k &= 3)
101 			dval(&da) *= 1 << k;
102 		}
103 	else {
104 		k = -k;
105 		word0(&db) += (k >> 2)*Exp_msk1;
106 		if (k &= 3)
107 			dval(&db) *= 1 << k;
108 		}
109 #else
110 	if (k > 0)
111 		word0(&da) += k*Exp_msk1;
112 	else {
113 		k = -k;
114 		word0(&db) += k*Exp_msk1;
115 		}
116 #endif
117 	return dval(&da) / dval(&db);
118 	}
119 
120 #ifdef INFNAN_CHECK
121 
122  int
match(sp,t)123 match
124 #ifdef KR_headers
125 	(sp, t) CONST char **sp, *t;
126 #else
127 	(CONST char **sp, CONST char *t)
128 #endif
129 {
130 	int c, d;
131 	CONST char *s = *sp;
132 
133 	while( (d = *t++) !=0) {
134 		if ((c = *++s) >= 'A' && c <= 'Z')
135 			c += 'a' - 'A';
136 		if (c != d)
137 			return 0;
138 		}
139 	*sp = s + 1;
140 	return 1;
141 	}
142 #endif /* INFNAN_CHECK */
143 
144  void
145 #ifdef KR_headers
copybits(c,n,b)146 copybits(c, n, b) ULong *c; int n; Bigint *b;
147 #else
148 copybits(ULong *c, int n, Bigint *b)
149 #endif
150 {
151 	ULong *ce, *x, *xe;
152 #ifdef Pack_16
153 	int nw, nw1;
154 #endif
155 
156 	ce = c + ((unsigned int)(n-1) >> kshift) + 1;
157 	x = b->x;
158 #ifdef Pack_32
159 	xe = x + b->wds;
160 	while(x < xe)
161 		*c++ = *x++;
162 #else
163 	nw = b->wds;
164 	nw1 = nw & 1;
165 	for(xe = x + (nw - nw1); x < xe; x += 2)
166 		Storeinc(c, x[1], x[0]);
167 	if (nw1)
168 		*c++ = *x;
169 #endif
170 	while(c < ce)
171 		*c++ = 0;
172 	}
173 
174  ULong
175 #ifdef KR_headers
any_on(b,k)176 any_on(b, k) Bigint *b; int k;
177 #else
178 any_on(Bigint *b, int k)
179 #endif
180 {
181 	int n, nwds;
182 	ULong *x, *x0, x1, x2;
183 
184 	x = b->x;
185 	nwds = b->wds;
186 	n = (unsigned int)k >> kshift;
187 	if (n > nwds)
188 		n = nwds;
189 	else if (n < nwds && (k &= kmask)) {
190 		x1 = x2 = x[n];
191 		x1 >>= k;
192 		x1 <<= k;
193 		if (x1 != x2)
194 			return 1;
195 		}
196 	x0 = x;
197 	x += n;
198 	while(x > x0)
199 		if (*--x)
200 			return 1;
201 	return 0;
202 	}
203