在 ActionScript 3 中,Math.floor 的行为是否类似于 Math.round?

3
这里有个问题:
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中未报告的错误。或者……我做错了什么吗?

1
你试过只用32.9吗?可能是因为你试图过于精确,因此它可能会说32.999999999999999 == 33(即因为.9重复== 1)。你尝试过跟踪n吗? - Mike
JavaScript 返回相同的结果,让我相信这是预期的结果,尽管它与 Floor 应该执行的定义不符... 奇怪? - jpea
JavaScript版本:http://jsfiddle.net/jpsJ8/ - jpea
是的,似乎这是AS3与AS2之间一个已知的问题,这篇KB文章不再存在了,但显然它描述了这个问题 - http://www.kirupa.com/forum/showthread.php?t=247416 - jpea
谢谢大家——我无法将n设置为32.9,因为它来自音频文件,这是ActionScript获取音频文件中位置的方式。真遗憾!我的实际n通常像这样:13202.990233456 - macloo
3个回答

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 - 双精度浮点数没有足够的位来存储额外的精度,并且它将被替换为最接近的值。请注意,这不是算术上最接近的值,而是按照标准定义的值。
建议阅读:http://en.wikipedia.org/wiki/Machine_epsilon

1

就像其他人所建议的那样,这不是一个错误。如果您有n = 32.999999999999996,它会向下舍入为32。如果您有n = 32.999999999999997,那么它与n = 33相同,因此不能实际向下舍入。


1
您刚刚遇到了困扰“所有”语言的现象。浮点数在二进制中非常难以表示,因此在使用它们时可能会失去精度。
var p:int = 0;
var n:Number = 0;
n = 32.999999999999999;
p = Math.floor(n);
trace(p); // returns 33 

在这种情况下,底层计算机将n读取为等于33,远在您尝试调用Math.floor之前。

有关更多信息,请参见浮点数的这篇维基百科文章,其中有关准确性的部分


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接