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 36219557Sdasg_ddfmt(buf, dd0, ndig, bufsize) char *buf; double *dd0; int ndig; size_t bufsize; 37112158Sdas#else 38219557Sdasg_ddfmt(char *buf, double *dd0, int ndig, size_t 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; 46219557Sdas U *dd, ddx[2]; 47187808Sdas#ifdef Honor_FLT_ROUNDS /*{{*/ 48187808Sdas int Rounding; 49187808Sdas#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ 50187808Sdas Rounding = Flt_Rounds; 51187808Sdas#else /*}{*/ 52187808Sdas Rounding = 1; 53187808Sdas switch(fegetround()) { 54187808Sdas case FE_TOWARDZERO: Rounding = 0; break; 55187808Sdas case FE_UPWARD: Rounding = 2; break; 56187808Sdas case FE_DOWNWARD: Rounding = 3; 57187808Sdas } 58187808Sdas#endif /*}}*/ 59187808Sdas#else /*}{*/ 60187808Sdas#define Rounding FPI_Round_near 61187808Sdas#endif /*}}*/ 62112158Sdas 63112158Sdas if (bufsize < 10 || bufsize < ndig + 8) 64112158Sdas return 0; 65112158Sdas 66219557Sdas dd = (U*)dd0; 67219557Sdas L = dd->L; 68112158Sdas if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) { 69112158Sdas /* Infinity or NaN */ 70112158Sdas if (L[_0] & 0xfffff || L[_1]) { 71112158Sdas nanret: 72112158Sdas return strcp(buf, "NaN"); 73112158Sdas } 74112158Sdas if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { 75112158Sdas if (L[2+_0] & 0xfffff || L[2+_1]) 76112158Sdas goto nanret; 77112158Sdas if ((L[_0] ^ L[2+_0]) & 0x80000000L) 78112158Sdas goto nanret; /* Infinity - Infinity */ 79112158Sdas } 80112158Sdas infret: 81112158Sdas b = buf; 82112158Sdas if (L[_0] & 0x80000000L) 83112158Sdas *b++ = '-'; 84112158Sdas return strcp(b, "Infinity"); 85112158Sdas } 86112158Sdas if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { 87112158Sdas L += 2; 88112158Sdas if (L[_0] & 0xfffff || L[_1]) 89112158Sdas goto nanret; 90112158Sdas goto infret; 91112158Sdas } 92219557Sdas if (dval(&dd[0]) + dval(&dd[1]) == 0.) { 93112158Sdas b = buf; 94112158Sdas#ifndef IGNORE_ZERO_SIGN 95112158Sdas if (L[_0] & L[2+_0] & 0x80000000L) 96112158Sdas *b++ = '-'; 97112158Sdas#endif 98112158Sdas *b++ = '0'; 99112158Sdas *b = 0; 100112158Sdas return b; 101112158Sdas } 102112158Sdas if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) { 103219557Sdas dval(&ddx[1]) = dval(&dd[0]); 104219557Sdas dval(&ddx[0]) = dval(&dd[1]); 105112158Sdas dd = ddx; 106219557Sdas L = dd->L; 107112158Sdas } 108219557Sdas z = d2b(dval(&dd[0]), &ex, &bx); 109219557Sdas if (dval(&dd[1]) == 0.) 110112158Sdas goto no_y; 111112158Sdas x = z; 112219557Sdas y = d2b(dval(&dd[1]), &ey, &by); 113112158Sdas if ( (i = ex - ey) !=0) { 114112158Sdas if (i > 0) { 115112158Sdas x = lshift(x, i); 116112158Sdas ex = ey; 117112158Sdas } 118112158Sdas else 119112158Sdas y = lshift(y, -i); 120112158Sdas } 121112158Sdas if ((L[_0] ^ L[2+_0]) & 0x80000000L) { 122112158Sdas z = diff(x, y); 123112158Sdas if (L[_0] & 0x80000000L) 124112158Sdas z->sign = 1 - z->sign; 125112158Sdas } 126112158Sdas else { 127112158Sdas z = sum(x, y); 128112158Sdas if (L[_0] & 0x80000000L) 129112158Sdas z->sign = 1; 130112158Sdas } 131112158Sdas Bfree(x); 132112158Sdas Bfree(y); 133112158Sdas no_y: 134112158Sdas bits = zx = z->x; 135112158Sdas for(i = 0; !*zx; zx++) 136112158Sdas i += 32; 137112158Sdas i += lo0bits(zx); 138112158Sdas if (i) { 139112158Sdas rshift(z, i); 140112158Sdas ex += i; 141112158Sdas } 142112158Sdas fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]); 143112158Sdas if (fpi.nbits < 106) { 144112158Sdas fpi.nbits = 106; 145112158Sdas if (j < 3) { 146112158Sdas for(i = 0; i <= j; i++) 147112158Sdas bits0[i] = bits[i]; 148112158Sdas while(i < 4) 149112158Sdas bits0[i++] = 0; 150112158Sdas bits = bits0; 151112158Sdas } 152112158Sdas } 153112158Sdas mode = 2; 154112158Sdas if (ndig <= 0) { 155112158Sdas if (bufsize < (int)(fpi.nbits * .301029995664) + 10) { 156112158Sdas Bfree(z); 157112158Sdas return 0; 158112158Sdas } 159112158Sdas mode = 0; 160112158Sdas } 161112158Sdas fpi.emin = 1-1023-53+1; 162112158Sdas fpi.emax = 2046-1023-106+1; 163187808Sdas fpi.rounding = Rounding; 164112158Sdas fpi.sudden_underflow = 0; 165112158Sdas i = STRTOG_Normal; 166112158Sdas s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); 167187808Sdas b = g__fmt(buf, s, se, decpt, z->sign, bufsize); 168112158Sdas Bfree(z); 169112158Sdas return b; 170112158Sdas } 171