module ActionView module Helpers #:nodoc: module NumberHelper # Formats a +number+ into a fraction string (i.e. 1 1/3 or 2/9). You can customize the format # in the +options+ hash. # # *NOTE*: This function only supports the "pretty printing" of factions less than 1/10th. # # ==== Options # * *precision* - Options. Sets the level of precision. Defaults to 3. # # ==== Examples # number_to_fraction 0.25 # => 1/4 # number_to_fraction 1.375 # => 1 3/8 # number_to_fraction 5.22 # => 5 2/9 # number_to_fraction 3.55 :precision => 2 # 3 => 5/9 def number_to_fraction number = '', options = {} number = number.to_s.strip options.reverse_merge! :precision => 3 whole, numerator, denominator = nil if number.include? '.' whole, numerator = number.split '.' rational = Rational(numerator.ljust(options[:precision], '0').to_i, (10 ** options[:precision])) # Check for repeating/complex decimals - yeah, this solution is lame. case when !numerator.match(/^33+/).nil? then numerator, denominator = 1, 3 when !numerator.match(/^66+/).nil? then numerator, denominator = 2, 3 when !numerator.match(/^1{1}6+/).nil? then numerator, denominator = 1, 6 when !numerator.match(/^8{1}3+/).nil? then numerator, denominator = 5, 6 when !numerator.match(/^142/).nil? then numerator, denominator = 1, 7 when !numerator.match(/^285/).nil? then numerator, denominator = 2, 7 when !numerator.match(/^428/).nil? then numerator, denominator = 3, 7 when !numerator.match(/^571/).nil? then numerator, denominator = 4, 7 when !numerator.match(/^714/).nil? then numerator, denominator = 5, 7 when !numerator.match(/^857/).nil? then numerator, denominator = 6, 7 when !numerator.match(/^125/).nil? then numerator, denominator = 1, 8 when !numerator.match(/^375/).nil? then numerator, denominator = 3, 8 when !numerator.match(/^625/).nil? then numerator, denominator = 5, 8 when !numerator.match(/^875/).nil? then numerator, denominator = 7, 8 when !numerator.match(/^11+/).nil? then numerator, denominator = 1, 9 when !numerator.match(/^22+/).nil? then numerator, denominator = 2, 9 when !numerator.match(/^44+/).nil? then numerator, denominator = 4, 9 when !numerator.match(/^55+/).nil? then numerator, denominator = 5, 9 when !numerator.match(/^77+/).nil? then numerator, denominator = 7, 9 when !numerator.match(/^88+/).nil? then numerator, denominator = 8, 9 else numerator, denominator = rational.numerator, rational.denominator end else whole = number end whole = nil if whole == '0' && numerator [whole, [numerator, denominator].compact * '/'].compact.join(' ').strip end end end end