Home | History | Annotate | Download | only in gdtoa
      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 	}
    202