In Ruby, what do 7 / 2, -7 / 2 and 7 / 2.0 return, and how do you split 100 cents three ways?
answer
- both Integers: Integer result
- floors toward negative infinity
- one Float operand: Float result
- divmod returns [quotient, modulus]
- Integer zero raises, Float zero gives Infinity
basics
~20 s7 / 2 is 3 and -7 / 2 is -4, because Integer division floors; 7 / 2.0 is 3.5, because a Float operand gives Float division. Split with 100.divmod(3), which returns [33, 1], and hand out the leftover cent.
solid answer
~40 sWhen both operands are Integers, `/` returns an Integer rounded toward negative infinity: `7 / 2` is `3`, and `-7 / 2` is `-4`, not `-3`. If either side is a Float, the result is a Float, so `7 / 2.0` and `7.0 / 2` are `3.5`. Dividing an Integer by exact `0` raises `ZeroDivisionError`, while `7.0 / 0` returns `Infinity`. To split a restaurant bill, keep the amount in integer cents and use `divmod`: `100.divmod(3)` returns `[33, 1]`, the floored quotient and the leftover, so two people pay 33 and one pays 34, and the shares always add back to 100. Plain `/` would silently drop the leftover cent, and converting to Float to share it invites rounding errors.
code
ruby · 14 lines7 / 2 # => 3
-7 / 2 # => -4 (floored, not truncated)
7 / 2.0 # => 3.5
7.div(2.0) # => 3
7.0 / 0 # => Infinity
bill = 100 # cents
diners = 3
share, extra = bill.divmod(diners) # => [33, 1]
shares = Array.new(diners) { |i| i < extra ? share + 1 : share }
shares # => [34, 33, 33]
shares.sum # => 100
bill / diners # => 33, and a cent is lostgo deeper
Recall that two Integers give an Integer quotient, one Float operand gives a Float, and Integer division by zero raises ZeroDivisionError.
Explain flooring toward negative infinity, why -7 / 2 is -4, and how divmod keeps quotient and modulus consistent for bucketing.
Insist on integer minor units and divmod for money and quotas, and review any division on values that can go negative for flooring surprises.
Standardise how the codebase represents money and splits totals, so rounding and leftover-cent rules are decided once instead of per feature.
Division is where Ruby's arithmetic operators surprise newcomers most, because the **types of the operands** decide what `/` does, and because Integer division **floors** instead of truncating. ## What / returns In Ruby, `/` is a method on the left operand: `7 / 2` is `7./(2)`, handled by `Integer#/`. Its behaviour depends on both operands: | Expression | Result | Why | |---|---|---| | `7 / 2` | `3` | Integer by Integer gives an Integer | | `-7 / 2` | `-4` | the quotient is floored toward negative infinity | | `7 / -2` | `-4` | same flooring when the divisor is negative | | `7 / 2.0` | `3.5` | a Float divisor gives Float division | | `7.0 / 2` | `3.5` | `Float#/` with an Integer argument | | `7 / 0` | `ZeroDivisionError` | Integer division by exact zero | | `7.0 / 0` | `Infinity` | Float division by zero follows IEEE 754 | Two definitions: - **Flooring** means rounding down toward negative infinity: -3.5 becomes -4. - **Truncating** means dropping the fractional part, rounding toward zero: -3.5 becomes -3. Ruby's Integer `/` floors. For positive operands the two agree, which is why the difference hides until a negative number turns up - a refund, a temperature, an offset. ## Related division methods - **`Integer#div`** always floors and returns an Integer, even with a Float argument: `7.div(2.0)` is `3`. - **`Integer#divmod`** returns `[quotient, modulus]` in one call, with the quotient floored and the modulus equal to `self % other`, so `q * divisor + r` always gives back the original number. - **`Integer#fdiv`** returns a Float quotient; it is the explicit way to ask for `3.5`. - **`Integer#**`** raises to a power; note that `2 ** -1` returns the Rational `(1/2)`, not a Float, so exponentiation can also change the result type. ## Splitting a restaurant bill Money should be held in **integer minor units** (cents), never as a Float, because binary floating point cannot represent most decimal fractions exactly. Splitting 100 cents three ways then becomes an integer problem: ```ruby total = 100 people = 3 share, leftover = total.divmod(people) # => [33, 1] shares = Array.new(people) { |i| i < leftover ? share + 1 : share } shares # => [34, 33, 33] shares.sum # => 100 ``` The steps: 1. `divmod` gives the base share (`33`) and how many cents are left over (`1`). 2. The first `leftover` people pay one extra cent each. 3. The shares always add back to the total, so no cent disappears and none is invented. Common wrong versions: - `total / people` alone gives `33` each and silently loses a cent. - `total / people.to_f` gives `33.333333333333336`, and rounding each share gives 99 in total with `round` or 102 with `ceil` - never exactly 100. - Using Floats for the running total accumulates representation error over many bills. ## Why flooring matters beyond money Flooring keeps `/` and `%` consistent: for any Integers `a` and non-zero `b`, `a == (a / b) * b + (a % b)`. With `-7` and `2`, `-7 / 2` is `-4` and `-7 % 2` is `1`, and `-4 * 2 + 1` is `-7`. That identity is what makes `divmod` safe to use for bucketing - grouping timestamps into slots, assigning tables to waiters, paginating - even when values go negative, because every value lands in exactly one bucket and the bucket index never skips. ## Reading division in code review A few patterns deserve a second look whenever you see `/` in Ruby code: 1. **Averages and percentages** computed from Integer counts: `hits / total * 100` is `0` whenever `hits < total`, because the Integer division happens first. Reorder to `hits * 100 / total` or use `fdiv`. 2. **Negative inputs** reaching Integer division, such as refunds or time offsets: the result floors, so `-1 / 2` is `-1`, not `0`. 3. **Mixed types by accident**: a value read as a Float from a config file turns an intended Integer split into a fractional one. 4. **Division by user-supplied counts**: an Integer zero raises `ZeroDivisionError`, which is usually better than the silent `Infinity` a Float gives. ## Checklist - Both operands Integer: Integer result, floored. - Any Float operand: Float result; exact-zero Float division gives `Infinity` or `NaN` instead of raising. - Need both parts: `divmod`. - Need a fractional result on purpose: `fdiv`, or make one operand a Float. - Money: integer cents plus `divmod`, never Float division.
- In Ruby, what does 7 / 0 do compared with 7.0 / 0 and 0.0 / 0?`7 / 0` raises `ZeroDivisionError`, because Integer division by exact zero is an error. `7.0 / 0` returns `Infinity` and `0.0 / 0` returns `NaN`, because Float division follows IEEE 754 and produces special values instead of raising.
- Why does Ruby's Integer division floor instead of truncate?Flooring keeps `/` consistent with `%`, whose result takes the divisor's sign: `a == (a / b) * b + a % b` holds for every sign combination. That makes `divmod`, bucketing and wrap-around arithmetic behave the same for negative numbers as for positive ones. Truncating division is still available through `remainder` for the modulus side.
- In Ruby, what type does 2 ** -2 return?A Rational, `(1/4)`. `Integer#**` with a negative Integer exponent returns an exact Rational rather than a Float, so exponentiation can change the result type just as a Float operand does for `/`.
saying these in an interview costs you the question
- -7 / 2 in Ruby is -3 because Integer division truncates toward zero.
- Ruby's / always returns a Float when the division is not exact.
- Dividing an Integer by zero in Ruby returns Infinity.
- Store bill amounts as Floats and round each share at the end.
- 100 / 3 * 3 gives back 100 in Ruby.