java中Infinity(無限)和NaN
1、i == i + 1
一個數字永遠不會等於它自己加1?Java 強制要求使用IEEE 754 浮點數算術運算[IEEE 754],它可以讓你用一個double 或float來表示無窮大。正如我們在學校裏面學到的,無窮大加1還是無窮大。
你可以用任何被計算為無窮大的浮點算術表達式來初始化i,例如:
double i = 1.0 / 0.0;
不過,你最好是能夠利用標準類庫為你提供的常量:
double i = Double.POSITIVE_INFINITY;
事實上,你不必將i 初始化為無窮大以確保循環永遠執行。任何足夠大的浮點數都可以實現這一目的,例如:
double i = 1.0e40;
2、i != i
一個數字總是等於它自己? IEEE 754 浮點算術保留了一個特殊的值用來表示一個不是數字的數量[IEEE 754]。這個值就是NaN(“不是一個數字(Not a Number)”的縮寫),對於所有沒有良好的數字定義的浮點計算,例如0.0/0.0,其值都是它。規範中描述道,NaN 不等於任何浮點數值,包括它自身在內[JLS ]。
你可以用任何計算結果為NaN 的浮點算術表達式來初始化i,例如:
double i = 0.0 / 0.0;
同樣,為了表達清晰,你可以使用標準類庫提供的常量:
double i = Double.NaN;
NaN 還有其他的驚人之處。任何浮點操作,只要它的一個或多個操作數為NaN,那麽其結果為NaN
class Test {
public static void main(String[] args) {
double i = 0.0 / 0.0;
System.out.println(i - i == 0);
}
}
總之,float 和double 類型都有一個特殊的NaN 值,用來表示不是數字的數量。
3、NaN與任何數比較均返回false
if( (0 > c) || (0 == c) || (0 < c)){
System.out.println("NaN compared with 0 is not always false.");
}else{
System.out.println("NaN compared with 0 is always false!");
}
註:
Double.NaN == Double.NaN,結果是false。但是,
Double a = new Double(Double.NaN);
Double b = new Double(Double.NaN);]
a.equals(b); //true
4、Float.compare()
而當我們使用Float.compare()這個方法來比較兩個NaN時,卻會得到相等的結果。可以用下面的代碼驗證:
float nan=Float.NaN;float anotherNan=Float.NaN;
System.out.println(Float.compare(nan,anotherNan));
compare()方法如果返回0,就說明兩個數相等,返回-1,就說明第一個比第二個小,返回1則正好相反。
上面語句的返回結果是0。
一般來說,基本類型的compare()方法與直接使用==的效果“應該”是一樣的,但在NaN這個問題上不一致,是利是弊,取決於使用的人作何期望。當程序的語義要求兩個NaN不應該被認為相等時(例如用NaN來代表兩個無窮大,學過高等數學的朋友們都記得,兩個無窮看上去符號是一樣,但不應該認為是相等的兩樣東西),就使用==判斷;如果NaN被看得無足輕重(畢竟,我只關心數字,兩個不是數字的東西就劃歸同一類好了嘛)就使用Float.compare()。
另一個在==和compare()方法上表現不一致的浮點數就是正0和負0(當然這也是計算機表示有符號數字的老大難問題),我們(萬能的)人類當然知道0.0f和-0.0f應該是相等的數字,但是試試下面的代碼:
float zero=0.0f;
System.out.println(zero==negZero);
System.out.println(Float.compare(zero,negZero));
返回的結果是true和-1。看到了麽,==認為正0和負0相等,而compare()方法認為正0比負0要大。所以對0的比較來說,==是更好的選擇。
java中Infinity(無限)和NaN