我在Java中有一个double,我想检查它是否为NaN。
做这个的最好方式是什么?
使用静态Double.isNaN(double)方法,或Double的.isNaN()方法。
// 1. static method
if (Double.isNaN(doubleValue)) {
...
}
// 2. object's method
if (doubleObject.isNaN()) {
...
}
简单地做:
if (var == Double.NaN) {
...
}
由于如何定义NaN和浮点数的IEEE标准,还不够。
另一种方法是v!= v。只有NaN自己比较false。但是不要这样做,isNaN的性能要好一百万倍。 :)
这对我没有用。 Double.isNaN(var)虽然工作
@Joren,迟到总比没有好:在可读性方面,使用isNaN确实比使用v!= v好。但是,isNaN方法的源代码与v!= v完全相同。来源:静态公共布尔isNaN(double v){return(v!= v); }
Double.isNaN should be (true)好答案
Double.isNaN(yourVariable)工作
@Joren isNaN只是检查v!= v;)但是看起来更好
使用Java 5:value == Double.NaN不起作用,但是Double.isNaN(value)可以正常工作。
@Rolf号。您会期望的,但事实并非如此。即使d为NaN," d == Double.NaN"也永远不会为真。您不能将其用作检查NaN的方法,而必须使用isNaN
@Timo不确定您要在这里说什么。 isNan的源与语句v != v相等,因此d == Double.NaN与该语句有什么关系?
@Rolf是具体的,我说您不正确。告诉我,v!= v的结果是什么? -注意v是相同的变量
@Rolf号。您不能使用" d == Double.NaN"-它永远不会正确。用代码向自己证明,运行此" System.out.println(" Value =" +(0.0 / 0.0)+"与Nan的比较= +((0.0 / 0.0)== Double.NaN)+"与Nan =" + Double.isNaN((0.0 / 0.0)));"结果->"值= NaN与Nan的比较= false与Nan = true的比较"。
@Rolf NaN是double(基本类型)的有效值。 IEEE坚持(我认为),与VALUE NaN的任何比较都必须始终是错误的,包括与自身的比较。 NaN检查所做的是将双精度值与其自身进行比较,如果恰巧返回false,则它必须是NaN,因为其他任何值都将返回true。 compare(3,3)-> true,compare(1,1)-> true ...等... compare(Nan,Nan)->否。它必须是唯一执行此操作的值,因此OP可以通过说" if(myValue!= myValue)"来查找NaN ... ...但是它看起来很奇怪,并且isNan更好,但是== NaN将永远无法工作。
@Timo,首先,我从未说过d == Double.NaN将起作用。其次,v != v之所以起作用是因为:A. Java标准手册如此,而B.方法isNan使用此方法。
@Timo,因此我仍然不确定您要在此处纠正的内容。除了我从未见过或说过的d == Double.NaN部分,基本上都说了相同的话。
尝试Double.isNaN():
Returns true if this Double value is a Not-a-Number (NaN), false otherwise.
请注意,[Double.isNaN()]将不起作用,因为未装箱的双打没有与之关联的方法。
我以为您不能在Java中的原始类型上调用方法。确实需要是Double.isNan()而不是Double.isNan(),对吗?
Joren,他依靠自动装箱(double被编译器/运行时转换为Double);从1.5开始的新功能。朝这个方向冒险的风险很小;从Double变为double会产生NullPointerExceptions风险。
我认为自动装箱只能将double用作参数,并将其添加到集合中,等等。尝试声明双精度x,然后要求x到isNaN()-给我一个编译器错误。
真的,我怀疑安德鲁(Andrew)只是错过了键入第一个" double"的Shift键。
您可能还想考虑通过Double.isFinite(value)检查值是否有限。 从Java 8开始,在Double类中有了一个新方法,您可以立即检查该值是否不是NaN和无穷大。
/**
* Returns {@code true} if the argument is a finite floating-point
* value; returns {@code false} otherwise (for NaN and infinity
* arguments).
*
* @param d the {@code double} value to be tested
* @return {@code true} if the argument is a finite
* floating-point value, {@code false} otherwise.
* @since 1.8
*/
public static boolean isFinite(double d)
您可以使用var != var检查NaN。 NaN不等于NaN。
编辑:这可能是迄今为止最糟糕的方法。 这很混乱,可读性很差,而且总体上还是不好的做法。
有人可以解释一下反对意见吗?我知道,这种方式非常糟糕,并且isNan的可读性更好,但是可以,对吗?而isNan方法使用它来检查NaN。
我猜这是因为这种方式非常糟糕,而isNaN的可读性更好。
我没有投票给您,但是我认为这里的附加注释将很有用:如果您比较Float或Double这样的包装器,最终将以这种方式比较引用,而不是它们的值,这绝对不是您想要的。
@Battle_Slug感谢您的评论。我确实知道这是一个非常糟糕的主意,但出于完整性考虑,我将其放在此处。
isNan是在后台进行的,但是它如何工作?有什么不等于自己的东西?
@wilmol自定义类方法
方法? 你是说操作员? Double类是否已重载!=运算符?
在这里得到了我的答案:stackoverflow.com/a/8819776/6122976
下面的代码片段将有助于评估保留NaN的原始类型。
double dbl = Double.NaN;
Double.valueOf(dbl).isNaN() ? true : false;
初学者需要一些实际的例子。 因此,请尝试以下代码。
public class Not_a_Number {
public static void main(String[] args) {
// TODO Auto-generated method stub
String message ="0.0/0.0 is NaN.
similarly Math.sqrt(-1) is NaN.";
String dottedLine ="------------------------------------------------";
Double numerator = -2.0;
Double denominator = -2.0;
while (denominator <= 1) {
Double x = numerator/denominator;
Double y = new Double (x);
boolean z = y.isNaN();
System.out.println("y = " + y);
System.out.println("z = " + z);
if (z == true){
System.out.println(message);
}
else {
System.out.println("Hi, everyone");
}
numerator = numerator + 1;
denominator = denominator +1;
System.out.println(dottedLine);
} // end of while
} // end of main
} // end of class
这个例子做的太多了,并且不清楚您要显示的内容。这只是一堆零碎的代码。
作为OP,他是09年问这个问题时的初学者,我可以向您保证,被接受的答案比这个"实际"示例要有用得多。
感谢@ p.g.gajendra babu发布此示例代码。