Imported Upstream version 1.46.0
[platform/upstream/nghttp2.git] / third-party / mruby / mrbgems / mruby-rational / mrblib / rational.rb
1 class Rational < Numeric
2   def inspect
3     "(#{to_s})"
4   end
5
6   def to_s
7     "#{numerator}/#{denominator}"
8   end
9
10   def *(rhs)
11     if rhs.is_a? Rational
12       Rational(numerator * rhs.numerator, denominator * rhs.denominator)
13     elsif rhs.is_a? Integer
14       Rational(numerator * rhs, denominator)
15     elsif rhs.is_a? Numeric
16       numerator * rhs / denominator
17     end
18   end
19
20   def +(rhs)
21     if rhs.is_a? Rational
22       Rational(numerator * rhs.denominator + rhs.numerator * denominator, denominator * rhs.denominator)
23     elsif rhs.is_a? Integer
24       Rational(numerator + rhs * denominator, denominator)
25     elsif rhs.is_a? Numeric
26       (numerator + rhs * denominator) / denominator
27     end
28   end
29
30   def -(rhs)
31     if rhs.is_a? Rational
32       Rational(numerator * rhs.denominator - rhs.numerator * denominator, denominator * rhs.denominator)
33     elsif rhs.is_a? Integer
34       Rational(numerator - rhs * denominator, denominator)
35     elsif rhs.is_a? Numeric
36       (numerator - rhs * denominator) / denominator
37     end
38   end
39
40   def /(rhs)
41     if rhs.is_a? Rational
42       Rational(numerator * rhs.denominator, denominator * rhs.numerator)
43     elsif rhs.is_a? Integer
44       Rational(numerator, denominator * rhs)
45     elsif rhs.is_a? Numeric
46       numerator / rhs / denominator
47     end
48   end
49
50   def <=>(rhs)
51     if rhs.is_a?(Integral)
52       return numerator <=> rhs if denominator == 1
53       rhs = Rational(rhs)
54     end
55
56     case rhs
57     when Rational
58       (numerator * rhs.denominator - denominator * rhs.numerator) <=> 0
59     when Numeric
60       (rhs <=> self)&.-@
61     else
62       nil
63     end
64   end
65
66   def ==(rhs)
67     return true if self.equal?(rhs)
68     if rhs.is_a?(Integral) && denominator == 1
69       return numerator == rhs
70     end
71     if rhs.is_a?(Rational)
72       numerator * rhs.denominator == denominator * rhs.numerator
73     else
74       rhs == self
75     end
76   end
77 end
78
79 class Numeric
80   def to_r
81     Rational(self, 1)
82   end
83 end
84
85 module Kernel
86   def Rational(numerator, denominator = 1)
87     a = numerator
88     b = denominator
89     a, b = b, a % b until b == 0
90     Rational._new(numerator.div(a), denominator.div(a))
91   end
92
93   [:+, :-, :*, :/, :<=>, :==, :<, :<=, :>, :>=].each do |op|
94     original_operator_name = :"__original_operator_#{op}_rational"
95     Fixnum.instance_eval do
96       alias_method original_operator_name, op
97       define_method op do |rhs|
98         if rhs.is_a? Rational
99           Rational(self).__send__(op, rhs)
100         else
101           __send__(original_operator_name, rhs)
102         end
103       end
104     end
105     Float.instance_eval do
106       alias_method original_operator_name, op
107       define_method op do |rhs|
108         if rhs.is_a? Rational
109           rhs = rhs.to_f
110         end
111         __send__(original_operator_name, rhs)
112       end
113     end if Object.const_defined?(:Float)
114   end
115 end