问题在于:
var p:int = 0;
var n:Number = 0;
n = 32.999999999999999;
p = Math.floor(n);
trace(p); // returns 33
n = 32.11111111111111;
p = Math.floor(n);
trace(p); // returns 32
我希望这两个都返回32.我已经搜索过了,这似乎是AS3中未报告的错误。或者......我做错了什么?
答案 0 :(得分:5)
首先,这不是一个错误!!!
您正在使用数字类型double
- [IEEE浮点运算标准(IEEE 754)] [1]。这意味着您没有确切的数字,但接近精确值的近似数字。
例如,如果要将最小可能值加到或减去数字33左右的双值尾数,则得到值:
32.999999999999986
32.99999999999999
33.0
33.00000000000001
33.000000000000014
你的本质上是最接近33的双值可以得到的值。如果你没有发现差异,那么
32.99999999999999 // closest lower
32.999999999999999 // input value
33.0 // closest higher
当代码被解释或解析为数字时,32.999999999999999
变为33.0
。以同样的方式打印32.9999999999999879
得到32.999999999999986
- double只是没有用于存储额外精度的位,并且它将被替换为最接近的值。再次注意,这在算术上并不是最接近的,而是在标准中定义的。
答案 1 :(得分:1)
你刚刚遇到了在某种程度上困扰所有语言的现象。浮点数很难用二进制表示,因此在使用它们时可能会失去精度。
var p:int = 0;
var n:Number = 0;
n = 32.999999999999999;
p = Math.floor(n);
trace(p); // returns 33
在您尝试调用Math.floor之前很久,底层计算机读取的n等于33。
有关详细信息,请参阅This wikipedia article about Floating Point, in the section about accuracy
答案 2 :(得分:1)
正如其他人所说,这不是一个错误。如果你有n = 32.999999999999996
它会向下舍入到32.如果你有n = 32.999999999999997
那么它与n = 33
相同,所以它实际上不能向下舍入。