bigdecimal

Ruby BigDecimal#new: How to Create BigDecimal Values

There are several ways to create BigDecimal values in Ruby, and the approach you choose matters. The most important rule applies to all of them: always use strings as the source value, not floats. We will cover why shortly.

The BigDecimal() Kernel Method

require 'bigdecimal'

BigDecimal("1.23")      # => 0.123e1
BigDecimal("0.0825")    # => 0.825e-1
BigDecimal("1000")      # => 0.1e4
BigDecimal("0")         # => 0.0

This is the canonical way to create BigDecimal values. The string is parsed exactly as written, with no binary floating-point involvement. The output format looks unfamiliar at first — BigDecimal uses engineering notation internally — but the value is exact.

Do Not Pass a Float

Passing a float literal to BigDecimal() captures the float’s binary imprecision rather than the decimal value you intended:

# Wrong: inherits floating-point error
BigDecimal(0.1)
# => 0.1000000000000000055511151231257827021181583404541015625e0

# Correct: parse from string
BigDecimal("0.1")
# => 0.1e0

That enormous decimal expansion is the actual binary float value that your CPU stores. When you pass a string instead, BigDecimal parses your decimal intent directly. This single distinction is worth remembering, because floating-point-derived BigDecimals can silently produce wrong financial calculations.

The bigdecimal/util Helper

Requiring bigdecimal/util adds to_d to String, Integer, Float, and Rational, which often leads to more readable code:

require 'bigdecimal'
require 'bigdecimal/util'

"1.23".to_d          # => 0.123e1
123.to_d             # => 0.123e3
(1/3r).to_d(10)      # => 0.3333333333e0  (10 significant digits)

Float#to_d converts via the float’s string representation, which avoids the binary precision issue:

0.1.to_d   # => 0.1e0

This is one of the few times it is safe to start from a float — to_d goes through the string representation rather than capturing the raw binary value.

Creating from Integer

require 'bigdecimal'

BigDecimal(42)      # => 0.42e2
42.to_d             # works with bigdecimal/util

Integers are exact in Ruby, so creating a BigDecimal from one is always safe. No precision is lost in the conversion.

Creating from Rational

require 'bigdecimal'
require 'bigdecimal/util'

(1/3r).to_d(15)
# => 0.333333333333333e0

The second argument to to_d sets the number of significant digits for the conversion. For repeating fractions like one-third, you must supply a digit count — otherwise BigDecimal has no way to know where to stop.

Special Values

require 'bigdecimal'

BigDecimal::INFINITY   # => Infinity
-BigDecimal::INFINITY  # => -Infinity
BigDecimal::NAN        # => NaN

These constants let you check for edge cases:

n = BigDecimal("1.0") / BigDecimal("0")
n.infinite?   # => 1
n.nan?        # => false

Division by zero produces Infinity rather than raising an exception, which differs from Integer division behavior. If your code divides BigDecimal values where the denominator might be zero, it is worth checking with infinite? or nan? before using the result.