今天被老師問到1/0 , 1.0/0 , 1/0.0 , 1.0/0.0
原來之前還是沒有掌握的細節問題啊~~~~ 好好的啃一下。。。。。。。!!!!!!!!!!!!!!!!!!!!!
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。這條規則是非常合理的,但是它卻具有奇怪的結果。例如,下面的程式將列印false:
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 negZero=-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的比較來說,==是更好的選擇。
更有趣的事:
double i = 1.0 / 0; System.out.println(i); //InfinitySystem.out.println(i + 1); //InfinitySystem.out.println(i == i + 1); //truei = 0.0 / 0;System.out.println(i); //NaNSystem.out.println(i + 1); //NaNSystem.out.println(i == i + 1); //false