Project

General

Profile

Actions

Bug #7142

closed

mingw TestFloat#test_round_with_precision failure

Added by h.shirosaki (Hiroshi Shirosaki) over 9 years ago. Updated over 9 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
ruby -v:
ruby 2.0.0dev (2012-10-09 trunk 37127) [i386-mingw32]
Backport:
[ruby-core:47911]

Description

=begin
Trunk ruby on Windows XP x86 with mingw-w64 gcc 4.7.2 has the following test failure.

  1. 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

Actions #1

Updated by Anonymous over 9 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r37168.
Hiroshi, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


win32.h: set floating point precision for pow()

  • include/ruby/win32.h (rb_w32_pow): set floating point precision
    for mingw-w64 x86 pow(). This improves the precision of pow() on
    Windows XP for TestFloat#test_round_with_precision failure.
    [ruby-core:47911] [Bug #7142]
Actions

Also available in: Atom PDF