Backport #1397
closedto_f of rational
Description
=begin
irb
irb(main):001:0> require "rational"
=> true
irb(main):002:0> a=10**309
=> 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
irb(main):003:0> b=a+1
=> 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
irb(main):004:0> c=Rational(a,b)
=> Rational(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001)
irb(main):005:0> c.to_f
/usr/local/lib/ruby/1.8/rational.rb:390: warning: Bignum out of Float range
/usr/local/lib/ruby/1.8/rational.rb:390: warning: Bignum out of Float range
=> NaN
=end
Updated by bk1 (Karl Brodowsky) over 15 years ago
=begin
expected result would be 1.0
This bug has been reported already in rubyforge with [#25582]
=end
Updated by bk1 (Karl Brodowsky) over 15 years ago
=begin
A fix for this bug might be along the following line, but this might still cause rounding errors in case only one of numerator and denominator is above Float::MAX and the other one is pretty small and would loose significant digits.
class Rational
FLOAT_MAX_I = Float::MAX.to_i
def to_f
numerator = @numerator
denominator = @denominator
sign = numerator <=> 0
if (sign.zero?)
return 0.0
elsif sign < 0
numerator = -numerator
end
while numerator >= FLOAT_MAX_I || denominator >=
FLOAT_MAX_I do
numerator >>= 8
denominator >>= 8
if (denominator == 0)
raise ZeroDivisionError, "denominator too close to
zero: #{@numerator}/{@denominator}"
elsif numerator == 0
return 0.0
end
end
return numerator.to_f / denominator.to_f
end
end
=end
Updated by tadf (tadayoshi funaba) about 15 years ago
- Assignee set to keiju (Keiju Ishitsuka)
=begin
=end
Updated by shyouhei (Shyouhei Urabe) over 14 years ago
- Status changed from Closed to Assigned
- Assignee changed from keiju (Keiju Ishitsuka) to shyouhei (Shyouhei Urabe)
=begin
=end
Updated by shyouhei (Shyouhei Urabe) over 14 years ago
- Status changed from Assigned to Closed
- % Done changed from 0 to 100
=begin
This issue was solved with changeset r28205.
Karl, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
=end