Issue #7142 has been reported by h.shirosaki (Hiroshi Shirosaki).

----------------------------------------
Bug #7142: mingw TestFloat#test_round_with_precision failure
https://bugs.ruby-lang.org/issues/7142

Author: h.shirosaki (Hiroshi Shirosaki)
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2012-10-09 trunk 37127) [i386-mingw32]


=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



-- 
http://bugs.ruby-lang.org/