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 * 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 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 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 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 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