我需要编写一个函数来检测传入它的数字是否未定义。在ocaml toplevel我发现了一些有趣的东西。
nan = nan;;
这被证实是假的。但后来我发现了更奇特的东西
nan == nan;;
评估为真。 =和==之间有什么区别,以及为什么第一个比较在将两个nans与自己进行比较时返回false?
答案 0 :(得分:5)
正如@Colonel Thirty Two所说,NaN的标准行为不等于它自己。 (这是一个好主意是一个单独的辩论。)
NaN值始终在物理上是相等的,这是不正确的:
# let x = 0.0 /. 0.0;;
val x : float = nan
# x == nan;;
- : bool = false
物理相等==
是一个棘手且依赖于实现的概念。粗略地说,它测试了值的共享,这对于像nan这样的不可变值是不可检测的。如果您确切知道自己正在做什么,则只应在程序中使用它。
<强>更新强>
您可以使用compare
测试NaN:
# let is_nan x = compare x nan = 0;;
val is_nan : float -> bool = <fun>
# is_nan nan;;
- : bool = true
# is_nan (1.0 /. 0.0);;
- : bool = false
# is_nan (0.0 /. 0.0);;
- : bool = true
答案 1 :(得分:3)
指定NaN与任何数字都不同,包括其自身。这是因为它可能有多种表示形式。
你的==在这里工作,因为它验证了这两个值共享相同的内存区域。如果你&#34;生产&#34;那就不会出现这种情况。计算中的NaN。
检测变量NaN-ness的正确方法可以是使用这个小函数:
let is_nan x = FP_nan = classify_float x