You're doing high- precision arithmetic, and floating-point numbers are not precise enough.

A `BigDecimal`

number can
represent a real number to an arbitrary number of decimal
places.

require 'bigdecimal' BigDecimal("10").to_s # => "0.1E2" BigDecimal("1000").to_s # => "0.1E4" BigDecimal("1000").to_s("F") # => "1000.0" BigDecimal("0.123456789").to_s # => "0.123456789E0"

Compare how `Float`

and
`BigDecimal`

store the same
high-precision number:

nm = "0.123456789012345678901234567890123456789" nm.to_f # => 0.123456789012346 BigDecimal(nm).to_s # => "0.123456789012345678901234567890123456789E0"

`BigDecimal`

numbers store
numbers in scientific notation format. A `BigDecimal`

consists of a sign (positive or
negative), an arbitrarily large decimal fraction, and an arbitrarily
large exponent. This is similar to the way floating-point numbers are
stored, but a double- precision floating-point implementation like Ruby's
cannot represent an exponent less than `Float::MIN_EXP`

(–1021) or greater than
`Float::MAX_EXP`

(1024). Float
objects also can't represent numbers at a greater precision than `Float::EPSILON`

, or about
2.2*10^{-16}.

You can use `BigDecimal#split`

to split a `BigDecimal`

object into the parts of its scientific-notation representation. It returns an array of four numbers: the sign (1 for positive numbers,–1 for negative numbers), the fraction (as a string), the base of the exponent (which is always 10), and the exponent itself. ...

Start Free Trial

No credit card required