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

Go to the source code of this file.

Functions

static double ulpdown (double *d)
 
int strtodI (CONST char *s, char **sp, double *dd)
 

Function Documentation

◆ strtodI()

int strtodI ( CONST char *  s,
char **  sp,
double *  dd 
)

Definition at line 60 of file strtodI.c.

62 {
63  static FPI fpi = {53, 1 - 1023 - 53 + 1, 2046 - 1023 - 53 + 1, 1, SI};
64  ULong bits[2], sign;
65  Long exp;
66  int j, k;
67  typedef union
68  {
69  double d[2];
70  ULong L[4];
71  } U2;
72  U2* u;
73 
74  k = strtodg(s, sp, &fpi, &exp, bits);
75  u = (U2*)dd;
76  sign = (k & STRTOG_Neg) ? 0x80000000L : 0;
77  switch(k & STRTOG_Retmask)
78  {
79  case STRTOG_NoNumber:
80  u->d[0] = u->d[1] = 0.;
81  break;
82 
83  case STRTOG_Zero:
84  u->d[0] = u->d[1] = 0.;
85 #ifdef Sudden_Underflow
86  if(k & STRTOG_Inexact)
87  {
88  if(sign)
89  u->L[_0] = 0x80100000L;
90  else
91  u->L[2 + _0] = 0x100000L;
92  }
93  break;
94 #else
95  goto contain;
96 #endif
97 
98  case STRTOG_Denormal:
99  u->L[_1] = bits[0];
100  u->L[_0] = bits[1];
101  goto contain;
102 
103  case STRTOG_Normal:
104  u->L[_1] = bits[0];
105  u->L[_0] = (bits[1] & (unsigned)~0x100000) | (unsigned)((exp + 0x3ff + 52) << 20);
106  contain:
107  j = k & STRTOG_Inexact;
108  if(sign)
109  {
110  u->L[_0] |= sign;
111  j = STRTOG_Inexact - j;
112  }
113  switch(j)
114  {
115  case STRTOG_Inexlo:
116 #ifdef Sudden_Underflow
117  if((u->L[_0] & 0x7ff00000) < 0x3500000)
118  {
119  u->L[2 + _0] = u->L[_0] + 0x3500000;
120  u->L[2 + _1] = u->L[_1];
121  u->d[1] += ulp(u->d[1]);
122  u->L[2 + _0] -= 0x3500000;
123  if(!(u->L[2 + _0] & 0x7ff00000))
124  {
125  u->L[2 + _0] = sign;
126  u->L[2 + _1] = 0;
127  }
128  }
129  else
130 #endif
131  u->d[1] = u->d[0] + ulp(u->d[0]);
132  break;
133  case STRTOG_Inexhi:
134  u->d[1] = u->d[0];
135 #ifdef Sudden_Underflow
136  if((u->L[_0] & 0x7ff00000) < 0x3500000)
137  {
138  u->L[_0] += 0x3500000;
139  u->d[0] -= ulpdown(u->d);
140  u->L[_0] -= 0x3500000;
141  if(!(u->L[_0] & 0x7ff00000))
142  {
143  u->L[_0] = sign;
144  u->L[_1] = 0;
145  }
146  }
147  else
148 #endif
149  u->d[0] -= ulpdown(u->d);
150  break;
151  default:
152  u->d[1] = u->d[0];
153  }
154  break;
155 
156  case STRTOG_Infinite:
157  u->L[_0] = u->L[2 + _0] = sign | 0x7ff00000;
158  u->L[_1] = u->L[2 + _1] = 0;
159  if(k & STRTOG_Inexact)
160  {
161  if(sign)
162  {
163  u->L[2 + _0] = 0xffefffffL;
164  u->L[2 + _1] = 0xffffffffL;
165  }
166  else
167  {
168  u->L[_0] = 0x7fefffffL;
169  u->L[_1] = 0xffffffffL;
170  }
171  }
172  break;
173 
174  case STRTOG_NaN:
175  u->L[0] = u->L[2] = d_QNAN0;
176  u->L[1] = u->L[3] = d_QNAN1;
177  break;
178 
179  case STRTOG_NaNbits:
180  u->L[_0] = u->L[2 + _0] = 0x7ff00000 | sign | bits[1];
181  u->L[_1] = u->L[2 + _1] = bits[0];
182  }
183  return k;
184 }
#define SI
Definition: gdtoaimp.h:635
unsigned Long ULong
Definition: gdtoa.h:41
static double ulpdown(double *d)
Definition: strtodI.c:38
Definition: gdtoa.h:86
double ulp(double x)
Definition: ulp.c:38
#define Long
Definition: gdtoa.h:38
int strtodg(CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits)
Definition: strtodg.c:443

References Long, SI, strtodg(), STRTOG_Denormal, STRTOG_Inexact, STRTOG_Inexhi, STRTOG_Inexlo, STRTOG_Infinite, STRTOG_NaN, STRTOG_NaNbits, STRTOG_Neg, STRTOG_NoNumber, STRTOG_Normal, STRTOG_Retmask, STRTOG_Zero, ulp(), and ulpdown().

◆ ulpdown()

static double ulpdown ( double *  d)
static

Definition at line 38 of file strtodI.c.

40 {
41  double u;
42  ULong* L = (ULong*)d;
43 
44  u = ulp(*d);
45  if(!(L[_1] | (L[_0] & 0xfffff)) && (L[_0] & 0x7ff00000) > 0x00100000)
46  {
47  {
48  u *= 0.5;
49  }
50  }
51  return u;
52 }
unsigned Long ULong
Definition: gdtoa.h:41
double ulp(double x)
Definition: ulp.c:38

References ulp().

Referenced by strtodI().