为什么在浮点算术中0.9999999999999999!= 1但0.9999999999999999 + 1 == 2

时间:2018-07-04 09:23:16

标签: python floating-point precision

我知道这一定是另一个浮点精度问题:令x为0.9999999999999999。然后x + 1 == 2用浮点运算,但是x!=1。这是什么情况?以下是我在ipython控制台上尝试过的内容。

 for (var i = 0; i < data.real.length; i++) {
    var o2 = i == data.real.length - 1 ? 0 : i + 1;
    var rO1 = data.real[i];
    var rO2 = data.real[o2];
    var fO1 = data.zeroAxis[i];
    var fO2 = data.zeroAxis[o2];

    var curve = new THREE.CatmullRomCurve3([ rO1, rO2, fO1, fO2 ]);

    var points = curve.getPoints(50);
    var geometry = new THREE.BufferGeometry().setFromPoints(points);



    var material = new THREE.LineBasicMaterial({
        color : 0xff0000
    });

    // Create the final object to add to the scene
    var curveObject = new THREE.Line(geometry, material);
    console.log(curveObject)
    this.tb.scene.add(curveObject);
    this.tb.render();
}

[编辑]关于折点浮点计算的现有问题主要与FP表示错误有关,这似乎不是这里的主要原因。

2 个答案:

答案 0 :(得分:2)

0.51.0的间隔中,与1.02.0的间隔中的小数部分相比,您还有一个小数部分0.9999999999 + 1234567890.0 。所以这是预期的。

您可以使用以下示例:

9

第一个加数中有十个数字services@project.gserviceaccount.com

双精度(即64位)(二进制)浮点类型的精度大约为16个十进制数字。因此,只有从大约16位数字的“第一位”(即最高有效位)起才能记住一个数字。

答案 1 :(得分:1)

您使用的浮点格式的有效位数为53位。这意味着它可以将数字表示为一个53位整数乘以或除以2的幂。

0.9999999999999999转换为这种格式时,最接近的可表示值为(2 53 -1)/ 2 53 ,恰好是0.99999999999999988897769753748434595763683319091796875。请注意,分子正好使用53位。

加1时,数学结果将为(2 54 −1)/ 2 53 。分子将具有54位。它不能以浮点格式表示,因此必须四舍五入以适合。两个最接近的可表示值是:

  • (2 54 -2)/ 2 53 =(2 53 -1)/ 2 52
  • (2 54 -0)/ 2 53 = 2。

这两者都与精确的数学结果相去甚远。打破平局的规则是在其有效位的低位使用值为零的值。 (即使我在这里将有效数字表示为整数,但它是浮点格式的“左调整”分数,因此分子1对应于二进制数字1.000000…000 2

因此,将1加到0.9999999999999999时,计算结果必须四舍五入到2。