If you do not know what residue classes are, just read on, it will be explained to the extent needed later on.

The concept of rounding seems familiar, but let us try to grab it a little bit more systematically.

Let us assume a set of numbers and a subset of it, whose elements can be represented in the programming or software environment we are having in mind. We want to use a metric . Usually we have three requirements for :

- Identity of indiscernibles:
- Symmetry:
- Triangular inquation:

Usually the number that we are dealing with can be considered to be within the world of real or complex numbers, we can hence assume that , often even or if we are honest . Then we are usually working with , which is kind of implicitly clear. If you do not know complex numbers, just think of real or even rational numbers, which is the most common case anyway. Off course the concepts for rounding of -adic numbers are really interesting and beautiful, but since I do not want to explain -adic numbers here, I will not extend on this issue.

What is our intuitive understanding of rounding?

Maybe just a map

,

that is chosen with certain constraints for each x in such a way that is minimal.

We need the constraints to enforce uniqueness if multiple values with minimal exist. The classical case of rounding to integral numbers has to answer the question of how to round . If is a subset of the real numbers, which is „usually“ the case, we have ordering. We can choose between the following constraints:

- ROUND_UP
- Z.B. and and
- ROUND_DOWN
- Z.B. and and
- ROUND_CEILING
- Z.B. and and
- ROUND_FLOOR
- Z.B. and and
- ROUND_HALF_UP
- Minimize , but if multiple optimal values exist for , pick the one furthest away from 0, for example and and and
- ROUND_HALF_DOWN
- Minimize , but if multiple optimal values exist for , pick the one closest to 0, for example and and and
- ROUND_HALF_CEILING
- Minimize , but if multiple optimal values exist for , pick the largest, for example and and and
- ROUND_HALF_FLOOR
- Minimize , but if multiple optimal values exist for , pick the smallest, for example and and and
- ROUND_HALF_EVEN
- Minimize , but if multiple optimal values exist for , pick the one with even last digit. Please observe that this constraint is useful in the classical case, but it cannot be generalized. For example: and and and and
- ROUND_UNNECESSARY
- This constraint does not work in the mathematical sense (or only with ugly abusive math formulas), but programmatically we can do that: We try and throw an exception if not .

Usually we are thinking in the decimal system (even though our computers prefer something else, but the computer should serve us and not vice versa..). So we pick a power of ten with , so . Now we simply define

,

which means that contains all numbers of with a maximum of digits after the decimal point. This rounding works quite well with something like LongDecimal in Ruby or BigDecimal in Scala or Java, but BigDecimal offers fewer rounding modes than LongDecimal for Ruby.

Now we look at the residue class rounding. We assume such a power of ten . Then we need an integral number and a set of numbers , we call them residues. Now we define .

That means that if we fill the number with zeros to the given number of places after the decimal point, remove the decimal point and perform a division with residue of this number by , the residue lies in . In this case ROUND_HALF_EVEN can become difficult to implement and ambiguous, so we might need to sacrifice it. But even worse, we have to deal with the case that 0 is not in and provide rules how to round 0. The candidates have self-explanatory names:

- ZERO_ROUND_TO_PLUS
- ZERO_ROUND_TO_MINUS
- ZERO_ROUND_TO_CLOSEST_PREFER_PLUS
- ZERO_ROUND_TO_CLOSEST_PREFER_MINUS
- ZERO_ROUND_UNNECESSARY

An important application of this is and . This is used in Switzerland and probably other currency regions for rounding money amounts to multiples of 5 Rappen (0.05 CHF). This has already been described in „Rounding of Money Amounts„. If we have and we have the usual non-CHF-rounding case. Maybe there are even cases for and . But the concept is more general, if you like to use it.

Pingback: Rounding with sum | Karl Brodowskys IT-Blog