Math.floor 是不是像 ActionScript 3 中的 Math.round 一样?
Posted
技术标签:
【中文标题】Math.floor 是不是像 ActionScript 3 中的 Math.round 一样?【英文标题】:Is Math.floor acting like Math.round in ActionScript 3?Math.floor 是否像 ActionScript 3 中的 Math.round 一样? 【发布时间】:2011-07-10 10:20:01 【问题描述】:问题来了:
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 中未报告的错误。还是……我做错了什么?
【问题讨论】:
你试过只用 32.9 吗?可能是您试图过于精确,因此可能会说 32.999999999999999 == 33(即,因为 .9 重复 == 1)您是否尝试仅跟踪 n? javascript 返回相同的结果,让我相信这是预期的结果,尽管定义 Floor 应该做什么没有意义......奇怪吗? javascript 版本:jsfiddle.net/jpsJ8 是的,似乎这也是 as3 与 as2 的一个已知问题 - 他们指向的这篇 KB 文章已找不到,但显然它描述了问题 - kirupa.com/forum/showthread.php?t=247416 谢谢大家——我无法制作 n 32.9,因为它来自音频文件,而这就是 ActionScript 在音频文件中获取位置的方式。无赖!我的真实n往往是这样的:13202.990233456 【参考方案1】:首先,这不是bug!!!
您正在使用数字类型double
- [IEEE 浮点算术标准 (IEEE 754)][1]。这意味着您没有精确的数字,而是接近精确值的近似数字。
例如,如果您想在数字 33 附近的双精度尾数中加上或减去可能的最小值,那么您会得到值:
32.999999999999986
32.99999999999999
33.0
33.00000000000001
33.000000000000014
Thy 基本上是 double 值可以具有的 33 左右最接近的值。如果你没有发现差异,那么
32.99999999999999 // closest lower
32.999999999999999 // input value
33.0 // closest higher
现在,当代码被解释或解析为数字时,32.999999999999999
变为 33.0
。同样,如果您打印出32.9999999999999879
,您将得到32.999999999999986
- double 只是没有位来存储该额外精度,它将被替换为最接近的值。再次注意,这不是算术上最接近的,而是标准中定义的。
推荐阅读:http://en.wikipedia.org/wiki/Machine_epsilon
【讨论】:
【参考方案2】:正如其他人所建议的,这不是错误。如果你有n = 32.999999999999996
,它会向下舍入到32。如果你有n = 32.999999999999997
,那么它与n = 33
相同,所以它实际上不能向下舍入。
【讨论】:
【参考方案3】:您刚刚遇到了某种程度困扰所有语言的现象。浮点数真的很难用二进制表示,因此在使用它们时可能会丢失精度。
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
【讨论】:
以上是关于Math.floor 是不是像 ActionScript 3 中的 Math.round 一样?的主要内容,如果未能解决你的问题,请参考以下文章
Math.Floor() 和 Math.Truncate() 之间的区别
Math.floor,Math.ceil,Math.rint,Math.round用法