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