Skip to content

Commit 5232f70

Browse files
committed
py/formatfloat: Fix exact int formatting on 32-bit mingw.
When compiler optimizations are enabled on the mingw version of gcc, we are getting failing tests because of rounding issues, for example: print(float("1e24")) would print 9.999999999999999e+23 instead of 1e+24 We can work around the issue by using `powl()` instead of `pow()` in `mp_format_float()` on affected targets. Signed-off-by: David Lechner <david@pybricks.com>
1 parent bb77c1d commit 5232f70

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

py/formatfloat.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ static inline int fp_expval(FPTYPE x) {
9898
return (int)((fb.i >> MP_FLOAT_FRAC_BITS) & (~(0xFFFFFFFF << MP_FLOAT_EXP_BITS))) - MP_FLOAT_EXP_OFFSET;
9999
}
100100

101+
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE && defined(__GNUC__) && defined(__MINGW32__) && defined(__i386__)
102+
// When optimizations are enabled using mingw's gcc, it breaks pow(double, double)
103+
// and gives wrong results.
104+
#define POW powl
105+
#else
106+
#define POW MICROPY_FLOAT_C_FUN(pow)
107+
#endif
108+
101109
int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, char sign) {
102110

103111
char *s = buf;
@@ -184,10 +192,10 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
184192
FPTYPE f_entry = f; // Save f in case we go to 'f' format.
185193
// Build negative exponent
186194
e = -e_guess;
187-
FPTYPE u_base = MICROPY_FLOAT_C_FUN(pow)(10, -e);
195+
FPTYPE u_base = POW(10, -e);
188196
while (u_base > f) {
189197
++e;
190-
u_base = MICROPY_FLOAT_C_FUN(pow)(10, -e);
198+
u_base = POW(10, -e);
191199
}
192200
// Normalize out the inferred unit. Use divide because
193201
// pow(10, e) * pow(10, -e) is slightly < 1 for some e in float32
@@ -235,10 +243,10 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
235243
// that is not greater than it, and use that to start the
236244
// mantissa.
237245
e = e_guess;
238-
FPTYPE next_u = MICROPY_FLOAT_C_FUN(pow)(10, e + 1);
246+
FPTYPE next_u = POW(10, e + 1);
239247
while (f >= next_u) {
240248
++e;
241-
next_u = MICROPY_FLOAT_C_FUN(pow)(10, e + 1);
249+
next_u = POW(10, e + 1);
242250
}
243251

244252
// If the user specified fixed format (fmt == 'f') and e makes the
@@ -310,7 +318,7 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
310318
FPTYPE u_base = FPCONST(1.0);
311319
if (digit_index > 0) {
312320
// Generate 10^digit_index for positive digit_index.
313-
u_base = MICROPY_FLOAT_C_FUN(pow)(10, digit_index);
321+
u_base = POW(10, digit_index);
314322
}
315323
for (d = 0; d < 9; ++d) {
316324
if (f < u_base) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy