Last Updated: February 25, 2016
·
1.188K
· gus

Humanize currency

I wanted to remove the trailing zero decimals of a float and only display the number as an integer. However, if those decimals are relevant, the first 2 trailing decimals should be shown.

The normal approach dictates to use some basic string manipulation in the form of:

 > "%.2f % 2.509
=> 2.50
> "%g" % 2.00
=> 2

Perfect! a combination of the two should do the trick, right?

> "%g" % ("%.2f" % 2.00)
=> 2 # :)
> "%g" % ("%.2f" % 2.50)
=> 2.5 # :(

What about comparing values?

> 2.00 == 2.00.to_i
=> true # wtf?

Bring in the bananas!

Numeric.class_eval do
  def has_significant_zeros?
    begin
      !Integer("%g" % self)
    rescue ArgumentError, TypeError
      true
    end
  end
end

> number = 2.00
> number.to_i unless number.has_significant_zeros?
=> 2
> number = 2.50
> number.to_i unless number.has_significant_zeros?
=> nil

Now we can implement whatever fancies us, even the earlier approach, for instance

def sanitize_currency(number)
  return "%.2f" % number if number.has_significant_zeros?

  number.to_i
end