为啥 Math.round() 为 NaN 参数返回 0?
Posted
技术标签:
【中文标题】为啥 Math.round() 为 NaN 参数返回 0?【英文标题】:Why does Math.round() return 0 for NaN arguments?为什么 Math.round() 为 NaN 参数返回 0? 【发布时间】:2012-04-24 10:04:53 【问题描述】:我认为对 NaN 进行任何数学运算的结果都应该返回一个 NaN,但是 Math.round(Float.NaN) == 0
Math.round() 的这种行为的基本原理是什么?
奇怪的是,C# 的行为不同:http://msdn.microsoft.com/en-us/library/75ks3aby.aspx
【问题讨论】:
正如@pst 所说,它为 NaN 定义的正常行为:“如果参数为 NaN,则结果为 0”。 基本原理是Math.round()
在 NaN 上调用时曾经存在一个错误,它可能会破坏未来对 Math.round()
的调用:bugs.sun.com/bugdatabase/view_bug.do?bug_id=4755500
差别很可能是;在 Java 中,它返回 long
,它不能是 Double.NaN
,而在 C# 中,它返回 double
【参考方案1】:
哈哈。我想打自己的头。
Math.round(double)
返回一个 long 并且 long 不能是 NaN
。替代方案是一个例外。
在 C# 中,结果仍然是 double
。
【讨论】:
问题是关于浮点数的舍入 @HunterMcMillen 是的,long Math.round(double)
是它在 Java 中的定义方式。这个答案解释了为什么它返回0
而不是NaN
。如果是double Math.round(double)
,那么 C# 方式可能更合适...
@Hunter:操作返回 long
。
哈哈,很有趣(也有点悲伤)。该死的,自动装箱(让我感到困惑)【参考方案2】:
Math.round()
定义为(long)Math.floor(a + 0.5d)
。
-
如果
a
是NaN
,那么a+0.5d
是NaN
。
Math.floor()
被委派为 StrictMath.floor()
,当传入 NaN
时返回 NaN
。
将NaN
转换为long
时,返回0
所以最终,归结为为什么将NaN
转换为long
会返回 0。这个问题已在this question 中进行了深入讨论。
【讨论】:
+1 用于深入研究实现!是否有相应功能的 [Open Source JDK] 代码链接? +1 在 Java 7 中,由于这个问题Why Math.round(0.499999999999999917) rounds to 1 on Java 6,这个定义已被删除以上是关于为啥 Math.round() 为 NaN 参数返回 0?的主要内容,如果未能解决你的问题,请参考以下文章
javascript的Math.round()函数为啥不能精确小数点位数,
为啥 Math.Round(2.5) 返回 2 而不是 3?