Question
Ruby Integer Division: Why 9 / 5 Returns 1 and How to Get Decimals
Question
Why does division in Ruby return an integer instead of a decimal value?
For example:
9 / 5 # => 1
I expected the result to be 1.8. Why does Ruby return 1, and how can I get the correct non-integer decimal result?
Short Answer
You will learn how Ruby chooses the result type for division, why dividing two Integer values discards the fractional part, and how to deliberately perform floating-point division when you need a decimal result.
Concept
Ruby supports several numeric types, including Integer, Float, and Rational. The types of the operands influence how an operation behaves.
When both sides of / are integers, Ruby performs integer division:
9 / 5 # => 1
The mathematical answer is 1.8, but integer division keeps only the whole-number quotient. It truncates the fractional part toward zero:
17 / 5 # => 3
-17 / 5 # => -3
Ruby returns 1 because the expression contains two integers: 9 and 5.
To get a decimal result, make at least one operand a Float:
9.0 / 5 # => 1.8
9 / 5.0 # => 1.8
This matters because programs often calculate averages, prices, percentages, measurements, and rates. Integer division can silently produce an incorrect value when a fraction is important.
Mental Model
Think of integer division as sharing items that cannot be split.
If you share 9 whole cookies among 5 people and only count complete cookies per person, each person gets 1 whole cookie. The remaining 4 cookies are not represented in the integer result:
9 / 5 # 1 whole cookie each
Floating-point division allows cookies to be cut into pieces. Once one number is written as 9.0 or 5.0, Ruby knows that fractional pieces are allowed:
9.0 / 5 # 1.8 cookies each
Syntax and Examples
Use / with a Float operand when you want a floating-point result.
numerator = 9
denominator = 5
result = numerator.to_f / denominator
puts result # 1.8
to_f converts the integer 9 to the float 9.0. Because one operand is now a float, Ruby performs floating-point division.
Other valid forms are:
9.0 / 5 # => 1.8
9 / 5.0 # => 1.8
9.fdiv(5) # => 1.8
fdiv explicitly requests floating-point division and is especially clear when both values are integers.
If exact fractional arithmetic is needed instead of an approximate decimal float, use Rational:
require "rational"
Rational(9, 5) # => (9/5)
Rational(9, 5).to_f # => 1.8
For most everyday calculations, converting one operand to a float or using fdiv is sufficient.
Step by Step Execution
Consider this example:
total_points = 9
players = 5
average = total_points.to_f / players
puts average
Step by step:
total_pointsstores the integer9.playersstores the integer5.total_points.to_fconverts9into the float9.0.- Ruby evaluates
9.0 / 5using floating-point division. - The result is the float
1.8. putsdisplays1.8.
Without to_f, Ruby evaluates this instead:
total_points / players # 9 / 5 => 1
Both operands are integers, so the fractional .8 is discarded.
Real World Use Cases
Integer versus decimal division appears in many common tasks:
- Averages: Calculate the average test score or average order value.
total_score.to_f / student_count - Percentages: Convert completed tasks into a completion percentage.
completed.to_f / total * 100 - Rates: Calculate requests per second, distance per hour, or bytes per second.
bytes.fdiv(seconds) - Pagination: Integer division is useful when calculating a whole page number.
item_index / items_per_page - Money: Use decimal-safe tools such as
BigDecimalfor currency calculations rather than ordinary floats when precision is required.
Real Codebase Usage
In production Ruby code, developers make the intended kind of division explicit.
For a calculated rate or average, use fdiv or to_f:
def completion_rate(completed, total)
return 0.0 if total.zero?
completed.fdiv(total)
end
The guard clause prevents division by zero, and fdiv clearly states that the method returns a floating-point value.
For percentages, convert before dividing, not after:
percentage = successful_requests.fdiv(total_requests) * 100
For money, use BigDecimal because binary floating-point values cannot precisely represent many decimal values:
require "bigdecimal"
price = BigDecimal("9.00")
quantity = BigDecimal("5")
unit_price = price / quantity
For whole units, such as page counts or complete groups, integer division is intentional:
full_boxes = item_count / items_per_box
Common Mistakes
Converting after integer division
This is too late:
9 / 5.to_f # => 1.8
(9 / 5).to_f # => 1.0
In (9 / 5).to_f, Ruby first calculates 9 / 5 as 1, then converts 1 to 1.0. Convert an operand before division instead.
Assuming integer division rounds
Integer division does not round to the nearest integer:
8 / 5 # => 1, not 2
It truncates toward zero. If you need rounding, divide as floats and call a rounding method:
(8.0 / 5).round # => 2
Ignoring division by zero
Neither integer nor float division should be used with a zero denominator without handling that case:
def average(total, count)
return 0.0 if count.zero?
total.fdiv(count)
end
Using Float for exact money values
This can expose floating-point precision artifacts:
0.1 + 0.2 # may not display as an exact 0.3 in calculations
Use BigDecimal for financial values that require exact decimal behavior.
Comparisons
| Approach | Example | Result | Best use |
|---|---|---|---|
| Integer division | 9 / 5 | 1 | Whole groups, indexes, page numbers |
| Float literal | 9.0 / 5 | 1.8 | Simple decimal calculations |
to_f conversion | 9.to_f / 5 | 1.8 | Values stored in integer variables |
fdiv | 9.fdiv(5) | 1.8 | Explicit floating-point division |
| Rational number | Rational(9, 5) | (9/5) | Exact fractions |
BigDecimal | BigDecimal("9") / 5 | exact decimal representation | Currency and precision-sensitive decimals |
/ is not always "decimal division" in Ruby. Its behavior depends on the numeric types involved. fdiv is often the clearest option when you specifically want a float.
Cheat Sheet
# Two integers: fractional part is discarded
9 / 5 # => 1
# Make one operand a Float
9.0 / 5 # => 1.8
9 / 5.0 # => 1.8
9.to_f / 5 # => 1.8
# Explicit floating-point division
9.fdiv(5) # => 1.8
# Convert before, not after, division
(9 / 5).to_f # => 1.0 # too late
# Round a decimal result if needed
(8.0 / 5).round # => 2
# Avoid division by zero
result = count.zero? ? 0.0 : total.fdiv(count)
Integer / Integerperforms integer division.- A
Floaton either side of/produces aFloatresult. - Integer division truncates toward zero; it does not round.
- Prefer
BigDecimalfor currency andRationalfor exact fractions.
FAQ
Why does 9 / 5 equal 1 in Ruby?
Both 9 and 5 are integers. Ruby therefore performs integer division and discards the fractional part.
How do I get 1.8 from 9 / 5 in Ruby?
Make at least one number a float or use fdiv:
9.0 / 5
# or
9.fdiv(5)
Does Ruby integer division round down?
For positive values it appears to round down, but the precise rule is truncation toward zero. For example, -9 / 5 is -1, not -2.
Is to_f or fdiv better in Ruby?
Both work. fdiv is more explicit about your intent to perform floating-point division. to_f is convenient when you already need to convert a value for other reasons.
Why is (9 / 5).to_f equal to 1.0?
Ruby calculates 9 / 5 first, producing 1. Only afterward does to_f convert that result to 1.0; the lost fraction cannot be restored.
Should I use floats for prices in Ruby?
Usually no. Use BigDecimal for currency values to avoid floating-point precision issues.
Can I keep the exact fraction instead of getting a float?
Yes. Use Rational(9, 5), which represents the exact fraction 9/5.
Mini Project
Description
Build a small score summary that calculates a player's average points per game. The project demonstrates why integer division can be misleading in reports and how fdiv preserves the decimal part.
Goal
Create a Ruby program that safely calculates and displays an average score with two decimal places.
Requirements
Use integer values for total points and games played.|Return 0.0 when games played is zero.|Use floating-point division to preserve fractional averages.|Display the average rounded to two decimal places.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.