Do not trust Floating Point: Unterschied zwischen den Versionen

Aus expecco Wiki (Version 2.x)
Zur Navigation springen Zur Suche springen
Zeile 6: Zeile 6:
== An Example ==
== An Example ==


=== Rumps Royal Pain ===
=== Rump's Royal Pain ===


Try to compute the following expression (in your favorite programming language):
Try to compute the following expression (in your favorite programming language):

Version vom 20. Dezember 2021, 10:25 Uhr

Introduction[Bearbeiten]

The essence of this article in one sentence is "Do not blindly trust any result when computing with floating point numbers".

This may sound strange, but you have to be aware all the time, that computations involving floating point numbers are always in danger of being inexact and sometimes completely (absurdly) wrong.

An Example[Bearbeiten]

Rump's Royal Pain[Bearbeiten]

Try to compute the following expression (in your favorite programming language):

333.75y6 + x2(11x2y2 - y6 - 121y4 - 2) + 5.5y8 + x/(2y)

with:

 x = 77617 and y = 33096.

in Smalltalk, this could be written as:

x := 77617.
y := 33096.

(333.75 * (y ** 6)) 
+ ((x ** 2)
   * ((11 * (x ** 2) * (y ** 2))
      - (y ** 6)
      - (121 * (y ** 4))
      - 2))
+ (5.5 * (y ** 8))
+ (x / (2 * y))

or in JavaScript as:

x = 77617;
y = 33096;

(333.75 * (y ** 6)) 
+ ((x ** 2)
   * ((11 * (x ** 2) * (y ** 2))
      - (y ** 6)
      - (121 * (y ** 4))
      - 2))
+ (5.5 * (y ** 8))
+ (x / (2 * y))

when evaluated, the result will be 1.18059162071741e+21.
- which is completely incorrect. The correct (approximated) result is: -0.8273960599..

So not even the sign is correct, but the IEEE value is off by 21 orders of magnitudes!

In Smalltalk/X, you can compute this by using large precision floats; simply write:

x := 77617QL.
y := 33096QL.
...

to get:

-0.827396059946821368141165095479816291999033115784384819



Copyright © 2014-2024 eXept Software AG