master
  1/****************************************************************
  2
  3The author of this software is David M. Gay.
  4
  5Copyright (C) 1998, 1999 by Lucent Technologies
  6All Rights Reserved
  7
  8Permission to use, copy, modify, and distribute this software and
  9its documentation for any purpose and without fee is hereby
 10granted, provided that the above copyright notice appear in all
 11copies and that both that the copyright notice and this
 12permission notice and warranty disclaimer appear in supporting
 13documentation, and that the name of Lucent or any of its entities
 14not be used in advertising or publicity pertaining to
 15distribution of the software without specific, written prior
 16permission.
 17
 18LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 19INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 20IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 21SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 22WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 23IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 24ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 25THIS 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
 34Bigint *s2b (const char *s, int nd0, int nd, ULong y9, int dplen)
 35{
 36	Bigint *b;
 37	int i, k;
 38	Long x, y;
 39
 40	x = (nd + 8) / 9;
 41	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
 42#ifdef Pack_32
 43	b = Balloc(k);
 44	b->x[0] = y9;
 45	b->wds = 1;
 46#else
 47	b = Balloc(k+1);
 48	b->x[0] = y9 & 0xffff;
 49	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
 50#endif
 51
 52	i = 9;
 53	if (9 < nd0) {
 54		s += 9;
 55		do b = multadd(b, 10, *s++ - '0');
 56			while(++i < nd0);
 57		s += dplen;
 58	}
 59	else
 60		s += dplen + 9;
 61	for(; i < nd; i++)
 62		b = multadd(b, 10, *s++ - '0');
 63	return b;
 64}
 65
 66double ratio (Bigint *a, Bigint *b)
 67{
 68	union _dbl_union da, db;
 69	int k, ka, kb;
 70
 71	dval(&da) = b2d(a, &ka);
 72	dval(&db) = b2d(b, &kb);
 73	k = ka - kb + ULbits*(a->wds - b->wds);
 74	if (k > 0)
 75		word0(&da) += k*Exp_msk1;
 76	else {
 77		k = -k;
 78		word0(&db) += k*Exp_msk1;
 79	}
 80	return dval(&da) / dval(&db);
 81}
 82
 83#ifdef INFNAN_CHECK
 84
 85int match (const char **sp, char *t)
 86{
 87	int c, d;
 88	const char *s = *sp;
 89
 90	while( (d = *t++) !=0) {
 91		if ((c = *++s) >= 'A' && c <= 'Z')
 92			c += 'a' - 'A';
 93		if (c != d)
 94			return 0;
 95	}
 96	*sp = s + 1;
 97	return 1;
 98}
 99#endif /* INFNAN_CHECK */
100
101void copybits (ULong *c, int n, Bigint *b)
102{
103	ULong *ce, *x, *xe;
104#ifdef Pack_16
105	int nw, nw1;
106#endif
107
108	ce = c + ((n-1) >> kshift) + 1;
109	x = b->x;
110#ifdef Pack_32
111	xe = x + b->wds;
112	while(x < xe)
113		*c++ = *x++;
114#else
115	nw = b->wds;
116	nw1 = nw & 1;
117	for(xe = x + (nw - nw1); x < xe; x += 2)
118		Storeinc(c, x[1], x[0]);
119	if (nw1)
120		*c++ = *x;
121#endif
122	while(c < ce)
123		*c++ = 0;
124}
125
126ULong any_on (Bigint *b, int k)
127{
128	int n, nwds;
129	ULong *x, *x0, x1, x2;
130
131	x = b->x;
132	nwds = b->wds;
133	n = k >> kshift;
134	if (n > nwds)
135		n = nwds;
136	else if (n < nwds && (k &= kmask)) {
137		x1 = x2 = x[n];
138		x1 >>= k;
139		x1 <<= k;
140		if (x1 != x2)
141			return 1;
142	}
143	x0 = x;
144	x += n;
145	while(x > x0)
146		if (*--x)
147			return 1;
148	return 0;
149}