Sync usage with man page.
[netbsd-mini2440.git] / lib / libc / gdtoa / g_ddfmt.c
blob3cb127f40ab5c33c1d6c07fc47e89b25e4b97ebb
1 /* $NetBSD: g_ddfmt.c,v 1.1.1.1 2006/01/25 15:18:44 kleink Exp $ */
3 /****************************************************************
5 The author of this software is David M. Gay.
7 Copyright (C) 1998 by Lucent Technologies
8 All Rights Reserved
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.
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.
29 ****************************************************************/
31 /* Please send bug reports to David M. Gay (dmg@acm.org). */
33 #include "gdtoaimp.h"
34 #include <string.h>
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
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];
50 if (bufsize < 10 || bufsize < ndig + 8)
51 return 0;
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");
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 */
66 infret:
67 b = buf;
68 if (L[_0] & 0x80000000L)
69 *b++ = '-';
70 return strcp(b, "Infinity");
72 if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) {
73 L += 2;
74 if (L[_0] & 0xfffff || L[_1])
75 goto nanret;
76 goto infret;
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;
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;
94 z = d2b(dd[0], &ex, &bx);
95 if (z == NULL)
96 return NULL;
97 if (dd[1] == 0.)
98 goto no_y;
99 x = z;
100 y = d2b(dd[1], &ey, &by);
101 if (y == NULL)
102 return NULL;
103 if ( (i = ex - ey) !=0) {
104 if (i > 0) {
105 x = lshift(x, i);
106 if (x == NULL)
107 return NULL;
108 ex = ey;
110 else {
111 y = lshift(y, -i);
112 if (y == NULL)
113 return NULL;
116 if ((L[_0] ^ L[2+_0]) & 0x80000000L) {
117 z = diff(x, y);
118 if (z == NULL)
119 return NULL;
120 if (L[_0] & 0x80000000L)
121 z->sign = 1 - z->sign;
123 else {
124 z = sum(x, y);
125 if (z == NULL)
126 return NULL;
127 if (L[_0] & 0x80000000L)
128 z->sign = 1;
130 Bfree(x);
131 Bfree(y);
132 no_y:
133 bits = zx = z->x;
134 for(i = 0; !*zx; zx++)
135 i += 32;
136 i += lo0bits(zx);
137 if (i) {
138 rshift(z, i);
139 ex += i;
141 fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]);
142 if (fpi.nbits < 106) {
143 fpi.nbits = 106;
144 if (j < 3) {
145 for(i = 0; i <= j; i++)
146 bits0[i] = bits[i];
147 while(i < 4)
148 bits0[i++] = 0;
149 bits = bits0;
152 mode = 2;
153 if (ndig <= 0) {
154 if (bufsize < (int)(fpi.nbits * .301029995664) + 10) {
155 Bfree(z);
156 return 0;
158 mode = 0;
160 fpi.emin = 1-1023-53+1;
161 fpi.emax = 2046-1023-106+1;
162 fpi.rounding = FPI_Round_near;
163 fpi.sudden_underflow = 0;
164 i = STRTOG_Normal;
165 s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
166 if (s == NULL)
167 return NULL;
168 b = g__fmt(buf, s, se, decpt, z->sign);
169 if (b == NULL)
170 return NULL;
171 Bfree(z);
172 return b;