mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
fmt_fp.c: fix float formatting on 32-bit x87 FPU
The power-of-10 normalization loop can leave f >= 10.0 when x87 extended precision (80-bit) produces different rounding than 64-bit SSE2. This caused garbled output (e.g. "0.0,6.04*2000001e+19" instead of "1.0e+20") because negative digit values were added to '0'. Add a correction step after the loop, and clamp extracted digits to [0,9] for robustness. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
+9
-1
@@ -222,6 +222,12 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch
|
||||
f *= *neg_pow;
|
||||
}
|
||||
}
|
||||
// correct for FP rounding errors in the power-of-10 loop
|
||||
// (e.g. x87 extended precision can leave f >= 10.0)
|
||||
if (f >= 10.0) {
|
||||
f *= 0.1;
|
||||
e++;
|
||||
}
|
||||
|
||||
// If the user specified fixed format (fmt == 'f') and e makes the
|
||||
// number too big to fit into the available buffer, then we'll
|
||||
@@ -284,7 +290,9 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch
|
||||
|
||||
// Print the digits of the mantissa
|
||||
for (int i = 0; i < num_digits; i++,dec--) {
|
||||
int8_t d = (int8_t)((int)f)%10;
|
||||
int8_t d = (int8_t)f;
|
||||
if (d > 9) d = 9;
|
||||
if (d < 0) d = 0;
|
||||
*s++ = '0' + d;
|
||||
if (dec == 0 && (prec > 0 || alt_form)) {
|
||||
*s++ = '.';
|
||||
|
||||
Reference in New Issue
Block a user