
July 8, 2026
If you’ve ever been surprised by this in Ruby:
(2.0 - 1.1) == 0.9# => false
you’re not alone.
Many developers initially assume this is a Ruby bug. It isn’t.
In fact, Ruby’s own issue tracker includes a Floating point numbers section in its FAQ that links directly to David Goldberg’s classic paper, What Every Computer Scientist Should Know About Floating-Point Arithmetic. More than three decades after its publication, it remains the definitive explanation of why floating-point numbers behave the way they do.
The Problem Isn’t Ruby
Ruby’s Float implements the IEEE 754 double-precision floating-point standard used by most modern programming languages, including C, C++, Java, Python, JavaScript, Go, and Rust.
The challenge is simple: many decimal values cannot be represented exactly in binary.
For example, values such as 0.1, 0.2, 0.9, and 1.1 are stored as the closest representable binary approximation. These tiny approximation errors accumulate during arithmetic.
That’s why:
1.1 - 0.9# => 0.20000000000000007
and why comparing floating-point values with == often produces unexpected results.
Ruby’s Recommended Solutions
The Ruby community generally recommends choosing the appropriate numeric type for your domain.
Float
Use Float for scientific calculations, graphics, simulations, and situations where tiny rounding errors are acceptable.
When comparing results, compare within a small tolerance instead of using direct equality.
BigDecimal
For financial applications and any domain requiring exact decimal arithmetic, use BigDecimal.
require "bigdecimal"price = BigDecimal("19.99")tax = BigDecimal("0.21")
Passing strings preserves the exact decimal value instead of first creating an imprecise Float.
Rational
When working with exact fractions, Rational provides mathematically precise results.
Rational(11, 10) - Rational(9, 10)# => (1/5)
A Timeless Reference
It’s unusual for an official language resource to recommend a paper published in 1991, but floating-point arithmetic is one of those foundational topics that hasn’t changed.
The algorithms used by CPUs have evolved, Ruby’s formatting has improved over the years, and BigDecimal has become easier to use, but the underlying mathematics—and the IEEE 754 standard—remain the same.
Sometimes the best explanation isn’t the newest one.
Further Reading
- Ruby Issue Tracker FAQ – Floating point numbers
- Ruby Talk FAQ – Floats are imprecise
- David Goldberg, What Every Computer Scientist Should Know About Floating-Point Arithmetic
- IEEE 754 Floating-Point Standard
