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