关于Double和Float的isNaN方法

源码为:

public static boolean isNaN(float v) {

        return (v != v);

}

而自己写的代码为:

Float v= 0.0f / 0.0f;

System.out.println(Float.isNaN(v));

 ystem.out.println((v != v));

下面打印的为:

true

false

问题:同样打印的是“v != v”为什么会不一样


第一种解释:
测试你的代码:

public class TestFloat{
 public static void main(String args[]){
   Float v = 0.0f / 0.0f;
   System.out.println(Float.isNaN(v));
   System.out.println((v != v));
 }
} 

输出:

true
false 

几点说明:

  1. NaN,是 Not a Number 的缩写。
  2. Float v = 0.0f/0.0f;
    这里,试图以浮点 0.0f 做分母,结果可能不会导致算数运算错误,即不会抛出算数异常。这是由于分子和分母都是两个通过浮点型表示的数,并且,这两个数如此之小,以致计算机已经不可能将它们与零区分。得出的结果是一个JAVA 包装类 Float 的对象 v,是一个非数字 (NaN) 值。
    Trying to divide by the floating point value 0.0f might not be a consequence of an incorrect algorithm. NaN essentially means that the answer to your calculation could not be determined because it involved the division of two numbers so small it was impossible for the computer to distinguish them from 0.
  3. static boolean isNaN(float v)
    如果 此 Float 值是一个非数字 (NaN) 值,则返回 true,否则返回 false。
  4. System.out.println(Float.isNaN(v));
    v 是包装类 Float 的一个实体(对象), 不是数字,因此调用 isNan(float v), 返回 true。
  5. System.out.println((v != v));
    (v != v) , 比较的是 v (Float 类对象 v 的引用), 是否不等, 即 v 是否不是它自己。 v 和 v, 同一个引用,当然相等(当然不会不等)。故返回 false。

第二种解释:
重复一下 楼主的命题。

已知:java.lang.Float 的静态方法 isNaN

public static boolean isNaN(float v) 的源码是:

public static boolean isNaN(float v) {

        return (v != v);

}

结果发现,调用JAVA 类库的这个静态方法(java.lang.Float.isNan(float v)),与直接使用逻辑判断 (v != v), 结果不一。这是为啥?

回答:

这取决于 isNan 方法的参数类型:

如果 isNan 方法的参数类型是 float,就意味着以浮点型的前提(观点)来判断 (v != v)。 由于 v 是由两个非常小的(难以将其区别于零的)浮点数 (0.0f)作为分子和分母构成的对象,已经不是浮点型数值了,于是判为不等,返回 true 。
如果 isNan 方法的参数类型是 Float,就意味着以浮点型的包装类 Float 的对象为前提(观点)来判断 (v != v)。 此刻,v 是同一个对象的引用,(v != v)当然不成立,故返回 false 。
直接比较同一个对象的引用:(v != v), 结果当然是 false.

有代码为证:

public class Test{

public static boolean isNaN_f(float v) {	
        return (v != v);
}
public static boolean isNaN_F(Float v) {	
        return (v != v);
}
 
public static void main(String args[]){
	Float v = 0.0f / 0.0f;
	System.out.println("参数为 float, 返回: " + isNaN_f(v));
	System.out.println("参数为 Float, 返回: " + isNaN_F(v));
	System.out.println("比较对象的引用: " + (v != v));
	}
}

输出:

参数为float, 返回: true
参数为 Float, 返回: false
比较对象的引用: fals

同理,可以验证 java.lang.Double 类的成员方法 isNan(double v):

public class Test_Double{

public static boolean isNaN_d(double v) {	
        return (v != v);
}
public static boolean isNaN_D(Double v) {	
        return (v != v);
}
 
public static void main(String args[]){
	Double v = 0.0 / 0.0;
	System.out.println("使用 java.lang.Double 类的成员方法 isNaN():" + v.isNaN(v));
	System.out.println("参数为 double, 返回: " + isNaN_d(v));
	System.out.println("参数为 Double, 返回: " + isNaN_D(v));
	System.out.println("比较对象的引用: " + (v != v));
	}
} 

输出:

java.lang.Double 类的成员方法 isNaN():true
参数为 double, 返回: true
参数为 Double, 返回: false
比较对象的引用: false

你可能感兴趣的:(java)