summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--test/ruby/test_sprintf.rb2
-rw-r--r--util.c7
3 files changed, 16 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index ee64ca9ece..f86d940ea8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Tue Nov 9 10:44:19 2010 NARUSE, Yui <naruse@ruby-lang.org>
+
+ * util.c (ruby_strtod): this code uses FPU's rounding system.
+ But x86's FPU calculates double precision floating-point
+ numbers in 80bit precision, so it fails to round the value.
+ So ensure the value is assigned a variable. [ruby-dev:42551]
+ see also [ruby-math:00802]
+ http://www.shudo.net/java-grandprix99/strictfp/
+
Tue Nov 9 07:30:15 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
* error.c (rb_syserr_new): new function to make SystemCallError
diff --git a/test/ruby/test_sprintf.rb b/test/ruby/test_sprintf.rb
index b82cbc4b90..b918ceba72 100644
--- a/test/ruby/test_sprintf.rb
+++ b/test/ruby/test_sprintf.rb
@@ -190,6 +190,8 @@ class TestSprintf < Test::Unit::TestCase
sprintf("%20.0f", 36893488147419107329.0))
assert_equal(" Inf", sprintf("% 0e", 1.0/0.0), "moved from btest/knownbug")
assert_equal(" -0.", sprintf("%#10.0f", -0.5), "[ruby-dev:42552]")
+ assert_equal("0x1.p+2", sprintf('%.0a', Float('0x1.fp+1')), "[ruby-dev:42551]")
+ assert_equal("-0x1.0p+2", sprintf('%.0a', Float('-0x1.ffp+1')), "[ruby-dev:42551]")
end
def test_float_hex
diff --git a/util.c b/util.c
index 0b69b6cfb7..bc307e4636 100644
--- a/util.c
+++ b/util.c
@@ -4014,10 +4014,13 @@ ruby_hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign,
/* Round to the desired number of digits. */
if (SIGFIGS > ndigits && ndigits > 0) {
float redux = 1.0f;
+ volatile double d;
int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG;
dexp_set(u, offset);
- u.d += redux;
- u.d -= redux;
+ d = u.d;
+ d += redux;
+ d -= redux;
+ u.d = d;
*decpt += dexp_get(u) - offset;
}