最近我遇到了几种语言的错误/功能。我对它是如何引起的有一个非常基本的了解(我想要一些详细的解释),但是当我想到多年来我必须犯下的所有错误时,问题是如何确定“ 嘿,这可能会导致一个荒谬的bug,我最好使用任意精确函数 “,其他语言确实有这个bug(而那些没有,为什么)。另外,为什么0.1 + 0.7这样做,而0.1 + 0.3不这样做,还有其他众所周知的例子吗?
PHP
//the first one actually doesn't make any sense to me,
//why 7 after typecast if it's represented internally as 8?
debug_zval_dump((0.1+0.7)*10); //double(8) refcount(1)
debug_zval_dump((int)((0.1+0.7)*10)); //long(7) refcount(1)
debug_zval_dump((float)((0.1+0.7)*10)); //double(8) refcount(1)
的Python:
>>> ((0.1+0.7)*10)
7.9999999999999991
>>> int((0.1+0.7)*10)
7
使用Javascript:
alert((0.1+0.7)*10); //7.999999999999999
alert(parseInt((0.7+0.1)*10)); //7
红宝石:
>> ((0.1+0.7)*10).to_i
=> 7
>>((0.1+0.7)*10)
=> 7.999999999999999
答案 0 :(得分:32)
答案 1 :(得分:7)
这不是语言问题。这是float point arithmetic的一般问题。
答案 2 :(得分:5)
Stop using floats。不,真的。
答案 3 :(得分:3)
floating point representation of numbers is not exact。
在Python中,int截断浮动朝零到最接近的整数。
PHP中为(int)
,Javascript中为parseInt
,Ruby中为to_i
也是如此。
这不是一个错误;这就是这些功能的运作方式。
例如,来自the docs的Python int
:
浮点数的转换 整数截断(朝零)。
答案 4 :(得分:1)
这是一个与浮点表示有关的已知问题,您可以在此处找到更多信息:
http://en.wikipedia.org/wiki/IEEE_754-2008
具体问题是7.9将直接转换(截断)为7,同时将其转换为int。在Python中,您可以使用以下方法解决此问题:
int( round(((0.1+0.7)*10)) )
......和其他语言类似。
但是,在许多情况下,这可能是一个问题。例如,浮点数对于工资单程序来说不够可靠。
也许其他人可以给你其他提示。无论如何,Hpe有帮助。
答案 5 :(得分:1)
使用decimal
模块:
>>> int((decimal.Decimal('0.1')+decimal.Decimal('0.7'))*10)
8
答案 6 :(得分:0)
PHP默认使用浮点数,您需要手动转换为整数。
您应该了解浮点运算。这里的其他帖子提供了足够的链接。
我个人使用round / ceil / float取决于我期望的而不是int
$a = (int) round((0.7 + 0.1) * 10);