mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Fix Rational#==
This commit is contained in:
@@ -3,7 +3,6 @@ MRuby::Gem::Specification.new('mruby-rational') do |spec|
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'Rational class'
|
||||
|
||||
spec.add_dependency 'mruby-metaprog', core: 'mruby-metaprog'
|
||||
spec.add_dependency 'mruby-object-ext', core: 'mruby-object-ext'
|
||||
spec.add_dependency 'mruby-numeric-ext', core: 'mruby-numeric-ext'
|
||||
end
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
class Rational < Numeric
|
||||
# Override #<, #<=, #>, #>= in Numeric
|
||||
prepend Comparable
|
||||
|
||||
def initialize(numerator = 0, denominator = 1)
|
||||
@numerator = numerator
|
||||
@denominator = denominator
|
||||
@@ -66,6 +69,24 @@ class Rational < Numeric
|
||||
end
|
||||
end
|
||||
|
||||
def <=>(rhs)
|
||||
case rhs
|
||||
when Fixnum
|
||||
return @numerator <=> rhs if @denominator == 1
|
||||
rhs = Rational(rhs)
|
||||
when Float
|
||||
return to_f <=> rhs
|
||||
end
|
||||
case rhs
|
||||
when Rational
|
||||
(@numerator * rhs.denominator - @denominator * rhs.numerator) <=> 0
|
||||
when Numeric
|
||||
return rhs <=> self
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def negative?
|
||||
numerator.negative?
|
||||
end
|
||||
@@ -86,17 +107,17 @@ def Rational(numerator = 0, denominator = 1)
|
||||
end
|
||||
|
||||
[Fixnum, Float].each do |cls|
|
||||
[:+, :-, :*, :/, :==].each do |op|
|
||||
[:+, :-, :*, :/, :<=>, :==, :<, :<=, :>, :>=].each do |op|
|
||||
cls.instance_exec do
|
||||
original_operator_name = "__original_operator_#{op}_rational"
|
||||
alias_method original_operator_name, op
|
||||
define_method op do |rhs|
|
||||
if rhs.is_a? Rational
|
||||
Rational(self).send(op, rhs)
|
||||
Rational(self).__send__(op, rhs)
|
||||
else
|
||||
send(original_operator_name, rhs)
|
||||
__send__(original_operator_name, rhs)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
def assert_rational(real, exp)
|
||||
assert_float real.numerator, exp.numerator
|
||||
assert_float real.numerator, exp.numerator
|
||||
assert_float real.denominator, exp.denominator
|
||||
end
|
||||
|
||||
def assert_equal_rational(exp, r1, r2)
|
||||
if exp
|
||||
assert_operator(r1, :==, r2)
|
||||
assert_not_operator(r1, :!=, r2)
|
||||
else
|
||||
assert_not_operator(r1, :==, r2)
|
||||
assert_operator(r1, :!=, r2)
|
||||
end
|
||||
end
|
||||
|
||||
assert 'Rational' do
|
||||
r = 5r
|
||||
assert_equal Rational, r.class
|
||||
@@ -54,4 +64,39 @@ assert 'Rational#/' do
|
||||
assert_rational Rational(-2, 9) / Rational(-9, 2), Rational(4, 81)
|
||||
assert_rational Rational(9, 8) / 4, Rational(9, 32)
|
||||
assert_float Rational(20, 9) / 9.8, 0.22675736961451246
|
||||
end
|
||||
end
|
||||
|
||||
assert 'Rational#==, Rational#!=' do
|
||||
assert_equal_rational(true, Rational(1,1), Rational(1))
|
||||
assert_equal_rational(true, Rational(-1,1), -1r)
|
||||
assert_equal_rational(true, Rational(13,4), 3.25)
|
||||
assert_equal_rational(true, Rational(13,3.25), Rational(4,1))
|
||||
assert_equal_rational(true, Rational(-3,-4), Rational(3,4))
|
||||
assert_equal_rational(true, Rational(-4,5), Rational(4,-5))
|
||||
assert_equal_rational(true, Rational(4,2), 2)
|
||||
assert_equal_rational(true, Rational(-4,2), -2)
|
||||
assert_equal_rational(true, Rational(4,-2), -2)
|
||||
assert_equal_rational(true, Rational(4,2), 2.0)
|
||||
assert_equal_rational(true, Rational(-4,2), -2.0)
|
||||
assert_equal_rational(true, Rational(4,-2), -2.0)
|
||||
assert_equal_rational(true, Rational(8,6), Rational(4,3))
|
||||
assert_equal_rational(false, Rational(13,4), 3)
|
||||
assert_equal_rational(false, Rational(13,4), 3.3)
|
||||
assert_equal_rational(false, Rational(2,1), 1r)
|
||||
assert_equal_rational(false, Rational(1), nil)
|
||||
assert_equal_rational(false, Rational(1), '')
|
||||
end
|
||||
|
||||
assert 'Fixnum#==(Rational), Fixnum#!=(Rational)' do
|
||||
assert_equal_rational(true, 2, Rational(4,2))
|
||||
assert_equal_rational(true, -2, Rational(-4,2))
|
||||
assert_equal_rational(true, -2, Rational(4,-2))
|
||||
assert_equal_rational(false, 3, Rational(13,4))
|
||||
end
|
||||
|
||||
assert 'Float#==(Rational), Float#!=(Rational)' do
|
||||
assert_equal_rational(true, 2.0, Rational(4,2))
|
||||
assert_equal_rational(true, -2.0, Rational(-4,2))
|
||||
assert_equal_rational(true, -2.0, Rational(4,-2))
|
||||
assert_equal_rational(false, 3.3, Rational(13,4))
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user