← notes

Percent change: the sign convention and the zero denominator

Nov 21, 2018

Two small Ruby utilities, one of which has a bug that outlives beginners.

celsius-to-fahrenheit.rb does what it says. percent-change.rb computes `-(x

  • y) / y`, multiplies by 100 and rounds to two places.

The formula is correct and written in a way that hides itself. -(x - y) / y is the same as (y - x) / y, and the second form reads as what it is: the change divided by the original. The leading negation makes every reader stop and check, a cost paid repeatedly for no benefit.

The bug is y being zero. Ruby’s float division gives Infinity or NaN and does not complain, so the script prints NaN and exits successfully. Percent change from zero is genuinely undefined rather than merely awkward, and the right behaviour is to say so rather than emit a float that ends up in a spreadsheet.

The thing worth carrying forward is that percent changes are asymmetric and people reason as though they are not. Fifty to a hundred is up 100%; a hundred back to fifty is down 50%. The same movement gives different magnitudes by direction, which is why averaging percent changes is invalid and a series of them cannot be summed. That trips up people well past this level.