diff options
| author | Ukrainskiy Sergey <[email protected]> | 2018-09-09 11:57:16 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-05-15 16:57:21 +0900 |
| commit | d67d2ae8e88b93536e71dfa41a90721ce351da7c (patch) | |
| tree | 25b8e534e0864817bf05dee8022004fa04e22fc7 /mrbgems/mruby-rational/mrblib/rational.rb | |
| parent | 79c3335e8d22ec76340b3028a7bbc658d631b17c (diff) | |
| download | mruby-d67d2ae8e88b93536e71dfa41a90721ce351da7c.tar.gz mruby-d67d2ae8e88b93536e71dfa41a90721ce351da7c.zip | |
Basic implementation of Complex and Rational classes
Diffstat (limited to 'mrbgems/mruby-rational/mrblib/rational.rb')
| -rw-r--r-- | mrbgems/mruby-rational/mrblib/rational.rb | 100 |
1 files changed, 72 insertions, 28 deletions
diff --git a/mrbgems/mruby-rational/mrblib/rational.rb b/mrbgems/mruby-rational/mrblib/rational.rb index 457c0488a..ffadd55eb 100644 --- a/mrbgems/mruby-rational/mrblib/rational.rb +++ b/mrbgems/mruby-rational/mrblib/rational.rb @@ -2,45 +2,89 @@ class Rational < Numeric def initialize(numerator = 0, denominator = 1) @numerator = numerator @denominator = denominator + + _simplify end - attr_reader :numerator, :denominator -end + def inspect + "(#{to_s})" + end -def Rational(numerator = 0, denominator = 1) - Rational.new(numerator, denominator) -end + def to_s + "#{numerator}/#{denominator}" + end -module ForwardOperatorToRational - def __forward_operator_to_rational(op, &b) - original_operator_name = "__original_operator_#{op}_rational" - alias_method original_operator_name, op - define_method op do |rhs| - if rhs.is_a? Rational - Rational.new(self).send(op, rhs) - else - send(original_operator_name, rhs) - end + def *(rhs) + if rhs.is_a? Rational + Rational(numerator * rhs.numerator, denominator * rhs.denominator) + elsif rhs.is_a? Integer + Rational(numerator * rhs, denominator) + elsif rhs.is_a? Numeric + numerator * rhs / denominator + end + end + + def +(rhs) + if rhs.is_a? Rational + Rational(numerator * rhs.denominator + rhs.numerator * denominator, denominator * rhs.denominator) + elsif rhs.is_a? Integer + Rational(numerator + rhs * denominator, denominator) + elsif rhs.is_a? Numeric + (numerator + rhs * denominator) / denominator + end + end + + def -(rhs) + if rhs.is_a? Rational + Rational(numerator * rhs.denominator - rhs.numerator * denominator, denominator * rhs.denominator) + elsif rhs.is_a? Integer + Rational(numerator - rhs * denominator, denominator) + elsif rhs.is_a? Numeric + (numerator - rhs * denominator) / denominator end end - def __forward_operators_to_rational - __forward_operator_to_rational :+ - __forward_operator_to_rational :- - __forward_operator_to_rational :* - __forward_operator_to_rational :/ + def /(rhs) + if rhs.is_a? Rational + Rational(numerator * rhs.denominator, denominator * rhs.numerator) + elsif rhs.is_a? Integer + Rational(numerator, denominator * rhs) + elsif rhs.is_a? Numeric + numerator / rhs / denominator + end + end - singleton_class.undef_method :__forward_operator_to_rational - singleton_class.undef_method :__forward_operators_to_rational + def negative? + numerator.negative? end + + def _simplify + a = numerator + b = denominator + a, b = b, a % b while !b.zero? + @numerator /= a + @denominator /= a + end + + attr_reader :numerator, :denominator end -class Fixnum - extend ForwardOperatorToRational - __forward_operators_to_rational +def Rational(numerator = 0, denominator = 1) + Rational.new(numerator, denominator) end -class Float - extend ForwardOperatorToRational - __forward_operators_to_rational +[Fixnum, Float].each do |cls| + [:+, :-, :*, :/, :==].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) + else + send(original_operator_name, rhs) + end + end + end + end end
\ No newline at end of file |
