g_ddfmt.c revision 165743
1112158Sdas/**************************************************************** 2112158Sdas 3112158SdasThe author of this software is David M. Gay. 4112158Sdas 5112158SdasCopyright (C) 1998 by Lucent Technologies 6112158SdasAll Rights Reserved 7112158Sdas 8112158SdasPermission to use, copy, modify, and distribute this software and 9112158Sdasits documentation for any purpose and without fee is hereby 10112158Sdasgranted, provided that the above copyright notice appear in all 11112158Sdascopies and that both that the copyright notice and this 12112158Sdaspermission notice and warranty disclaimer appear in supporting 13112158Sdasdocumentation, and that the name of Lucent or any of its entities 14112158Sdasnot be used in advertising or publicity pertaining to 15112158Sdasdistribution of the software without specific, written prior 16112158Sdaspermission. 17112158Sdas 18112158SdasLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 19112158SdasINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 20112158SdasIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 21112158SdasSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 22112158SdasWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 23112158SdasIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 24112158SdasARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 25112158SdasTHIS SOFTWARE. 26112158Sdas 27112158Sdas****************************************************************/ 28112158Sdas 29165743Sdas/* Please send bug reports to David M. Gay (dmg@acm.org). */ 30112158Sdas 31112158Sdas#include "gdtoaimp.h" 32112158Sdas#include <string.h> 33112158Sdas 34112158Sdas char * 35112158Sdas#ifdef KR_headers 36112158Sdasg_ddfmt(buf, dd, ndig, bufsize) char *buf; double *dd; int ndig; unsigned bufsize; 37112158Sdas#else 38112158Sdasg_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize) 39112158Sdas#endif 40112158Sdas{ 41112158Sdas FPI fpi; 42112158Sdas char *b, *s, *se; 43112158Sdas ULong *L, bits0[4], *bits, *zx; 44112158Sdas int bx, by, decpt, ex, ey, i, j, mode; 45112158Sdas Bigint *x, *y, *z; 46112158Sdas double ddx[2]; 47112158Sdas 48112158Sdas if (bufsize < 10 || bufsize < ndig + 8) 49112158Sdas return 0; 50112158Sdas 51112158Sdas L = (ULong*)dd; 52112158Sdas if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) { 53112158Sdas /* Infinity or NaN */ 54112158Sdas if (L[_0] & 0xfffff || L[_1]) { 55112158Sdas nanret: 56112158Sdas return strcp(buf, "NaN"); 57112158Sdas } 58112158Sdas if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { 59112158Sdas if (L[2+_0] & 0xfffff || L[2+_1]) 60112158Sdas goto nanret; 61112158Sdas if ((L[_0] ^ L[2+_0]) & 0x80000000L) 62112158Sdas goto nanret; /* Infinity - Infinity */ 63112158Sdas } 64112158Sdas infret: 65112158Sdas b = buf; 66112158Sdas if (L[_0] & 0x80000000L) 67112158Sdas *b++ = '-'; 68112158Sdas return strcp(b, "Infinity"); 69112158Sdas } 70112158Sdas if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { 71112158Sdas L += 2; 72112158Sdas if (L[_0] & 0xfffff || L[_1]) 73112158Sdas goto nanret; 74112158Sdas goto infret; 75112158Sdas } 76112158Sdas if (dd[0] + dd[1] == 0.) { 77112158Sdas b = buf; 78112158Sdas#ifndef IGNORE_ZERO_SIGN 79112158Sdas if (L[_0] & L[2+_0] & 0x80000000L) 80112158Sdas *b++ = '-'; 81112158Sdas#endif 82112158Sdas *b++ = '0'; 83112158Sdas *b = 0; 84112158Sdas return b; 85112158Sdas } 86112158Sdas if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) { 87112158Sdas ddx[1] = dd[0]; 88112158Sdas ddx[0] = dd[1]; 89112158Sdas dd = ddx; 90112158Sdas L = (ULong*)dd; 91112158Sdas } 92112158Sdas z = d2b(dd[0], &ex, &bx); 93112158Sdas if (dd[1] == 0.) 94112158Sdas goto no_y; 95112158Sdas x = z; 96112158Sdas y = d2b(dd[1], &ey, &by); 97112158Sdas if ( (i = ex - ey) !=0) { 98112158Sdas if (i > 0) { 99112158Sdas x = lshift(x, i); 100112158Sdas ex = ey; 101112158Sdas } 102112158Sdas else 103112158Sdas y = lshift(y, -i); 104112158Sdas } 105112158Sdas if ((L[_0] ^ L[2+_0]) & 0x80000000L) { 106112158Sdas z = diff(x, y); 107112158Sdas if (L[_0] & 0x80000000L) 108112158Sdas z->sign = 1 - z->sign; 109112158Sdas } 110112158Sdas else { 111112158Sdas z = sum(x, y); 112112158Sdas if (L[_0] & 0x80000000L) 113112158Sdas z->sign = 1; 114112158Sdas } 115112158Sdas Bfree(x); 116112158Sdas Bfree(y); 117112158Sdas no_y: 118112158Sdas bits = zx = z->x; 119112158Sdas for(i = 0; !*zx; zx++) 120112158Sdas i += 32; 121112158Sdas i += lo0bits(zx); 122112158Sdas if (i) { 123112158Sdas rshift(z, i); 124112158Sdas ex += i; 125112158Sdas } 126112158Sdas fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]); 127112158Sdas if (fpi.nbits < 106) { 128112158Sdas fpi.nbits = 106; 129112158Sdas if (j < 3) { 130112158Sdas for(i = 0; i <= j; i++) 131112158Sdas bits0[i] = bits[i]; 132112158Sdas while(i < 4) 133112158Sdas bits0[i++] = 0; 134112158Sdas bits = bits0; 135112158Sdas } 136112158Sdas } 137112158Sdas mode = 2; 138112158Sdas if (ndig <= 0) { 139112158Sdas if (bufsize < (int)(fpi.nbits * .301029995664) + 10) { 140112158Sdas Bfree(z); 141112158Sdas return 0; 142112158Sdas } 143112158Sdas mode = 0; 144112158Sdas } 145112158Sdas fpi.emin = 1-1023-53+1; 146112158Sdas fpi.emax = 2046-1023-106+1; 147112158Sdas fpi.rounding = FPI_Round_near; 148112158Sdas fpi.sudden_underflow = 0; 149112158Sdas i = STRTOG_Normal; 150112158Sdas s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); 151112158Sdas b = g__fmt(buf, s, se, decpt, z->sign); 152112158Sdas Bfree(z); 153112158Sdas return b; 154112158Sdas } 155