int((0.1 + 0.7)* 10)= 7在几种语言。 如何防止这一点?
最近我遇到了几种语言的错误/function。 我有一个非常基本的知识,它是如何引起的(我想要一些详细的解释),但是当我想到我多年来一直想要的所有错误时,问题是我怎样才能确定“ 嘿,这可能会导致一个riddiculous的错误,我最好使用任意的精度函数 “,其他语言有这个错误(和那些谁不, 为什么 )。 另外,为什么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
ruby:
>> ((0.1+0.7)*10).to_i => 7 >>((0.1+0.7)*10) => 7.999999999999999
计算机科学家应该知道什么是浮点运算
这不是一个语言问题。 这是浮点运算的一般问题。
停止使用浮游物 。 不完全是。
数字的浮点表示不准确 。
在Python中, int截断向零移动到最接近的整数。 (int)
,Javascript中的parseInt
和Ruby中的to_i
做同样的事情。
这不是一个错误; 这些function是如何工作的。
例如,从Python的int
文档 :
浮点数转换为整数截断(趋近于零)。
这是一个与浮点表示有关的已知问题,您可以从中find更多信息:
http://en.wikipedia.org/wiki/IEEE_754-2008
具体的问题是7.9会直接转换(trunc)到7,同时将其转换为int。 在Python中你可以用下面的方法解决
int( round(((0.1+0.7)*10)) )
…在其他语言中也是如此
但是,是的,在许多情况下这可能是一个问题。 例如,浮点数对于工资计划来说不够可靠。
也许别人可以给你其他提示。 无论如何,这个帮助。
使用decimal
模块:
>>> int((decimal.Decimal('0.1')+decimal.Decimal('0.7'))*10) 8
PHP默认使用浮点数,你需要手动转换为整数。
你应该知道浮点运算。 这里的其他post提供了足够的链接。
就我个人而言,我使用round / ceil / float取决于我期望的而不是int
$a = (int) round((0.7 + 0.1) * 10);