`

浮点数0.57 0.58 造出的坑爹问题

阅读更多

看下面代码:

console.log(parseInt(0.59*100),parseInt(0.58*100),parseInt(0.57*100),parseInt(0.56*100))

 你猜输出什么呢?

 

在 PHP里面

var_dump(intval(0.59 * 100));
var_dump(intval(0.58 * 100));
var_dump(intval(0.57 * 100));
var_dump(intval(0.56 * 100));

 

不知道py里面是不是这样...

 

哈哈哈 为什么 只有 0.57/0.58 这个呢

2
5
分享到:
评论
9 楼 justjavac 2013-05-10  
vb2005xu 写道
果然如此,你的http://justjavac.iteye.com/blog/1724438 让我受益很多啊

你的博文也很不错,共同交流,共同进步。
8 楼 vb2005xu 2013-05-10  
果然如此,你的http://justjavac.iteye.com/blog/1724438 让我受益很多啊
7 楼 justjavac 2013-05-09  
vb2005xu 写道
此处的精度问题 为什么 只有0.57/0.58 这两个有问题 而 0.59 0.56 等却没有问题呢

这几个都有问题,只是你选择的乘数100,太小了,问题没有显现出来而已。
6 楼 justjavac 2013-05-09  
vb2005xu 写道
此处的精度问题 为什么 只有0.57/0.58 这两个有问题 而 0.59 0.56 等却没有问题呢


还是这篇文章,代码之谜(五)- 浮点数(谁偷了你的精度?),仔细品味一下。如果把它们写出2进制浮点数,就明白了。其实一个令人震惊的事实就是,99%的数不能够被精确的表示为浮点数。


0.56*10056.00000000000001
0.57*10056.99999999999999
0.58*10057.99999999999999
0.59*10059


看到上面的表格,好像 0.59 可以精确表示一样,其实不然,首先,0.59的末尾是9,意味着他不可能被转换成有限二进制小数(why?)。肯定是一个循环小数,如果循环节超过了浮点数的尾数,那么就给人一种可以精确表示的假象。(设计到很多公式,就不写了,以后专门写博客讨论)。

运行: 0.59*1e71
结果: 5.9e+70

运行: 0.59*1e72
结果: 5.899999999999999e+71

看出端倪来了吗?
5 楼 vb2005xu 2013-05-09  
此处的精度问题 为什么 只有0.57/0.58 这两个有问题 而 0.59 0.56 等却没有问题呢
4 楼 justjavac 2013-05-09  
vb2005xu 写道
不知道py里面是不是这样


0.58*100 = 57.99999999999999 是超越语言的,是IEEE规定的浮点数的运算标准,一般情况下,57.99999999999999会四舍五入到58。其实浮点数遇到5后,不一定总是入,具体可以看浮点数规范。

为什么结果是 57 呢,主要是因为 parseInt 和 intval 函数。他们的规则是,从第一个数字开始,知道遇到不是数字的字符,结束。

所以

parseInt("012") 结果是 10 (不要惊讶,0开头的数字是八进制)
parseInt("12abc") 结果是 12 (不解释)
parseInt("12.123") 结果是 12

12e5 是多少呢?科学计数法,结果是 1200000(12后面五个0)

parseInt("12e5") 的结果呢?结果是12,因为e字符不是数字,所以后面的都忽略了。


parseInt("abc") 这个呢?结果是0?如果是0的话,你让 parseInt("0abc") 情何以堪啊!结果是 NaN (Not a Number)。
3 楼 justjavac 2013-05-09  
0.58*100 的结果是 57.99999999999999
parseInt 并不是四舍五入,所以就变成了 57。
2 楼 justjavac 2013-05-09  
1 楼 lukeme 2013-05-08  
确实奇怪,结果竟然是
59 57 56 56

相关推荐

Global site tag (gtag.js) - Google Analytics