您的位置:首页 > 产品设计 > UI/UE

(java)a!=a在什么情况下为true?

2010-12-09 10:31 260 查看
目前只发现两种情况:

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了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: