Frage
Kann jemand bitte erklären, warum int (0.4 * 10.0)
4
ist noch int ((2.4 - 2.0) * 10.0)
ist 3
?
Und dann auch erklären, bitte, wie 4
zu bekommen. d Muss ich wirklich int (System.Math.Round((2.4 - 2.0) * 10.0))
tun?
Es ist einfach so hässlich für etwas, das so einfach sein sollte.
Lösung
Die doppelte Darstellung von 2,4-2,0 ist ,399999999999. Wenn Sie eine Zahl konvertieren die Dezimalstellen in int abgeschnitten wird, so wird 3,999999999 abgeschnitten 3.
Andere Tipps
Und dann bitte auch erklären, wie man 4 h muss ich tun, um wirklich
int (System.Math.Round ((2,4-2,0) * 10,0))
Es ist nur so hässlich für etwas, das so einfach sein sollte.
Natürlich nicht nur definieren
let round x = int System.Math.Round(x)
Eigentlich in .NET gibt es einen decimal
Datentyp, die Sie mit diesem Problem helfen können, wenn Ihre Zahlen genau wie Dezimalzahlen dargestellt werden.
2.4m - 2.0m == 0.4m
2.4 - 2.0 != 0.4
To covert a float
number to an int
use:
let i = Convert.ToInt32(f)
Floating-point numbers are not infinite precision. Some numbers can be represented perfectly (anything involving powers of two, e.g. 1, 1/2 = 0.5, 1/4 = 0.25, etc.), and others can't (e.g. 1/3 cannot be exactly decomposed into a finite sequence of powers of two). Often, chopping the end of the infinite series causes the encoded version of a number to be slightly smaller than its true value.
Combine this with the fact that the (int) operator truncates rather than rounds, and you can run into cases where an operation that should yield 4.0 results in 3.999999999991 instead, which becomes 3.
Any time you're trying to convert floats/doubles to ints, you want to think carefully about which operator you want to use -- truncating (rounding down), rounding up, or rounding-to-nearest.
Since this is an issue with floating-point representations, this is true not just in F#, but C# and (IIRC) Java and other languages.