Embedded Artistry libc
C Standard Library Support for Bare-metal Systems
g_ddfmt.c File Reference
#include "gdtoaimp.h"
#include <string.h>
Include dependency graph for g_ddfmt.c:

Go to the source code of this file.

Functions

char * g_ddfmt (char *buf, double *dd, int ndig, unsigned bufsize)
 

Function Documentation

◆ g_ddfmt()

char* g_ddfmt ( char *  buf,
double *  dd,
int  ndig,
unsigned  bufsize 
)

Definition at line 41 of file g_ddfmt.c.

43 {
44  FPI fpi;
45  char *b, *s, *se;
46  ULong *L, bits0[4], *bits, *zx;
47  int bx, by, decpt, ex, ey, i, j, mode;
48  Bigint *x, *y, *z;
49  double ddx[2];
50 
51  if(bufsize < 10 || bufsize < (unsigned)(ndig + 8))
52  {
53  {
54  return 0;
55  }
56  }
57 
58  L = (ULong*)dd;
59  if((L[_0] & 0x7ff00000L) == 0x7ff00000L)
60  {
61  /* Infinity or NaN */
62  if(L[_0] & 0xfffff || L[_1])
63  {
64  nanret:
65  return strcp(buf, "NaN");
66  }
67  if((L[2 + _0] & 0x7ff00000) == 0x7ff00000)
68  {
69  if(L[2 + _0] & 0xfffff || L[2 + _1])
70  {
71  {
72  goto nanret;
73  }
74  }
75  if((L[_0] ^ L[2 + _0]) & 0x80000000L)
76  {
77  {
78  goto nanret; /* Infinity - Infinity */
79  }
80  }
81  }
82  infret:
83  b = buf;
84  if(L[_0] & 0x80000000L)
85  {
86  {
87  *b++ = '-';
88  }
89  }
90  return strcp(b, "Infinity");
91  }
92  if((L[2 + _0] & 0x7ff00000) == 0x7ff00000)
93  {
94  L += 2;
95  if(L[_0] & 0xfffff || L[_1])
96  {
97  {
98  goto nanret;
99  }
100  }
101  goto infret;
102  }
103  if(dd[0] + dd[1] == 0.)
104  {
105  b = buf;
106 #ifndef IGNORE_ZERO_SIGN
107  if(L[_0] & L[2 + _0] & 0x80000000L)
108  {
109  {
110  *b++ = '-';
111  }
112  }
113 #endif
114  *b++ = '0';
115  *b = 0;
116  return b;
117  }
118  if((L[_0] & 0x7ff00000L) < (L[2 + _0] & 0x7ff00000L))
119  {
120  ddx[1] = dd[0];
121  ddx[0] = dd[1];
122  dd = ddx;
123  L = (ULong*)dd;
124  }
125  z = d2b(dd[0], &ex, &bx);
126  if(dd[1] == 0.)
127  {
128  {
129  goto no_y;
130  }
131  }
132  x = z;
133  y = d2b(dd[1], &ey, &by);
134  if((i = ex - ey) != 0)
135  {
136  if(i > 0)
137  {
138  x = lshift(x, i);
139  ex = ey;
140  }
141  else
142  {
143  {
144  y = lshift(y, -i);
145  }
146  }
147  }
148  if((L[_0] ^ L[2 + _0]) & 0x80000000L)
149  {
150  z = diff(x, y);
151  if(L[_0] & 0x80000000L)
152  {
153  {
154  z->sign = 1 - z->sign;
155  }
156  }
157  }
158  else
159  {
160  z = sum(x, y);
161  if(L[_0] & 0x80000000L)
162  {
163  {
164  z->sign = 1;
165  }
166  }
167  }
168  Bfree(x);
169  Bfree(y);
170 no_y:
171  bits = zx = z->x;
172  for(i = 0; !*zx; zx++)
173  {
174  {
175  i += 32;
176  }
177  }
178  i += lo0bits(zx);
179  if(i)
180  {
181  rshift(z, i);
182  ex += i;
183  }
184  fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds - 1]);
185  if(fpi.nbits < 106)
186  {
187  fpi.nbits = 106;
188  if(j < 3)
189  {
190  for(i = 0; i <= j; i++)
191  {
192  bits0[i] = bits[i];
193  }
194  while(i < 4)
195  {
196  bits0[i++] = 0;
197  }
198  bits = bits0;
199  }
200  }
201  mode = 2;
202  if(ndig <= 0)
203  {
204  if(bufsize < (unsigned)(fpi.nbits * .301029995664) + 10)
205  {
206  Bfree(z);
207  return 0;
208  }
209  mode = 0;
210  }
211  fpi.emin = 1 - 1023 - 53 + 1;
212  fpi.emax = 2046 - 1023 - 106 + 1;
213  fpi.rounding = FPI_Round_near;
214  fpi.sudden_underflow = 0;
215  i = STRTOG_Normal;
216  s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
217  b = g__fmt(buf, s, se, decpt, (ULong)z->sign);
218  Bfree(z);
219  return b;
220 }
int emax
Definition: gdtoa.h:90
ULong x[1]
Definition: gdtoaimp.h:488
int wds
Definition: gdtoaimp.h:487
char * g__fmt(char *b, char *s, const char *se, int decpt, ULong sign)
Definition: g__fmt.c:46
int sudden_underflow
Definition: gdtoa.h:92
Bigint * lshift(Bigint *b, int k)
Definition: misc.c:495
char * gdtoa(FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)
Definition: gdtoa.c:130
int sign
Definition: gdtoaimp.h:487
Bigint * diff(Bigint *a, Bigint *b)
Definition: misc.c:617
int rounding
Definition: gdtoa.h:91
int nbits
Definition: gdtoa.h:88
int lo0bits(ULong *y)
Definition: misc.c:108
#define hi0bits(x)
Definition: gdtoaimp.h:525
Bigint * d2b(double d, int *e, int *bits)
Definition: misc.c:798
unsigned Long ULong
Definition: gdtoa.h:41
void Bfree(Bigint *v)
Definition: misc.c:92
int emin
Definition: gdtoa.h:89
void rshift(Bigint *b, int k)
Definition: gmisc.c:39
Definition: gdtoa.h:86
Bigint * sum(Bigint *a, Bigint *b)
Definition: sum.c:39
#define strcp
Definition: gdtoaimp.h:541

References Bfree(), d2b(), diff(), FPI::emax, FPI::emin, FPI_Round_near, g__fmt(), gdtoa(), hi0bits, lo0bits(), lshift(), FPI::nbits, FPI::rounding, rshift(), Bigint::sign, strcp, STRTOG_Normal, FPI::sudden_underflow, sum(), Bigint::wds, and Bigint::x.