xref: /openbsd/lib/libc/gdtoa/smisc.c (revision 1a653cbc)
17b36286aSmartynas /****************************************************************
27b36286aSmartynas 
37b36286aSmartynas The author of this software is David M. Gay.
47b36286aSmartynas 
57b36286aSmartynas Copyright (C) 1998, 1999 by Lucent Technologies
67b36286aSmartynas All Rights Reserved
77b36286aSmartynas 
87b36286aSmartynas Permission to use, copy, modify, and distribute this software and
97b36286aSmartynas its documentation for any purpose and without fee is hereby
107b36286aSmartynas granted, provided that the above copyright notice appear in all
117b36286aSmartynas copies and that both that the copyright notice and this
127b36286aSmartynas permission notice and warranty disclaimer appear in supporting
137b36286aSmartynas documentation, and that the name of Lucent or any of its entities
147b36286aSmartynas not be used in advertising or publicity pertaining to
157b36286aSmartynas distribution of the software without specific, written prior
167b36286aSmartynas permission.
177b36286aSmartynas 
187b36286aSmartynas LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
197b36286aSmartynas INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
207b36286aSmartynas IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
217b36286aSmartynas SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
227b36286aSmartynas WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
237b36286aSmartynas IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
247b36286aSmartynas ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
257b36286aSmartynas THIS SOFTWARE.
267b36286aSmartynas 
277b36286aSmartynas ****************************************************************/
287b36286aSmartynas 
297b36286aSmartynas /* Please send bug reports to David M. Gay (dmg at acm dot org,
307b36286aSmartynas  * with " at " changed at "@" and " dot " changed to ".").	*/
317b36286aSmartynas 
327b36286aSmartynas #include "gdtoaimp.h"
337b36286aSmartynas 
347b36286aSmartynas  Bigint *
s2b(s,nd0,nd,y9,dplen)357b36286aSmartynas s2b
367b36286aSmartynas #ifdef KR_headers
37*1a653cbcSmartynas 	(s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9;
387b36286aSmartynas #else
39*1a653cbcSmartynas 	(CONST char *s, int nd0, int nd, ULong y9, int dplen)
407b36286aSmartynas #endif
417b36286aSmartynas {
427b36286aSmartynas 	Bigint *b;
437b36286aSmartynas 	int i, k;
447b36286aSmartynas 	Long x, y;
457b36286aSmartynas 
467b36286aSmartynas 	x = (nd + 8) / 9;
477b36286aSmartynas 	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
487b36286aSmartynas #ifdef Pack_32
497b36286aSmartynas 	b = Balloc(k);
50384cfdc1Smartynas 	if (b == NULL)
51384cfdc1Smartynas 		return (NULL);
527b36286aSmartynas 	b->x[0] = y9;
537b36286aSmartynas 	b->wds = 1;
547b36286aSmartynas #else
557b36286aSmartynas 	b = Balloc(k+1);
56384cfdc1Smartynas 	if (b == NULL)
57384cfdc1Smartynas 		return (NULL);
587b36286aSmartynas 	b->x[0] = y9 & 0xffff;
597b36286aSmartynas 	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
607b36286aSmartynas #endif
617b36286aSmartynas 
627b36286aSmartynas 	i = 9;
637b36286aSmartynas 	if (9 < nd0) {
647b36286aSmartynas 		s += 9;
65384cfdc1Smartynas 		do {
66384cfdc1Smartynas 			b = multadd(b, 10, *s++ - '0');
67384cfdc1Smartynas 			if (b == NULL)
68384cfdc1Smartynas 				return (NULL);
69384cfdc1Smartynas 			} while(++i < nd0);
70*1a653cbcSmartynas 		s += dplen;
717b36286aSmartynas 		}
727b36286aSmartynas 	else
73*1a653cbcSmartynas 		s += dplen + 9;
74384cfdc1Smartynas 	for(; i < nd; i++) {
757b36286aSmartynas 		b = multadd(b, 10, *s++ - '0');
76384cfdc1Smartynas 		if (b == NULL)
77384cfdc1Smartynas 			return (NULL);
78384cfdc1Smartynas 		}
797b36286aSmartynas 	return b;
807b36286aSmartynas 	}
817b36286aSmartynas 
827b36286aSmartynas  double
ratio(a,b)837b36286aSmartynas ratio
847b36286aSmartynas #ifdef KR_headers
857b36286aSmartynas 	(a, b) Bigint *a, *b;
867b36286aSmartynas #else
877b36286aSmartynas 	(Bigint *a, Bigint *b)
887b36286aSmartynas #endif
897b36286aSmartynas {
90*1a653cbcSmartynas 	U da, db;
917b36286aSmartynas 	int k, ka, kb;
927b36286aSmartynas 
93*1a653cbcSmartynas 	dval(&da) = b2d(a, &ka);
94*1a653cbcSmartynas 	dval(&db) = b2d(b, &kb);
957b36286aSmartynas 	k = ka - kb + ULbits*(a->wds - b->wds);
967b36286aSmartynas #ifdef IBM
977b36286aSmartynas 	if (k > 0) {
98*1a653cbcSmartynas 		word0(&da) += (k >> 2)*Exp_msk1;
997b36286aSmartynas 		if (k &= 3)
100*1a653cbcSmartynas 			dval(&da) *= 1 << k;
1017b36286aSmartynas 		}
1027b36286aSmartynas 	else {
1037b36286aSmartynas 		k = -k;
104*1a653cbcSmartynas 		word0(&db) += (k >> 2)*Exp_msk1;
1057b36286aSmartynas 		if (k &= 3)
106*1a653cbcSmartynas 			dval(&db) *= 1 << k;
1077b36286aSmartynas 		}
1087b36286aSmartynas #else
1097b36286aSmartynas 	if (k > 0)
110*1a653cbcSmartynas 		word0(&da) += k*Exp_msk1;
1117b36286aSmartynas 	else {
1127b36286aSmartynas 		k = -k;
113*1a653cbcSmartynas 		word0(&db) += k*Exp_msk1;
1147b36286aSmartynas 		}
1157b36286aSmartynas #endif
116*1a653cbcSmartynas 	return dval(&da) / dval(&db);
1177b36286aSmartynas 	}
1187b36286aSmartynas 
1197b36286aSmartynas #ifdef INFNAN_CHECK
1207b36286aSmartynas 
1217b36286aSmartynas  int
match(sp,t)1227b36286aSmartynas match
1237b36286aSmartynas #ifdef KR_headers
1247b36286aSmartynas 	(sp, t) char **sp, *t;
1257b36286aSmartynas #else
1267b36286aSmartynas 	(CONST char **sp, char *t)
1277b36286aSmartynas #endif
1287b36286aSmartynas {
1297b36286aSmartynas 	int c, d;
1307b36286aSmartynas 	CONST char *s = *sp;
1317b36286aSmartynas 
1327b36286aSmartynas 	while( (d = *t++) !=0) {
1337b36286aSmartynas 		if ((c = *++s) >= 'A' && c <= 'Z')
1347b36286aSmartynas 			c += 'a' - 'A';
1357b36286aSmartynas 		if (c != d)
1367b36286aSmartynas 			return 0;
1377b36286aSmartynas 		}
1387b36286aSmartynas 	*sp = s + 1;
1397b36286aSmartynas 	return 1;
1407b36286aSmartynas 	}
1417b36286aSmartynas #endif /* INFNAN_CHECK */
1427b36286aSmartynas 
1437b36286aSmartynas  void
1447b36286aSmartynas #ifdef KR_headers
copybits(c,n,b)1457b36286aSmartynas copybits(c, n, b) ULong *c; int n; Bigint *b;
1467b36286aSmartynas #else
1477b36286aSmartynas copybits(ULong *c, int n, Bigint *b)
1487b36286aSmartynas #endif
1497b36286aSmartynas {
1507b36286aSmartynas 	ULong *ce, *x, *xe;
1517b36286aSmartynas #ifdef Pack_16
1527b36286aSmartynas 	int nw, nw1;
1537b36286aSmartynas #endif
1547b36286aSmartynas 
1557b36286aSmartynas 	ce = c + ((n-1) >> kshift) + 1;
1567b36286aSmartynas 	x = b->x;
1577b36286aSmartynas #ifdef Pack_32
1587b36286aSmartynas 	xe = x + b->wds;
1597b36286aSmartynas 	while(x < xe)
1607b36286aSmartynas 		*c++ = *x++;
1617b36286aSmartynas #else
1627b36286aSmartynas 	nw = b->wds;
1637b36286aSmartynas 	nw1 = nw & 1;
1647b36286aSmartynas 	for(xe = x + (nw - nw1); x < xe; x += 2)
1657b36286aSmartynas 		Storeinc(c, x[1], x[0]);
1667b36286aSmartynas 	if (nw1)
1677b36286aSmartynas 		*c++ = *x;
1687b36286aSmartynas #endif
1697b36286aSmartynas 	while(c < ce)
1707b36286aSmartynas 		*c++ = 0;
1717b36286aSmartynas 	}
1727b36286aSmartynas 
1737b36286aSmartynas  ULong
1747b36286aSmartynas #ifdef KR_headers
any_on(b,k)1757b36286aSmartynas any_on(b, k) Bigint *b; int k;
1767b36286aSmartynas #else
1777b36286aSmartynas any_on(Bigint *b, int k)
1787b36286aSmartynas #endif
1797b36286aSmartynas {
1807b36286aSmartynas 	int n, nwds;
1817b36286aSmartynas 	ULong *x, *x0, x1, x2;
1827b36286aSmartynas 
1837b36286aSmartynas 	x = b->x;
1847b36286aSmartynas 	nwds = b->wds;
1857b36286aSmartynas 	n = k >> kshift;
1867b36286aSmartynas 	if (n > nwds)
1877b36286aSmartynas 		n = nwds;
1887b36286aSmartynas 	else if (n < nwds && (k &= kmask)) {
1897b36286aSmartynas 		x1 = x2 = x[n];
1907b36286aSmartynas 		x1 >>= k;
1917b36286aSmartynas 		x1 <<= k;
1927b36286aSmartynas 		if (x1 != x2)
1937b36286aSmartynas 			return 1;
1947b36286aSmartynas 		}
1957b36286aSmartynas 	x0 = x;
1967b36286aSmartynas 	x += n;
1977b36286aSmartynas 	while(x > x0)
1987b36286aSmartynas 		if (*--x)
1997b36286aSmartynas 			return 1;
2007b36286aSmartynas 	return 0;
2017b36286aSmartynas 	}
202