| 1 |  |  | /**************************************************************** | 
    
    | 2 |  |  |  | 
    
    | 3 |  |  | The author of this software is David M. Gay. | 
    
    | 4 |  |  |  | 
    
    | 5 |  |  | Copyright (C) 1998, 1999 by Lucent Technologies | 
    
    | 6 |  |  | All Rights Reserved | 
    
    | 7 |  |  |  | 
    
    | 8 |  |  | Permission to use, copy, modify, and distribute this software and | 
    
    | 9 |  |  | its documentation for any purpose and without fee is hereby | 
    
    | 10 |  |  | granted, provided that the above copyright notice appear in all | 
    
    | 11 |  |  | copies and that both that the copyright notice and this | 
    
    | 12 |  |  | permission notice and warranty disclaimer appear in supporting | 
    
    | 13 |  |  | documentation, and that the name of Lucent or any of its entities | 
    
    | 14 |  |  | not be used in advertising or publicity pertaining to | 
    
    | 15 |  |  | distribution of the software without specific, written prior | 
    
    | 16 |  |  | permission. | 
    
    | 17 |  |  |  | 
    
    | 18 |  |  | LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | 
    
    | 19 |  |  | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. | 
    
    | 20 |  |  | IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY | 
    
    | 21 |  |  | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
    
    | 22 |  |  | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | 
    
    | 23 |  |  | IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | 
    
    | 24 |  |  | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | 
    
    | 25 |  |  | THIS SOFTWARE. | 
    
    | 26 |  |  |  | 
    
    | 27 |  |  | ****************************************************************/ | 
    
    | 28 |  |  |  | 
    
    | 29 |  |  | /* Please send bug reports to David M. Gay (dmg at acm dot org, | 
    
    | 30 |  |  |  * with " at " changed at "@" and " dot " changed to ".").	*/ | 
    
    | 31 |  |  |  | 
    
    | 32 |  |  | #include "gdtoaimp.h" | 
    
    | 33 |  |  |  | 
    
    | 34 |  |  |  Bigint * | 
    
    | 35 |  |  | s2b | 
    
    | 36 |  |  | #ifdef KR_headers | 
    
    | 37 |  |  | 	(s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9; | 
    
    | 38 |  |  | #else | 
    
    | 39 |  |  | 	(CONST char *s, int nd0, int nd, ULong y9, int dplen) | 
    
    | 40 |  |  | #endif | 
    
    | 41 |  |  | { | 
    
    | 42 |  |  | 	Bigint *b; | 
    
    | 43 |  |  | 	int i, k; | 
    
    | 44 |  |  | 	Long x, y; | 
    
    | 45 |  |  |  | 
    
    | 46 |  |  | 	x = (nd + 8) / 9; | 
    
    | 47 |  |  | 	for(k = 0, y = 1; x > y; y <<= 1, k++) ; | 
    
    | 48 |  |  | #ifdef Pack_32 | 
    
    | 49 |  |  | 	b = Balloc(k); | 
    
    | 50 |  |  | 	if (b == NULL) | 
    
    | 51 |  |  | 		return (NULL); | 
    
    | 52 |  |  | 	b->x[0] = y9; | 
    
    | 53 |  |  | 	b->wds = 1; | 
    
    | 54 |  |  | #else | 
    
    | 55 |  |  | 	b = Balloc(k+1); | 
    
    | 56 |  |  | 	if (b == NULL) | 
    
    | 57 |  |  | 		return (NULL); | 
    
    | 58 |  |  | 	b->x[0] = y9 & 0xffff; | 
    
    | 59 |  |  | 	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; | 
    
    | 60 |  |  | #endif | 
    
    | 61 |  |  |  | 
    
    | 62 |  |  | 	i = 9; | 
    
    | 63 |  |  | 	if (9 < nd0) { | 
    
    | 64 |  |  | 		s += 9; | 
    
    | 65 |  |  | 		do { | 
    
    | 66 |  |  | 			b = multadd(b, 10, *s++ - '0'); | 
    
    | 67 |  |  | 			if (b == NULL) | 
    
    | 68 |  |  | 				return (NULL); | 
    
    | 69 |  |  | 			} while(++i < nd0); | 
    
    | 70 |  |  | 		s += dplen; | 
    
    | 71 |  |  | 		} | 
    
    | 72 |  |  | 	else | 
    
    | 73 |  |  | 		s += dplen + 9; | 
    
    | 74 |  |  | 	for(; i < nd; i++) { | 
    
    | 75 |  |  | 		b = multadd(b, 10, *s++ - '0'); | 
    
    | 76 |  |  | 		if (b == NULL) | 
    
    | 77 |  |  | 			return (NULL); | 
    
    | 78 |  |  | 		} | 
    
    | 79 |  |  | 	return b; | 
    
    | 80 |  |  | 	} | 
    
    | 81 |  |  |  | 
    
    | 82 |  |  |  double | 
    
    | 83 |  |  | ratio | 
    
    | 84 |  |  | #ifdef KR_headers | 
    
    | 85 |  |  | 	(a, b) Bigint *a, *b; | 
    
    | 86 |  |  | #else | 
    
    | 87 |  |  | 	(Bigint *a, Bigint *b) | 
    
    | 88 |  |  | #endif | 
    
    | 89 |  |  | { | 
    
    | 90 |  |  | 	U da, db; | 
    
    | 91 |  |  | 	int k, ka, kb; | 
    
    | 92 |  |  |  | 
    
    | 93 |  |  | 	dval(&da) = b2d(a, &ka); | 
    
    | 94 |  |  | 	dval(&db) = b2d(b, &kb); | 
    
    | 95 |  |  | 	k = ka - kb + ULbits*(a->wds - b->wds); | 
    
    | 96 |  |  | #ifdef IBM | 
    
    | 97 |  |  | 	if (k > 0) { | 
    
    | 98 |  |  | 		word0(&da) += (k >> 2)*Exp_msk1; | 
    
    | 99 |  |  | 		if (k &= 3) | 
    
    | 100 |  |  | 			dval(&da) *= 1 << k; | 
    
    | 101 |  |  | 		} | 
    
    | 102 |  |  | 	else { | 
    
    | 103 |  |  | 		k = -k; | 
    
    | 104 |  |  | 		word0(&db) += (k >> 2)*Exp_msk1; | 
    
    | 105 |  |  | 		if (k &= 3) | 
    
    | 106 |  |  | 			dval(&db) *= 1 << k; | 
    
    | 107 |  |  | 		} | 
    
    | 108 |  |  | #else | 
    
    | 109 |  |  | 	if (k > 0) | 
    
    | 110 |  |  | 		word0(&da) += k*Exp_msk1; | 
    
    | 111 |  |  | 	else { | 
    
    | 112 |  |  | 		k = -k; | 
    
    | 113 |  |  | 		word0(&db) += k*Exp_msk1; | 
    
    | 114 |  |  | 		} | 
    
    | 115 |  |  | #endif | 
    
    | 116 |  |  | 	return dval(&da) / dval(&db); | 
    
    | 117 |  |  | 	} | 
    
    | 118 |  |  |  | 
    
    | 119 |  |  | #ifdef INFNAN_CHECK | 
    
    | 120 |  |  |  | 
    
    | 121 |  |  |  int | 
    
    | 122 |  |  | match | 
    
    | 123 |  |  | #ifdef KR_headers | 
    
    | 124 |  |  | 	(sp, t) char **sp, *t; | 
    
    | 125 |  |  | #else | 
    
    | 126 |  |  | 	(CONST char **sp, char *t) | 
    
    | 127 |  |  | #endif | 
    
    | 128 |  |  | { | 
    
    | 129 |  |  | 	int c, d; | 
    
    | 130 |  |  | 	CONST char *s = *sp; | 
    
    | 131 |  |  |  | 
    
    | 132 |  |  | 	while( (d = *t++) !=0) { | 
    
    | 133 |  |  | 		if ((c = *++s) >= 'A' && c <= 'Z') | 
    
    | 134 |  |  | 			c += 'a' - 'A'; | 
    
    | 135 |  |  | 		if (c != d) | 
    
    | 136 |  |  | 			return 0; | 
    
    | 137 |  |  | 		} | 
    
    | 138 |  |  | 	*sp = s + 1; | 
    
    | 139 |  |  | 	return 1; | 
    
    | 140 |  |  | 	} | 
    
    | 141 |  |  | #endif /* INFNAN_CHECK */ | 
    
    | 142 |  |  |  | 
    
    | 143 |  |  |  void | 
    
    | 144 |  |  | #ifdef KR_headers | 
    
    | 145 |  |  | copybits(c, n, b) ULong *c; int n; Bigint *b; | 
    
    | 146 |  |  | #else | 
    
    | 147 |  |  | copybits(ULong *c, int n, Bigint *b) | 
    
    | 148 |  |  | #endif | 
    
    | 149 |  |  | { | 
    
    | 150 |  |  | 	ULong *ce, *x, *xe; | 
    
    | 151 |  |  | #ifdef Pack_16 | 
    
    | 152 |  |  | 	int nw, nw1; | 
    
    | 153 |  |  | #endif | 
    
    | 154 |  |  |  | 
    
    | 155 |  |  | 	ce = c + ((n-1) >> kshift) + 1; | 
    
    | 156 |  |  | 	x = b->x; | 
    
    | 157 |  |  | #ifdef Pack_32 | 
    
    | 158 |  |  | 	xe = x + b->wds; | 
    
    | 159 |  |  | 	while(x < xe) | 
    
    | 160 |  |  | 		*c++ = *x++; | 
    
    | 161 |  |  | #else | 
    
    | 162 |  |  | 	nw = b->wds; | 
    
    | 163 |  |  | 	nw1 = nw & 1; | 
    
    | 164 |  |  | 	for(xe = x + (nw - nw1); x < xe; x += 2) | 
    
    | 165 |  |  | 		Storeinc(c, x[1], x[0]); | 
    
    | 166 |  |  | 	if (nw1) | 
    
    | 167 |  |  | 		*c++ = *x; | 
    
    | 168 |  |  | #endif | 
    
    | 169 |  |  | 	while(c < ce) | 
    
    | 170 |  |  | 		*c++ = 0; | 
    
    | 171 |  |  | 	} | 
    
    | 172 |  |  |  | 
    
    | 173 |  |  |  ULong | 
    
    | 174 |  |  | #ifdef KR_headers | 
    
    | 175 |  |  | any_on(b, k) Bigint *b; int k; | 
    
    | 176 |  |  | #else | 
    
    | 177 |  |  | any_on(Bigint *b, int k) | 
    
    | 178 |  |  | #endif | 
    
    | 179 |  |  | { | 
    
    | 180 |  |  | 	int n, nwds; | 
    
    | 181 |  |  | 	ULong *x, *x0, x1, x2; | 
    
    | 182 |  |  |  | 
    
    | 183 |  |  | 	x = b->x; | 
    
    | 184 |  |  | 	nwds = b->wds; | 
    
    | 185 |  |  | 	n = k >> kshift; | 
    
    | 186 |  |  | 	if (n > nwds) | 
    
    | 187 |  |  | 		n = nwds; | 
    
    | 188 |  |  | 	else if (n < nwds && (k &= kmask)) { | 
    
    | 189 |  |  | 		x1 = x2 = x[n]; | 
    
    | 190 |  |  | 		x1 >>= k; | 
    
    | 191 |  |  | 		x1 <<= k; | 
    
    | 192 |  |  | 		if (x1 != x2) | 
    
    | 193 |  |  | 			return 1; | 
    
    | 194 |  |  | 		} | 
    
    | 195 |  |  | 	x0 = x; | 
    
    | 196 |  |  | 	x += n; | 
    
    | 197 |  |  | 	while(x > x0) | 
    
    | 198 |  |  | 		if (*--x) | 
    
    | 199 |  |  | 			return 1; | 
    
    | 200 |  |  | 	return 0; | 
    
    | 201 |  |  | 	} |