class Fraction

A fraction! (Like a Rational, but … uh … in pure Ruby!)

Can be compared, added, multiplied, simplified, “percent”ed, “to_f”ed, and printed/inspected.

Attributes

bottom[RW]
denominator[RW]
first[RW]
last[RW]
numerator[RW]
top[RW]

Public Class Methods

[](*args) click to toggle source
# File lib/epitools/fraction.rb, line 24
def self.[](*args)
  new(*args)
end
new(first, last=1) click to toggle source

‘first` is the top part of the fraction, `last` is the bottom (eg: `first/last`)

# File lib/epitools/fraction.rb, line 19
def initialize(first, last=1)
  @first = first
  @last = last
end

Public Instance Methods

*(v) click to toggle source

Multiply the fractions

# 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) click to toggle source

Adds together the tops and bottoms of the fractions.

Example: For the fractions ‘a/c` and `b/d`, returns `a+b/c+d`

# 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) click to toggle source
# File lib/epitools/fraction.rb, line 30
def <=>(other)
  to_f <=> other.to_f
end
fraction()
Alias for: to_s
inspect() click to toggle source

“#<Fraction: 1/2>”

# File lib/epitools/fraction.rb, line 64
def inspect
  "#<Fraction: #{to_s}>"
end
percent() click to toggle source

Returns a string representing the number in percent

# File lib/epitools/fraction.rb, line 56
def percent
  "%0.1f%%" % (to_f * 100)
end
Also aliased as: to_percent
simplify() click to toggle source
# 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() click to toggle source

Returns the fraction as a float. (eg: Fraction.to_f == 0.5)

# File lib/epitools/fraction.rb, line 45
def to_f
  if @last == 0
    raise ZeroDivisionError
  else
    @first.to_f / @last
  end
end
to_percent()
Alias for: percent
to_s() click to toggle source

Returns a string representation: “a/b”

# File lib/epitools/fraction.rb, line 37
def to_s
  "#{@first}/#{@last}"
end
Also aliased as: fraction