Compensated Summation with Kahan
Reduce floating-point drift with Kahan and Neumaier compensated summation, and see where plain left-to-right addition loses a value.
Code
def kahan_sum(values: list[float]) -> float:
total = 0.0
compensation = 0.0
for value in values:
adjusted = value - compensation
updated = total + adjusted
compensation = (updated - total) - adjusted
total = updated
return total
def neumaier_sum(values: list[float]) -> float:
total = 0.0
compensation = 0.0
for value in values:
updated = total + value
if abs(total) >= abs(value):
compensation += (total - updated) + value
else:
compensation += (value - updated) + total
total = updated
return total + compensation
if __name__ == "__main__":
values = [1e16, 1.0, -1e16, 1.0]
print("naive:", sum(values))
print("kahan:", kahan_sum(values))
print("neumaier:", neumaier_sum(values))
Report a problem with this exampleOpens a pre-filled issue on GitHub.