IEEE 754浮点数学 [英] IEEE 754 floating point math
问题描述
使用IEEE754浮点数(在JavaScript中)时,与以下数学相关的精度损失的风险是什么?
What is the risk of precision loss associated with maths like the following when using IEEE754 floating point numbers (in JavaScript)?
10*.1
即整数乘以有理数.
推荐答案
注意:该问题在发布此答案后很久才进行了编辑,以添加除数"进行更新.
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...
实际上得到保证,具体取决于所涉及的整数和浮点数,这是因为我们使用的内容(以10为底的小数)与实际的IEEE-754浮点数之间不匹配(以2为基数的小数,然后以10为基数供我们使用).正如我们无法在底数10中精确表示10 / 3
一样,有多种底数10不能精确地存储在底数2中.
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.
但是对于您的特定问题:它在3点中断:3 * 0.1
是0.30000000000000004
.
But to your specific question: It breaks at 3: 3 * 0.1
is 0.30000000000000004
.
您甚至不需要乘法,但是加法已绰绰有余,经典示例是0.1 + 0.2
,这也导致了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
.
示例(JavaScript编号为IEEE-754双精度浮点数):
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.
不,那也不安全. :-)因为在以10为底的实际数学中会导致整数的分数值可能无法在IEEE-754的10底中精确表示,因此不准确的情况逐渐蔓延.例如,0.00000000002
演示了此问题:
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.
这篇关于IEEE 754浮点数学的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!