Question presented to candidate:
"If I type 0.1 + 0.2 == 0.3 into Python I get False. Why does that happen, how should I compare floats, and when would you reach for decimal.Decimal or fractions.Fraction instead of float?"
What a strong answer should cover:
- A Python
floatis a 64-bit IEEE 754 binary double (53 bits of precision,sys.float_info.mant_dig == 53); 0.1, 0.2 and 0.3 have no exact binary form, so each literal is stored as the nearest binary fraction and the sum lands on a different neighbour than 0.3 repr()prints the shortest string that round-trips, which is why0.1looks exact butDecimal(0.1)or(0.1).as_integer_ratio()reveals the real stored value- Compare with a tolerance (
math.isclose, withabs_tolnear zero), sum withmath.fsum, and know thatround()uses round-half-to-even on the stored binary value (round(2.675, 2)is2.67) Decimaldoes base-10 arithmetic with a configurable context (28 significant digits by default, explicit rounding modes,quantizefor cents): the right tool for money, and it must be built from strings or ints, not floatsFractionstores an exact numerator/denominator pair: exact for rational maths, but slower and its denominators can grow without bound- Trade-offs:
floatis hardware-fast and right for science and measurement;DecimalandFractionrefuse or downgrade when mixed with floats
Code / implementation expected: Optional β show the stored value of 0.1, a tolerant comparison, and a money calculation with Decimal and quantize.