Python Glossary Русский

all Python 3mathterm

math.fsum

aggregation

An accurate sum of floating-point numbers (free of rounding error).

Syntax

math.fsum(iterable)

Since Python 3.12 the built-in sum() adds floats with error compensation and beats naive addition, but it is still not exact, while fsum() keeps a set of partial sums and rounds only once at the very end — the gap shows up on terms of wildly different magnitude. The price is speed: fsum() is noticeably slower and always hands back a float, even for integer input. It is not the cure for money calculations either — use decimal.Decimal for those.

Examples

import math
# Классическая иллюстрация «sum накапливает ошибку» с Python 3.12 больше НЕ
# работает: встроенная sum() для float считает компенсированной суммой
# (алгоритм Нейманна), поэтому оба ответа точны.
print(sum([0.1] * 10))         # → 1.0
print(math.fsum([0.1] * 10))   # → 1.0
print(sum([0.1, 0.2, 0.3]))       # → 0.6
print(math.fsum([0.1, 0.2, 0.3]))  # → 0.6
import math
# Разница между sum и fsum зависит от версии: компенсация во встроенной sum
# крепнет от релиза к релизу. Этот случай на 3.12/3.13 даёт 0.0, на 3.14 — 1.0,
print(sum([1e100, 1, -1e100]))        # → ?  (0.0 на 3.12/3.13, 1.0 на 3.14)
print(math.fsum([1e100, 1, -1e100]))  # → 1.0 (fsum считает точно)
# поэтому ожидание помечено средозависимым. А fsum точен на любой версии:
print(sum([1, 1e100, -1e100, 1]))        # → 1.0 (порядок слагаемых меняет ответ)
import math
# Устойчивая иллюстрация: здесь sum теряет единицу на ВСЕХ версиях, fsum — нет.
print(math.fsum([1, 1e100, -1e100, 1]))  # → 2.0

See also

Open in the full glossarydocs.python.orgReport an inaccuracy