为什么JavaScript中的parseFloat()会产生一致但统一的结果? [英] Why does parseFloat() in JavaScript produce consisant but unitinutive results?

查看:99
本文介绍了为什么JavaScript中的parseFloat()会产生一致但统一的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管提供了有关添加在HTML input中增加浮点值的方法的问题的答案,我碰到了我所知道的是 IEEE浮点数学的常见问题.这是我所看到的示例(带有演示):

While providing an answer to a question about adding a method that increments a float value in an html input, I came across what I know is a common issue with IEEE Floating point math. This is an example (with a demo) of what I am seeing:

<input type="text" name="BoqTextBox" id="BoqTextBox" value="0.001" />
<input type="Button" id='AddButton' value="+" />
<script>
  $('#AddButton').on('click', function () {
    var input = $('#BoqTextBox');
    input.val(parseFloat(input.val(), 10) + 1);
  })
</script>

单击+按钮,首先使输入递增(使用此

Clicking on the + button, causes the input to increment at first like this (using this converter for IEEE Binary Representations):

                     S|   Exp   |      Mantissa
0.001              //0 0111 0101 000 0011 0001 0010 0110 1111
1.001              //0 0111 1111 000 0000 0010 0000 1100 0101
2.001              //0 1000 0000 000 0000 0001 0000 0110 0010
3.001              //0 1000 0000 100 0000 0001 0000 0110 0010
4.0009999999999994 //0 1000 0001 000 0000 0000 1000 0011 0001
5.0009999999999994 //0 1000 0001 010 0000 0000 1000 0011 0001
6.0009999999999994 //0 1000 0001 100 0000 0000 1000 0011 0001
7.0009999999999994 //0 1000 0001 110 0000 0000 1000 0011 0001
8.001              //0 1000 0010 000 0000 0000 0100 0001 1001
9.001              //0 1000 0010 001 0000 0000 0100 0001 1001
10.001             //0 1000 0010 010 0000 0000 0100 0001 1001
... then predictably like this until ...
15.001             //0 1000 0010 111 0000 0000 0100 0001 1001
16.000999999999998 //0 1000 0011 000 0000 0000 0010 0000 1100
17.000999999999998 //0 1000 0011 000 1000 0000 0010 0000 1100
18.000999999999998 //0 1000 0011 001 0000 0000 0010 0000 1100
19.000999999999998 //0 1000 0011 001 1000 0000 0010 0000 1100
... then predictably like this until ...
31.000999999999998 //0 1000 0011 111 1000 0000 0010 00001100
32.001             //0 1000 0100 000 0000 0000 0001 00000110
33.001             //0 1000 0100 000 0100 0000 0001 00000110
... then predictably like that up to 256 (a power of 8 seemed fitting to test) ...

我还不知道为什么这种行为会以这些特定值体现出来,我可以采取哪些逻辑步骤来减轻其影响?四舍五入以用于显示目的,同时将实际的计算值保留在其他位置?

What I don't yet know is why does this behavior manifest itself at those specific values, and what logical steps can I take to mitigate its effects? Rounding for display purposes while keeping the actual calculated value stored someplace else?

推荐答案

您猜想您应该仅在四舍五入后才打印输出.该行为是十进制与amp;之间的差异的结果.二进制基数,因为有些十进制数没有以浮点数的二进制格式精确表示,因此在将其存储为二进制然后再次读取时会损失一些精度.浮点数在CPU中以 1.XXXXX ... XXXX * 2 ^ P 的形式表示,因此从此表格中您可以看到,并非所有十进制数字都具有这样的表示形式,其长度限制为.

As you guessed you should print outputs only after rounding them. That behaviour is the result of difference between decimal & binary base numbers, because there are decimal numbers which don't have exact representation in binary format of floating point numbers, and therefore some accuracy is lost when storing it into binary and then reading it again. Floating point numbers are represented in CPU in the form 1.XXXXX...XXXX * 2^P, so from this form you can see that not all decimal numbers have such representation with limited length of XXXXXX...XXX.

这篇关于为什么JavaScript中的parseFloat()会产生一致但统一的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆