Project

General

Profile

Bug #2121

Updated by marcandre (Marc-Andre Lafortune) over 7 years ago

=begin 
  
  I've known this for a while, but only now realized this is actually a terrible bug. 
 
  The mathn library replaces Fixnum#/ and Bignum#/ causing them to return a different value. When the result of a division is not an integral value, the default versions will return 0. I can think of many algorithms that would use this expectation, and most other languages will not upconvert integral numeric types to floating-point or fractional types without explicit consent by the programmer. 
 
  When requiring 'mathn', Fixnum#/ and Bignum#/ are replaced with versions that return a fractional value ('quo') causing a core math operator to return not just a different type, but *a different value*. 
 
  No core library should be allowed to modify the return value of core numeric operators, or else those operators are worthless; you can't rely on them to return a specific value *ever* since someone else could require 'mathn' or 'rational'. 
 
  Note also that 'rational' destroys Fixnum#quo and Bignum#quo. This is also a bug that should be fixed, though it is less dangerous because they're not commonly-used operators. 
 
  The following code should not fail; Fixnum#/ should never return a value of a different magnitude based on which libraries are loaded: 
 
  {{{ 
  require 'test/unit' 
 
  class TestFixnumMath < Test::Unit::TestCase 
    # 0 to ensure it runs first, for illustration purposes 
    def test_0_without_mathn 
      assert_equal 0, 1/3 
    end 
 
    def test_with_mathn 
      require 'mathn' 
      assert_equal 0, 1/3 
    end 
  end 
  }}} 
 
  But it does fail: 
 
  {{{ 
  ~/projects/jruby ➔ ruby test_fixnum_math.rb  
  Loaded suite test_fixnum_math 
  Started 
  .F 
  Finished in 0.016003 seconds. 
 
    1) Failure: 
  test_with_mathn(TestFixnumMath) [test_fixnum_math.rb:11]: 
  <0> expected but was 
  <1/3>. 
 
  2 tests, 2 assertions, 1 failures, 0 errors 
  }}} 
 
 =end 
 

Back