You're misunderstanding what math.fsum
does. It computes the most accurate possible sum of the given inputs (that is, the closest exactly representable value to the exact mathematical sum of the inputs). It does not magically replace its inputs with the numbers you originally thought of.
In your third line above, the input to math.fsum
is a list containing the values 0.1000000000000000055511151231257827021181583404541015625
and 0.200000000000000011102230246251565404236316680908203125
(remember that with binary floating-point, What You See Is Not What You Get; here I'm showing the exact values that Python's using). The exact sum of those two values is 0.3000000000000000166533453693773481063544750213623046875
, and the closest representable IEEE 754 binary64 float to that exact sum is 0.3000000000000000444089209850062616169452667236328125
, which is what you're getting.
You're asking for math.fsum
to behave as though it were given the exact values 0.1
and 0.2
, but it has no way of knowing that that's what you want: it can only operate on the inputs that you give it.
Note that on most machines, addition of two floats will already be correctly rounded, so there's no advantage to using math.fsum
. math.fsum
is intended to remove the accumulation of rounding error involved in summing more than two floats.