(java)a!=a在什么情况下为true?
2010-12-09 10:31
260 查看
目前只发现两种情况:
为何?
对于jdk来说呢,具体实现也是有标准的
根据ieee 754的浮点运算标准来实现,好像在啥地方见过java的某个实现没有遵循这个标准
记不起来了。
以double为例吧
以上是jdk double的部分源程序
NaN和其来例
double c = Double.longBitsToDouble(0x7ff0000000000001L);
System.out.println(Double.isNaN(c));
这里面的c也是NaN
注意是native方法。
注释里面说的很详细了
* If the argument is any value in the range
* <code>0x7ff0000000000001L</code> through
* <code>0x7fffffffffffffffL</code> or in the range
* <code>0xfff0000000000001L</code> through
* <code>0xffffffffffffffffL</code>, the result is a NaN.
这两个范围内的转换成double都是NaN
同时
No IEEE
* 754 floating-point operation provided by Java can distinguish
* between two NaN values of the same type with different bit
* patterns.
这句话说明在java中两个NaN之间无法比较,所以a==a总是false
a!=a也就为true了
double a = Double.NaN; if(a != a) { System.out.println("gg"); } float b = Float.NaN; if(b != b) { System.out.println("gg"); }
为何?
对于jdk来说呢,具体实现也是有标准的
根据ieee 754的浮点运算标准来实现,好像在啥地方见过java的某个实现没有遵循这个标准
记不起来了。
以double为例吧
/** * A constant holding a Not-a-Number (NaN) value of type * <code>double</code>. It is equivalent to the value returned by * <code>Double.longBitsToDouble(0x7ff8000000000000L)</code>. */ public static final double NaN = 0.0d / 0.0; /** * Returns the <code>double</code> value corresponding to a given * bit representation. * The argument is considered to be a representation of a * floating-point value according to the IEEE 754 floating-point * "double format" bit layout. * <p> * If the argument is <code>0x7ff0000000000000L</code>, the result * is positive infinity. * <p> * If the argument is <code>0xfff0000000000000L</code>, the result * is negative infinity. * <p> * If the argument is any value in the range * <code>0x7ff0000000000001L</code> through * <code>0x7fffffffffffffffL</code> or in the range * <code>0xfff0000000000001L</code> through * <code>0xffffffffffffffffL</code>, the result is a NaN. No IEEE * 754 floating-point operation provided by Java can distinguish * between two NaN values of the same type with different bit * patterns. Distinct values of NaN are only distinguishable by * use of the <code>Double.doubleToRawLongBits</code> method. * <p> * In all other cases, let <i>s</i>, <i>e</i>, and <i>m</i> be three * values that can be computed from the argument: * <blockquote><pre> * int s = ((bits >> 63) == 0) ? 1 : -1; * int e = (int)((bits >> 52) & 0x7ffL); * long m = (e == 0) ? * (bits & 0xfffffffffffffL) << 1 : * (bits & 0xfffffffffffffL) | 0x10000000000000L; * </pre></blockquote> * Then the floating-point result equals the value of the mathematical * expression <i>s</i>·<i>m</i>·2<sup><i>e</i>-1075</sup>. *<p> * Note that this method may not be able to return a * <code>double</code> NaN with exactly same bit pattern as the * <code>long</code> argument. IEEE 754 distinguishes between two * kinds of NaNs, quiet NaNs and <i>signaling NaNs</i>. The * differences between the two kinds of NaN are generally not * visible in Java. Arithmetic operations on signaling NaNs turn * them into quiet NaNs with a different, but often similar, bit * pattern. However, on some processors merely copying a * signaling NaN also performs that conversion. In particular, * copying a signaling NaN to return it to the calling method * may perform this conversion. So <code>longBitsToDouble</code> * may not be able to return a <code>double</code> with a * signaling NaN bit pattern. Consequently, for some * <code>long</code> values, * <code>doubleToRawLongBits(longBitsToDouble(start))</code> may * <i>not</i> equal <code>start</code>. Moreover, which * particular bit patterns represent signaling NaNs is platform * dependent; although all NaN bit patterns, quiet or signaling, * must be in the NaN range identified above. * * @param bits any <code>long</code> integer. * @return the <code>double</code> floating-point value with the same * bit pattern. */ public static native double longBitsToDouble(long bits);
以上是jdk double的部分源程序
NaN和其来例
double c = Double.longBitsToDouble(0x7ff0000000000001L);
System.out.println(Double.isNaN(c));
这里面的c也是NaN
注意是native方法。
注释里面说的很详细了
* If the argument is any value in the range
* <code>0x7ff0000000000001L</code> through
* <code>0x7fffffffffffffffL</code> or in the range
* <code>0xfff0000000000001L</code> through
* <code>0xffffffffffffffffL</code>, the result is a NaN.
这两个范围内的转换成double都是NaN
同时
No IEEE
* 754 floating-point operation provided by Java can distinguish
* between two NaN values of the same type with different bit
* patterns.
这句话说明在java中两个NaN之间无法比较,所以a==a总是false
a!=a也就为true了
相关文章推荐
- 什么情况下Java对象才是已经死亡?
- 第2章 Java编程基础——FAQ2.05 super关键字有什么含义?在哪些情况下应用?
- JAVA里面什么情况下用逻辑运算符,什么情况下用位运算符?
- 在什么情况下Java比C++快?
- java中几种Map在什么情况下使用,并简单介绍原因及原理
- 【Java】Java创建String时,什么情况放进String Pool?
- JAVA中抽象类与接口的区别,分别在什么情况下使用它们
- 【java】什么情况下变量不等于自身
- java.io.Serializable引发的问题——什么是序列化?在什么情况下将类序列化?
- java窗口创建程序里.setResizable(false);false与true的区别是什么??
- 【java】什么情况下变量不等于自身
- java在什么情况下触发Full GC
- IsByRef在什么情况下为true?
- Java实际开发中set,Map,List分别用在什么情况
- java 面试题之1+1在什么情况下不等于2 ?
- java中几种Map在什么情况下使用,并简单介绍原因及原理
- java中几种Map在什么情况下使用,并简单介绍原因及原理
- 在什么情况下,Java比C++慢很多?
- java+selenium什么情况下使用List
- java开发线程篇3:同步和异步有何异同,在什么情况下分别使用他们?举例说明。