Class: Fraction
Overview
A fraction! (Like a Rational, but … uh … in pure Ruby!)
Can be compared, added, multiplied, simplified, “percent”ed, “to_f”ed, and printed/inspected.
Instance Attribute Summary collapse
-
#first ⇒ Object
(also: #top, #numerator)
Returns the value of attribute first.
-
#last ⇒ Object
(also: #bottom, #denominator)
Returns the value of attribute last.
Class Method Summary collapse
Instance Method Summary collapse
-
#*(v) ⇒ Object
Multiply the fractions.
-
#+(r) ⇒ Object
Adds together the tops and bottoms of the fractions.
- #<=>(other) ⇒ Object
-
#initialize(first, last = 1) ⇒ Fraction
constructor
‘first` is the top part of the fraction, `last` is the bottom (eg: `first/last`).
-
#inspect ⇒ Object
“#<Fraction: 1/2>”.
-
#percent ⇒ Object
(also: #to_percent)
Returns a string representing the number in percent.
- #simplify ⇒ Object
-
#to_f ⇒ Object
Returns the fraction as a float.
-
#to_s ⇒ Object
(also: #fraction)
Returns a string representation: “a/b”.
Constructor Details
#initialize(first, last = 1) ⇒ Fraction
‘first` is the top part of the fraction, `last` is the bottom (eg: `first/last`)
19 20 21 22 |
# File 'lib/epitools/fraction.rb', line 19 def initialize(first, last=1) @first = first @last = last end |
Instance Attribute Details
#first ⇒ Object Also known as: top, numerator
Returns the value of attribute first.
8 9 10 |
# File 'lib/epitools/fraction.rb', line 8 def first @first end |
#last ⇒ Object Also known as: bottom, denominator
Returns the value of attribute last.
8 9 10 |
# File 'lib/epitools/fraction.rb', line 8 def last @last end |
Class Method Details
.[](*args) ⇒ Object
24 25 26 |
# File 'lib/epitools/fraction.rb', line 24 def self.[](*args) new(*args) end |
Instance Method Details
#*(v) ⇒ Object
Multiply the fractions
87 88 89 90 91 92 93 94 95 96 |
# File 'lib/epitools/fraction.rb', line 87 def *(v) case v when Integer Fraction[ v*first, v*last ] when Fraction Fraction[ v.first*first, v.last*last ] else raise TypeError.new("I don't know how to multiply a Fraction and a #{v.class}. Sorry. :(") end end |
#+(r) ⇒ Object
Adds together the tops and bottoms of the fractions.
Example: For the fractions ‘a/c` and `b/d`, returns `a+b/c+d`
73 74 75 76 77 78 79 80 81 82 |
# File 'lib/epitools/fraction.rb', line 73 def +(r) case r when Integer self + Fraction[r] when Fraction Fraction[ r.last*first + r.first*last, r.last*last ] else raise TypeError.new("Sorry, I can't add a Fraction and a #{r.class}. :(") end end |
#<=>(other) ⇒ Object
30 31 32 |
# File 'lib/epitools/fraction.rb', line 30 def <=>(other) to_f <=> other.to_f end |
#inspect ⇒ Object
“#<Fraction: 1/2>”
64 65 66 |
# File 'lib/epitools/fraction.rb', line 64 def inspect "#<Fraction: #{to_s}>" end |
#percent ⇒ Object Also known as: to_percent
Returns a string representing the number in percent
56 57 58 |
# File 'lib/epitools/fraction.rb', line 56 def percent "%0.1f%%" % (to_f * 100) end |
#simplify ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/epitools/fraction.rb', line 98 def simplify require 'prime' # factor the numerator and denominator into hashes of { factor => exponent } pairs n_fact, d_fact = [numerator, denominator].map { |n| Prime.prime_division(n).to_h } # cancel out common factors by subtracting exponents d_fact.each do |v, d_exp| if n_exp = n_fact[v] if n_exp < d_exp d_fact[v] = d_exp - n_exp n_fact[v] = 0 else n_fact[v] = n_exp - d_exp # <= if n_exp == d_exp, this is 0, which covers the 3rd case d_fact[v] = 0 end end end # multiply the simplified factors back into full numbers simp_n, simp_d = [n_fact, d_fact].map { |h| h.map{ |n, exp| n ** exp }.reduce(:*) } Fraction[simp_n, simp_d] end |
#to_f ⇒ Object
Returns the fraction as a float. (eg: Fraction.to_f == 0.5)
45 46 47 48 49 50 51 |
# File 'lib/epitools/fraction.rb', line 45 def to_f if @last == 0 raise ZeroDivisionError else @first.to_f / @last end end |
#to_s ⇒ Object Also known as: fraction
Returns a string representation: “a/b”
37 38 39 |
# File 'lib/epitools/fraction.rb', line 37 def to_s "#{@first}/#{@last}" end |