Skip to main content
4 of 4
added 314 characters in body
user avatar
user avatar

A "stateless" approach (i.e. the same value always rounding the same way) cannot work. To see why, consider a sum of always the same number. After n terms, the error will equal n times the error between the original and rounded value, and this grows unboundedly.

A simple solution is to use "error propagation", as done in the image dithering algorithms. You just keep the fractional part of the sum, and update it with the fractional part of the next number. If the new fractional part exceeds 1, transfer this unit to the rounded value.

E.g.

2.3 + 4.4 + 6.4 + 3.1 ->

2, error = 0.3;

4, error = 0.7;

6, error = 1.1, which becomes 7, error 0.1

3, error = 0.2

Note that this gives the same output as the simple method of effectively computing the partial sums, rounding to integer and taking the difference with the previous sum (but for accumulation of floating-point errors in the long run).

2.3 + 4.4 + 6.4 + 3.1 -> 0, 2.3, 6.7, 13.1, 16.2 -> 0, 2, 6, 13, 16 -> 2 + 4 + 7 + 3

Note that I used truncation, but rounding also works.


Update:

If the distribution of the fractional parts is uniform, rounding to the nearest integer will work on average. In practice, this is rarely the case, because of Benford's law, so a bias can be expected. You can determine it experimentally, hoping that your data sets are homogeneous. In the long run, drifts are to be feared anyway.

user16034