IEEE 754 floating point math

后端 未结 1 1290
天涯浪人
天涯浪人 2021-01-27 15:37

What is the risk of precision loss associated with maths like the following when using IEEE754 floating point numbers (in JavaScript)?

10*.1

i.

相关标签:
1条回答
  • 2021-01-27 15:51

    Note: The question was edited to add "that is a divisor of" long after this answer was posted, see below the fold for an update.


    What is the risk of precision loss...

    It's virtually guaranteed, depending on the integer and floating point number involved, because of the mismatch between what we use (fractional numbers in base 10) and what IEEE-754 floating point numbers actually are (fractional numbers in base 2, then represented in base 10 for our use). Just as we can't represent 10 / 3 precisely in base 10, there are various base 10 numbers that cannot be precisely stored in base 2.

    But to your specific question: It breaks at 3: 3 * 0.1 is 0.30000000000000004.

    You don't even need multiplication for it, though, addition is more than sufficient, the classic example being 0.1 + 0.2, which also results in 0.30000000000000004.

    Examples (JavaScript numbers are IEEE-754 double-precision floating point):

    snippet.log(0.1 + 0.2); // 0.30000000000000004
    snippet.log(3 * 0.1);   // Also 0.30000000000000004
    <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
    <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


    Re your addition of "that is a divisor of": I take it you mean where the fractional number relates to the original integer such that the result will be an integer with actual math.

    No, that's not safe either. :-) Because fractional values that would, in real math in base 10, result in an integer may not be precisely represented in IEEE-754's base 10, and so inaccuracies creep in. 0.00000000002, for example, demonstrates this problem:

    snippet.log(200000000000 * 0.00000000002); // 3.9999999999999996
    <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
    <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

    I don't know whether there's a larger value that would introduce the imprecision, but it wouldn't surprise me.

    0 讨论(0)
提交回复
热议问题