2

Why are the two sums returning different values? In fact, if 0.1 is summed up 10 times in IEEE arithmetic, the result should not be exactly 1. It could be that np.sum() groups the sum differently, so that by chance the result is exactly 1. But is there is doc about this (besides studying the source code)? Surely, numpy isn't rounding off the result. And AFAIK, it is also using IEEE double floating point.

import numpy as np
​
print(1-sum(np.ones(10)*0.1))
print(1-np.sum(np.ones(10)*0.1))

-----

1.1102230246251565e-16
0.0
Rene
  • 3,746
  • 9
  • 29
  • 33
  • 1
    Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – esqew Feb 09 '22 at 20:25
  • Does this answer your question? [Python's sum vs. NumPy's numpy.sum](https://stackoverflow.com/questions/10922231/pythons-sum-vs-numpys-numpy-sum) – ddejohn Feb 09 '22 at 20:27
  • pssibly relevant: https://github.com/numpy/numpy/issues/8786 – Lucas Roberts Feb 09 '22 at 20:31

1 Answers1

4

Sorry, I found the solution in the docs. The algorithm of numpy.sum() is indeed more clever:

For floating point numbers the numerical precision of sum (and np.add.reduce) is in general limited by directly adding each number individually to the result causing rounding errors in every step. However, often numpy will use a numerically better approach (partial pairwise summation) leading to improved precision in many use-cases. This improved precision is always provided when no axis is given. When axis is given, it will depend on which axis is summed. Technically, to provide the best speed possible, the improved precision is only used when the summation is along the fast axis in memory. Note that the exact precision may vary depending on other parameters. In contrast to NumPy, Python’s math.fsum function uses a slower but more precise approach to summation. Especially when summing a large number of lower precision floating point numbers, such as float32, numerical errors can become significant. In such cases it can be advisable to use dtype="float64" to use a higher precision for the output.

See https://numpy.org/doc/stable/reference/generated/numpy.sum.html

ddejohn
  • 8,775
  • 3
  • 17
  • 30
Rene
  • 3,746
  • 9
  • 29
  • 33