Home | History | Annotate | Line # | Download | only in gdtoa
g_ddfmt.c revision 1.1
      1 /* $NetBSD: g_ddfmt.c,v 1.1 2006/01/25 15:18:44 kleink Exp $ */
      2 
      3 /****************************************************************
      4 
      5 The author of this software is David M. Gay.
      6 
      7 Copyright (C) 1998 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.org). */
     32 
     33 #include "gdtoaimp.h"
     34 #include <string.h>
     35 
     36  char *
     37 #ifdef KR_headers
     38 g_ddfmt(buf, dd, ndig, bufsize) char *buf; double *dd; int ndig; unsigned bufsize;
     39 #else
     40 g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize)
     41 #endif
     42 {
     43 	FPI fpi;
     44 	char *b, *s, *se;
     45 	ULong *L, bits0[4], *bits, *zx;
     46 	int bx, by, decpt, ex, ey, i, j, mode;
     47 	Bigint *x, *y, *z;
     48 	double ddx[2];
     49 
     50 	if (bufsize < 10 || bufsize < ndig + 8)
     51 		return 0;
     52 
     53 	L = (ULong*)dd;
     54 	if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) {
     55 		/* Infinity or NaN */
     56 		if (L[_0] & 0xfffff || L[_1]) {
     57  nanret:
     58 			return strcp(buf, "NaN");
     59 			}
     60 		if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) {
     61 			if (L[2+_0] & 0xfffff || L[2+_1])
     62 				goto nanret;
     63 			if ((L[_0] ^ L[2+_0]) & 0x80000000L)
     64 				goto nanret;	/* Infinity - Infinity */
     65 			}
     66  infret:
     67 		b = buf;
     68 		if (L[_0] & 0x80000000L)
     69 			*b++ = '-';
     70 		return strcp(b, "Infinity");
     71 		}
     72 	if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) {
     73 		L += 2;
     74 		if (L[_0] & 0xfffff || L[_1])
     75 			goto nanret;
     76 		goto infret;
     77 		}
     78 	if (dd[0] + dd[1] == 0.) {
     79 		b = buf;
     80 #ifndef IGNORE_ZERO_SIGN
     81 		if (L[_0] & L[2+_0] & 0x80000000L)
     82 			*b++ = '-';
     83 #endif
     84 		*b++ = '0';
     85 		*b = 0;
     86 		return b;
     87 		}
     88 	if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) {
     89 		ddx[1] = dd[0];
     90 		ddx[0] = dd[1];
     91 		dd = ddx;
     92 		L = (ULong*)dd;
     93 		}
     94 	z = d2b(dd[0], &ex, &bx);
     95 	if (dd[1] == 0.)
     96 		goto no_y;
     97 	x = z;
     98 	y = d2b(dd[1], &ey, &by);
     99 	if ( (i = ex - ey) !=0) {
    100 		if (i > 0) {
    101 			x = lshift(x, i);
    102 			ex = ey;
    103 			}
    104 		else
    105 			y = lshift(y, -i);
    106 		}
    107 	if ((L[_0] ^ L[2+_0]) & 0x80000000L) {
    108 		z = diff(x, y);
    109 		if (L[_0] & 0x80000000L)
    110 			z->sign = 1 - z->sign;
    111 		}
    112 	else {
    113 		z = sum(x, y);
    114 		if (L[_0] & 0x80000000L)
    115 			z->sign = 1;
    116 		}
    117 	Bfree(x);
    118 	Bfree(y);
    119  no_y:
    120 	bits = zx = z->x;
    121 	for(i = 0; !*zx; zx++)
    122 		i += 32;
    123 	i += lo0bits(zx);
    124 	if (i) {
    125 		rshift(z, i);
    126 		ex += i;
    127 		}
    128 	fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]);
    129 	if (fpi.nbits < 106) {
    130 		fpi.nbits = 106;
    131 		if (j < 3) {
    132 			for(i = 0; i <= j; i++)
    133 				bits0[i] = bits[i];
    134 			while(i < 4)
    135 				bits0[i++] = 0;
    136 			bits = bits0;
    137 			}
    138 		}
    139 	mode = 2;
    140 	if (ndig <= 0) {
    141 		if (bufsize < (int)(fpi.nbits * .301029995664) + 10) {
    142 			Bfree(z);
    143 			return 0;
    144 			}
    145 		mode = 0;
    146 		}
    147 	fpi.emin = 1-1023-53+1;
    148 	fpi.emax = 2046-1023-106+1;
    149 	fpi.rounding = FPI_Round_near;
    150 	fpi.sudden_underflow = 0;
    151 	i = STRTOG_Normal;
    152 	s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
    153 	b = g__fmt(buf, s, se, decpt, z->sign);
    154 	Bfree(z);
    155 	return b;
    156 	}
    157