Howto round a decimal up or down to the nearest multiple

10 Apr '17

Take me to the code, dammit. (I strongly recommend you look at the explanation. But then I would say that.)

Say you live in a country without 1, 5, or 10 cent coins (or the monetary equivalent), and you need to round a Decimal number to 20 or 25 cents. Unfortunately, the quantize method will only round your number to the argument’s exponent:

>>> from decimal import Decimal
>>> Decimal('0.3').quantize(Decimal('0.2'))
Decimal('0.3')

What we really want is the number rounded to the nearest multiple:

>>> round_up(Decimal('0.3'), Decimal('0.2'))
Decimal('0.4')
>>> round_down(Decimal('0.3'), Decimal('0.2'))
Decimal('0.2')

Luckily, this isn’t too difficult. But before I show the code, I want to walk through the operations we’ll perform. And don’t worry if maths isn’t your strong suit. In these examples, we’ll round 30 cents (0.3) to the nearest 20 cents (0.2), as indicated by the dotted line. First up, rounding down:

Graphical representation of the rounding down maths operations

  1. Rescale the number continuum, so that 0.2 is equal to 1, and 0.3 becomes 1.5
  2. Round down to the nearest integer, so 1.5 becomes 1
  3. Rescale the number continuum, so that 1 is equal to 0.2, i.e. the original scale has been restored

Rounding up is pretty much the same:

Graphical representation of the rounding up maths operations

  1. Rescale the number continuum, so that 0.2 is equal to 1, and 0.3 becomes 1.5
  2. Round up to the nearest integer, so 1.5 becomes 2
  3. Rescale the number continuum, so that 1 is equal to 0.2, i.e. the original scale has been restored

Finally, here’s the code. It even has unit tests, which probe the behaviour over various precision levels, exponents and values.

Python

Newer Older