Bug #7142
closedmingw TestFloat#test_round_with_precision failure
Description
=begin
Trunk ruby on Windows XP x86 with mingw-w64 gcc 4.7.2 has the following test failure.
- Failure:
test_round_with_precision(TestFloat) [C:/Users/Worker/Jenkins/workspace/ruby-trunk-x86-build/test/ruby/test_float.rb:389]:
<1.0e-300> expected but was
<9.999999999999994e-301>.
I get the failure with make test-all TESTS="-qv -n test_round_with_precision"
.
But it's strange that I don't get the failure with make test-all TESTS="-qv ruby/test_float.rb"
.
And This failure doesn't occur on Win7.
Floating-point precision seems to be changed for some reason. Mingw-w64 has own pow() implementation and the precision of pow(10, ndigits) is not proper.
I found calling (({_controlfp(_PC_64, _MCW_PC)})) before pow() improves precision and fixes this failure.
I'll commit this patch if there is no other better fix.
Index: include/ruby/win32.h¶
--- include/ruby/win32.h (revision 37136)
+++ include/ruby/win32.h (working copy)
@@ -764,7 +764,7 @@
} /* extern "C" { */
#endif
-#ifdef MINGW64
+#if defined(MINGW64)
/*
- Use powl() instead of broken pow() of x86_64-w64-mingw32.
- This workaround will fix test failures in test_bignum.rb,
@@ -775,6 +775,24 @@
{
return powl(x, y);
}
+#elif defined(__MINGW64_VERSION_MAJOR)
+/*
-
- Set floating point precision for pow() of mingw-w64 x86.
-
- With default precision the result is not proper on WinXP.
- */
+static inline double
+rb_w32_pow(double x, double y)
+{ - double r;
- unsigned int default_control = _controlfp(0, 0);
- _controlfp(_PC_64, _MCW_PC);
- r = pow(x, y);
- /* Restore setting */
- _controlfp(default_control, _MCW_PC);
- return r;
+}
+#endif
+#if defined(__MINGW64_VERSION_MAJOR) || defined(MINGW64)
#define pow rb_w32_pow
#endif
=end