diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-02-17 07:57:12 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-02-17 07:57:12 +0900 |
| commit | 09080fd2eeb38379d5059ce677451472b9904290 (patch) | |
| tree | 46042c5bec050902e99b2afa80065cdde51e9745 /src/numeric.c | |
| parent | 41a77111eaeb1265114e47019ce85c98fe12627e (diff) | |
| parent | db80a9a2ceeb75af23a3588f68c9e379c580d3d2 (diff) | |
| download | mruby-09080fd2eeb38379d5059ce677451472b9904290.tar.gz mruby-09080fd2eeb38379d5059ce677451472b9904290.zip | |
Merge pull request #1714 from h2so5/f2s
fix mrb_flo_to_str() exponent problem
Diffstat (limited to 'src/numeric.c')
| -rw-r--r-- | src/numeric.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/src/numeric.c b/src/numeric.c index 29241d813..9fc604547 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -130,9 +130,9 @@ mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit) } else { int digit; - int m; + int m = 0; int exp; - int e = 0; + mrb_bool e = FALSE; char s[48]; char *c = &s[0]; @@ -141,39 +141,41 @@ mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit) *(c++) = '-'; } - exp = (int)log10(n); + exp = (n > 1) ? floor(log10(n)) : -ceil(-log10(n)); - if ((exp < 0 ? -exp : exp) > max_digit) { + if ((exp < 0 ? -exp : exp) >= max_digit) { /* exponent representation */ - e = 1; - m = exp; - if (m < 0) { - m -= 1; - } - n = n / pow(10.0, m); - m = 0; + e = TRUE; + n = n / pow(10.0, exp); } else { /* un-exponent (normal) representation */ - m = exp; - if (m < 0) { - m = 0; + if (exp > 0) { + m = exp; } } /* puts digits */ while (max_digit >= 0) { mrb_float weight = pow(10.0, m); - digit = (int)floor(n / weight + FLT_EPSILON); + mrb_float fdigit = n / weight; + if (m < -1 && fdigit < FLT_EPSILON) { + if (e || exp > 0 || m <= -abs(exp)) { + break; + } + } + digit = (int)floor(fdigit + FLT_EPSILON); + if (m == 0 && digit > 9) { + n /= 10.0; + exp++; + continue; + } *(c++) = '0' + digit; n -= (digit * weight); max_digit--; if (m-- == 0) { *(c++) = '.'; } - else if (m < -1 && n < FLT_EPSILON) { - break; - } } if (e) { |
