14

最近我遇到了几种语言的错误/功能。我对它是如何引起的有一个非常基本的知识(我想要一些详细的解释),但是当我想到这些年来我必须犯的所有错误时,问题是我如何才能确定“嘿,这可能会导致一个荒谬的错误,我最好使用任意精度函数“,其他语言确实有这个错误(以及那些没有的,为什么)。另外,为什么 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                                                    
4

7 回答 7

33

每个计算机科学家都应该知道的关于浮点运算的知识

于 2011-06-22T11:40:43.627 回答
7

这不是语言问题。这是浮点运算的一般问题。

于 2011-06-22T11:41:00.530 回答
5

停止使用浮点数。不完全是。

于 2011-06-22T11:40:38.917 回答
3

数字的浮点表示不准确

在 Python 中,int将向零方向的浮点数截断为最接近的整数。 (int)在 PHP、parseIntJavascript 和to_iRuby 中做同样的事情。

这不是错误;这就是这些功能的工作方式。

例如,来自Python 的文档int

浮点数到整数的转换会截断(趋向于零)。

于 2011-06-22T11:41:32.480 回答
1

这是一个与浮点表示有关的已知问题,您可以在此处找到更多信息:

http://en.wikipedia.org/wiki/IEEE_754-2008

具体问题是7.9在转为int的同时会直接转(trunc)为7。在 Python 中,您可以通过以下方式解决此问题:

int( round(((0.1+0.7)*10)) )

...在其他语言中也是如此。

但是,是的,在许多情况下这可能是一个问题。例如,对于工资单程序来说,浮点数不够可靠。

也许其他人可以给你其他提示。无论如何,这会有所帮助。

于 2011-06-22T11:45:25.107 回答
1

使用decimal模块:

>>> int((decimal.Decimal('0.1')+decimal.Decimal('0.7'))*10)
8
于 2011-06-22T11:50:01.000 回答
0

PHP 默认使用浮点数,需要手动转换为整数。

您应该了解浮点运算。这里的其他帖子提供了足够的链接。

就我个人而言,我使用 round/ceil/float 取决于我的期望,而不是 int

$a = (int) round((0.7 + 0.1) * 10);
于 2011-06-22T11:45:21.320 回答