Am 28.06.22 um 23:18 schrieb Alexandru:
> Rich schrieb am Dienstag, 28. Juni 2022 um 23:14:28 UTC+2:
>> Alexandru <
alexandr...@meshparts.de> wrote:
>>> Why is this result not zero?
>>>
>>> set x -9408.8
>>> puts [expr {$x*$x + $x*$x + $x*$x - $x*$x - $x*$x - $x*$x}]
>>>
>>> This is a simplified demo of a more complex equation:
>>>
>>> set x -9408.8
>>> set y -9408.8
>>> set z -9408.8
>>> puts [expr {($x*$x + $y*$y + $z*$z - $x*$y - $y*$z - $z*$x)}]
>> See
https://floating-point-gui.de/ (and read most of the material
>> there).
>>
>> What you are seeing is /normal/ for binary floating point math.
>
> Thank you all.
> I actually aware of those numerical issues.
> But 1e-8 suprized me alot, because it's actually a large number in my opinion.
Yes it seems large but double precision FP is in the order of 10^-16.
When you square your number which is ~10^4, you get 10^8, and then you
subtract two similar numbers of ~10^8 from each other, therefore the
result is 16 orders of magnitude smaller, hence 10^-8. If you had used a
number which is perfectly representable, like -9408.5, then the result
is exact.
> I wonder, if same operation in C would give better results.
> Another intersting thing, changing order of terms, leads to clean zero:
C is not magic, it uses the same evaluation for double precision floats,
both use the FPU (nowadays SSE instructions) to do math on 64bit binary
IEEE floats.
You could use some higher precision library (which then runs, obviously,
slower) and raise the number of digits. If you have a running sum with
multiple terms, then there are some algorithms to improve the accuracy.
One of them is Kahan summation:
https://en.wikipedia.org/wiki/Kahan_summation_algorithm
You could try if that improves the situation. Also, I don't know where
the expression comes from, but if it has to do with 3D rotation, then
e.g. quaternion rotation is an algorithm which accumulates less error
with successive rotations than matrix rotation etc.
Christian