Today I Learned

A Hashrocket project

Convert to BigDecimal with `to_d` w/ActiveSupport

Ruby provides the BigDecimal method to convert to BigDecimal.

> require 'bigdecimal'
> BigDecimal("123.45")
#<BigDecimal:56236cc3cab8,'0.12345E3',18(18)>

But you can’t convert a float without a precision

> BigDecimal(123.12)
ArgumentError: can't omit precision for a Float.
> BigDecimal(123.12, 5).to_s
"0.12312E3"

When using Rails, and specifically with ActiveSupport required, you can use the to_d method converts to BigDecimal.

> require 'active_support'
> 123.to_d
#<BigDecimal:55ebd7800ea8,'0.123E3',9(27)>
> "123".to_d
#<BigDecimal:55ebd7800ea8,'0.123E3',9(27)>

And for floats provides a default precision of Float::DIG+1 which for me is 16. DIG is described as

The number of decimal digits in a double-precision floating point.

> 123.45.to_d
#<BigDecimal:55ebd2d6cfb8,'0.12345E3',18(36)>
> 123.45.to_d.to_s
"123.45"

Note, to_s in ActiveSupport outputs a more human readable number. Also Note, nil is not convertable with to_d

> require 'active_support'
> nil.to_d
NoMethodError: undefined method `to_d' for nil:NilClass
> BigDecimal(nil)
TypeError: no implicit conversion of nil into String
Looking for help? Hashrocket has been an industry leader in Ruby on Rails since 2008. Rails is a core skill for each developer at Hashrocket and we'd love to take a look at your project. Contact us and find out how we can help you.