lib/fractional.rb in fractional-1.0.1 vs lib/fractional.rb in fractional-1.1.0

- old
+ new

@@ -12,11 +12,15 @@ when Rational @value = value when String @value = Fractional.string_to_fraction( value, options ) when Fixnum - @value = Rational(value) + if @value == @value.to_i + @value = Rational(value) + else # It's still Rational if it's a natural number + @value = Fractional.float_to_fraction( value.to_f, options ) + end when Numeric @value = Fractional.float_to_fraction( value.to_f, options ) else raise TypeError, "Cannot instantiate Fractional from #{value.class}" end @@ -113,10 +117,14 @@ if options[:to_nearest] return self.round_to_nearest_fraction( value, options[:to_nearest] ) end + if options[:to_human] + return self.round_to_human_fraction( value ) + end + # first try to convert a repeating decimal unless guesstimate is forbidden unless options[:exact] repeat = float_to_rational_repeat(value) return repeat unless repeat.nil? end @@ -213,8 +221,31 @@ end def self.round_to_nearest_fraction(value, to_nearest_fraction) to_nearest_float = Fractional.new(to_nearest_fraction).to_f Fractional.new((Fractional.new(value).to_f / to_nearest_float).round * to_nearest_float) + end + + def self.numeric_to_mixed_number(amount) + sign_prefix = ( amount < 0 )? '-' : '' + amount = amount.abs + amount_as_integer = amount.to_i + if (amount_as_integer != amount.to_f) && (amount_as_integer > 0) + fraction = amount - amount_as_integer + "#{sign_prefix}#{amount_as_integer} #{fraction}" + else + if amount.denominator == 1 + "#{sign_prefix}#{amount_as_integer}" + else + sign_prefix + amount.to_s + end + end + end + + # Display numbers in human-readable manner. + # Examples: 0.5 -> 1/2, 2.333 -> 2 1/3, 0.666 -> 2/3 etc. + # + def self.round_to_human_fraction(value) + numeric_to_mixed_number value.rationalize(Rational('0.01')) end end