65
65
#define FLT_EXP_MASK 0x7F800000
66
66
#define FLT_MAN_MASK 0x007FFFFF
67
67
68
- union floatbits {
69
- float f ;
70
- uint32_t u ;
71
- };
72
68
static inline int fp_signbit (float x ) {
73
- union floatbits fb = {x };
74
- return fb .u & FLT_SIGN_MASK ;
69
+ mp_float_union_t fb = {x };
70
+ return fb .i & FLT_SIGN_MASK ;
75
71
}
76
72
#define fp_isnan (x ) isnan(x)
77
73
#define fp_isinf (x ) isinf(x)
78
74
static inline int fp_iszero (float x ) {
79
- union floatbits fb = {x };
80
- return fb .u == 0 ;
75
+ mp_float_union_t fb = {x };
76
+ return fb .i == 0 ;
81
77
}
82
78
static inline int fp_isless1 (float x ) {
83
- union floatbits fb = {x };
84
- return fb .u < 0x3f800000 ;
79
+ mp_float_union_t fb = {x };
80
+ return fb .i < 0x3f800000 ;
85
81
}
86
82
87
83
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
@@ -99,28 +95,6 @@ static inline int fp_isless1(float x) {
99
95
100
96
#endif // MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT/DOUBLE
101
97
102
- static inline int fp_ge_eps (FPTYPE x , FPTYPE y ) {
103
- mp_float_union_t fb_y = {y };
104
- // Back off 2 eps.
105
- // This is valid for almost all values, but in practice
106
- // it's only used when y = 1eX for X>=0.
107
- fb_y .i -= 2 ;
108
- return x >= fb_y .f ;
109
- }
110
-
111
- static const FPTYPE g_pos_pow [] = {
112
- #if FPDECEXP > 32
113
- MICROPY_FLOAT_CONST (1e256 ), MICROPY_FLOAT_CONST (1e128 ), MICROPY_FLOAT_CONST (1e64 ),
114
- #endif
115
- MICROPY_FLOAT_CONST (1e32 ), MICROPY_FLOAT_CONST (1e16 ), MICROPY_FLOAT_CONST (1e8 ), MICROPY_FLOAT_CONST (1e4 ), MICROPY_FLOAT_CONST (1e2 ), MICROPY_FLOAT_CONST (1e1 )
116
- };
117
- static const FPTYPE g_neg_pow [] = {
118
- #if FPDECEXP > 32
119
- MICROPY_FLOAT_CONST (1e-256 ), MICROPY_FLOAT_CONST (1e-128 ), MICROPY_FLOAT_CONST (1e-64 ),
120
- #endif
121
- MICROPY_FLOAT_CONST (1e-32 ), MICROPY_FLOAT_CONST (1e-16 ), MICROPY_FLOAT_CONST (1e-8 ), MICROPY_FLOAT_CONST (1e-4 ), MICROPY_FLOAT_CONST (1e-2 ), MICROPY_FLOAT_CONST (1e-1 )
122
- };
123
-
124
98
int mp_format_float (FPTYPE f , char * buf , size_t buf_size , char fmt , int prec , char sign ) {
125
99
126
100
char * s = buf ;
@@ -177,14 +151,20 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
177
151
if (fmt == 'g' && prec == 0 ) {
178
152
prec = 1 ;
179
153
}
180
- int e , e1 ;
154
+ int e ;
181
155
int dec = 0 ;
182
156
char e_sign = '\0' ;
183
157
int num_digits = 0 ;
184
- const FPTYPE * pos_pow = g_pos_pow ;
185
- const FPTYPE * neg_pow = g_neg_pow ;
186
158
int signed_e = 0 ;
187
159
160
+ // Approximate (?) power of 10 exponent from binary exponent.
161
+ // It seems to be right all the time, but to be sure, we try several values
162
+ // of 10 from one smaller.
163
+ mp_float_union_t fb = {f };
164
+ FPTYPE e_float = (fb .p .exp - MP_FLOAT_EXP_OFFSET ) *
165
+ FPCONST (0.3010299956639812 ); // 1/log2(10).
166
+ int e_guess = (int )((FPCONST (0.5 ) * (1 - 2 * (e_float < 0 ))) + e_float );
167
+
188
168
if (fp_iszero (f )) {
189
169
e = 0 ;
190
170
if (fmt == 'f' ) {
@@ -203,24 +183,25 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
203
183
}
204
184
}
205
185
} else if (fp_isless1 (f )) {
206
- FPTYPE f_mod = f ;
186
+ FPTYPE f_entry = f ; // Save f in case we go to 'f' format.
207
187
// Build negative exponent
208
- for ( e = 0 , e1 = FPDECEXP ; e1 ; e1 >>= 1 , pos_pow ++ , neg_pow ++ ) {
209
- if ( * neg_pow > f_mod ) {
210
- e += e1 ;
211
- f_mod *= * pos_pow ;
212
- }
188
+ e = - e_guess - 1 ;
189
+ FPTYPE u_base = MICROPY_FLOAT_C_FUN ( pow )( 10 , - e );
190
+ while ( u_base > f ) {
191
+ ++ e ;
192
+ u_base = MICROPY_FLOAT_C_FUN ( pow )( 10 , - e );
213
193
}
194
+ f *= MICROPY_FLOAT_C_FUN (pow )(10 , e );
214
195
215
196
char e_sign_char = '-' ;
216
- if (fp_isless1 (f_mod ) && f_mod >= FPROUND_TO_ONE ) {
217
- f_mod = FPCONST (1.0 );
197
+ if (fp_isless1 (f ) && f >= FPROUND_TO_ONE ) {
198
+ f = FPCONST (1.0 );
218
199
if (e == 0 ) {
219
200
e_sign_char = '+' ;
220
201
}
221
- } else if (fp_isless1 (f_mod )) {
202
+ } else if (fp_isless1 (f )) {
222
203
e ++ ;
223
- f_mod *= FPCONST (10.0 );
204
+ f *= FPCONST (10.0 );
224
205
}
225
206
226
207
// If the user specified 'g' format, and e is <= 4, then we'll switch
@@ -241,6 +222,7 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
241
222
242
223
num_digits = prec ;
243
224
signed_e = 0 ;
225
+ f = f_entry ;
244
226
++ num_digits ;
245
227
} else {
246
228
// For e & g formats, we'll be printing the exponent, so set the
@@ -262,19 +244,11 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
262
244
// scaling it. Instead, we find the product of powers of 10
263
245
// that is not greater than it, and use that to start the
264
246
// mantissa.
265
- FPTYPE u_base = FPCONST (1.0 );
266
- for (e = 0 , e1 = FPDECEXP ; e1 ; e1 >>= 1 , pos_pow ++ ) {
267
- FPTYPE next_u = u_base * * pos_pow ;
268
- // fp_ge_eps performs "f >= (next_u - 2eps)" so that if, for
269
- // numerical reasons, f is very close to a power of ten but
270
- // not strictly equal, we still treat it as that power of 10.
271
- // The comparison was failing for maybe 10% of 1eX values, but
272
- // although rounding fixed many of them, there were still some
273
- // rendering as 9.99999998e(X-1).
274
- if (fp_ge_eps (f , next_u )) {
275
- u_base = next_u ;
276
- e += e1 ;
277
- }
247
+ e = e_guess - 1 ;
248
+ FPTYPE next_u = MICROPY_FLOAT_C_FUN (pow )(10 , e + 1 );
249
+ while (f >= next_u ) {
250
+ ++ e ;
251
+ next_u = MICROPY_FLOAT_C_FUN (pow )(10 , e + 1 );
278
252
}
279
253
280
254
// If the user specified fixed format (fmt == 'f') and e makes the
@@ -341,39 +315,16 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
341
315
num_digits = prec ;
342
316
}
343
317
344
- if (signed_e < 0 ) {
345
- // The algorithm below treats numbers smaller than 1 by scaling them
346
- // repeatedly by 10 to bring the new digit to the top. Our input number
347
- // was smaller than 1, so scale it up to be 1 <= f < 10.
348
- FPTYPE u_base = FPCONST (1.0 );
349
- const FPTYPE * pow_u = g_pos_pow ;
350
- for (int m = FPDECEXP ; m ; m >>= 1 , pow_u ++ ) {
351
- if (m & e ) {
352
- u_base *= * pow_u ;
353
- }
354
- }
355
- f *= u_base ;
356
- }
357
-
358
318
int d = 0 ;
359
319
int num_digits_left = num_digits ;
360
320
for (int digit_index = signed_e ; num_digits_left >= 0 ; -- digit_index ) {
361
321
FPTYPE u_base = FPCONST (1.0 );
362
322
if (digit_index > 0 ) {
363
323
// Generate 10^digit_index for positive digit_index.
364
- const FPTYPE * pow_u = g_pos_pow ;
365
- int target_index = digit_index ;
366
- for (int m = FPDECEXP ; m ; m >>= 1 , pow_u ++ ) {
367
- if (m & target_index ) {
368
- u_base *= * pow_u ;
369
- }
370
- }
324
+ u_base = MICROPY_FLOAT_C_FUN (pow )(10 , digit_index );
371
325
}
372
326
for (d = 0 ; d < 9 ; ++ d ) {
373
- // This is essentially "if (f < u_base)", but with 2eps margin
374
- // so that if f is just a tiny bit smaller, we treat it as
375
- // equal (and accept the additional digit value).
376
- if (!fp_ge_eps (f , u_base )) {
327
+ if (f < u_base ) {
377
328
break ;
378
329
}
379
330
f -= u_base ;
@@ -390,7 +341,7 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
390
341
-- dec ;
391
342
-- num_digits_left ;
392
343
if (digit_index <= 0 ) {
393
- // Once we get below 1.0, we scale up f instead of calculting
344
+ // Once we get below 1.0, we scale up f instead of calculating
394
345
// negative powers of 10 in u_base. This provides better
395
346
// renditions of exact decimals like 1/16 etc.
396
347
f *= FPCONST (10.0 );
0 commit comments