module BrazilianCardinality::Number

Constants

HUNDREDS
NumberTooBigError
ONES
TENS

Public Class Methods

number_cardinal(number) click to toggle source
# File lib/brazilian_cardinality/number.rb, line 52
def number_cardinal(number)
  negative = number.negative? ? 'menos ' : ''
  n = number.to_i.abs

  expression = case n
               when 0..999 then cardinal_for_0_up_to_999(n)
               when 1000..999_999_999_999_999 then cardinal_for_thousands_to_trillions(n)
               else raise NumberTooBigError, "#{n} is too big"
               end

  "#{negative}#{expression}"
end

Private Class Methods

cardinal_for_0_up_to_999(number) click to toggle source
# File lib/brazilian_cardinality/number.rb, line 67
def cardinal_for_0_up_to_999(number)
  case number
  when 0..9 then ONES[number]
  when 10..19 then TENS[number]
  when 20..99 then cardinal_for_tens_and_hundreds(number, 10)
  when 100 then 'cem'
  when 101..999 then cardinal_for_tens_and_hundreds(number, 100)
  end
end
cardinal_for_scale_of_thousands(number, scale, singular, plural) click to toggle source
# File lib/brazilian_cardinality/number.rb, line 97
def cardinal_for_scale_of_thousands(number, scale, singular, plural)
  quocient = number / scale
  remainder = number % scale
  word = quocient > 1 ? plural : singular
  high_order_units = "#{number_cardinal(quocient)} #{word}"
  return high_order_units if remainder.zero?
  "#{high_order_units} e #{number_cardinal(remainder)}"
end
cardinal_for_tens_and_hundreds(number, scale) click to toggle source
# File lib/brazilian_cardinality/number.rb, line 90
def cardinal_for_tens_and_hundreds(number, scale)
  remainder = number % scale
  words_map = scale == 10 ? TENS : HUNDREDS
  return words_map[number] if remainder.zero?
  "#{words_map[number - remainder]} e #{number_cardinal(remainder)}"
end
cardinal_for_thousands_to_trillions(number) click to toggle source
# File lib/brazilian_cardinality/number.rb, line 77
def cardinal_for_thousands_to_trillions(number)
  case number
  when 1000..999_999
    cardinal_for_scale_of_thousands(number, 1_000, 'mil', 'mil')
  when 1_000_000..999_999_999
    cardinal_for_scale_of_thousands(number, 1_000_000, 'milhão', 'milhões')
  when 1_000_000_000..999_999_999_999
    cardinal_for_scale_of_thousands(number, 1_000_000_000, 'bilhão', 'bilhões')
  when 1_000_000_000_000..999_999_999_999_999
    cardinal_for_scale_of_thousands(number, 1_000_000_000_000, 'trilhão', 'trilhões')
  end
end