You're doing high- precision arithmetic, and floating-point numbers are not precise enough.
BigDecimal number can
represent a real number to an arbitrary number of decimal
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"
BigDecimal store the same
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
You can use
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. ...