簡(jiǎn)單的說(shuō),比較兩個(gè)int型或long型的數(shù)據(jù)沒有什么問題,可以用==來(lái)判斷,但對(duì)浮點(diǎn)數(shù)(float與double)來(lái)說(shuō),需要對(duì)Float.NaN和0.0這個(gè)兩個(gè)特殊數(shù)字作額外的處理。
Float.NaN嚴(yán)格說(shuō)來(lái)不是一個(gè)數(shù)字(它的字面意思也就是Not a Number),但是因?yàn)檫@個(gè)值可以被保存在一個(gè)float型的變量中(因?yàn)樗3J浅?的結(jié)果),所以暫且當(dāng)它是個(gè)數(shù)字吧。但它與一般的浮點(diǎn)數(shù)有些許不同,就是兩個(gè)NaN用==比較的結(jié)果會(huì)得到false。
可以用下面的代碼驗(yàn)證:
輸出結(jié)果為false
我用另一種除0的方法得到NaN,可以看到使用==判斷仍然得到false。代碼如下:
而當(dāng)我們使用Float.compare()這個(gè)方法來(lái)比較兩個(gè)NaN時(shí),卻會(huì)得到相等的結(jié)果??梢杂孟旅娴拇a驗(yàn)證:
compare()方法如果返回0,就說(shuō)明兩個(gè)數(shù)相等,返回-1,就說(shuō)明第一個(gè)比第二個(gè)小,返回1則正好相反。
上面這兩行語(yǔ)句的返回結(jié)果都是0。
一般來(lái)說(shuō),基本類型的compare()方法與直接使用==的效果“應(yīng)該”是一樣的,但在NaN這個(gè)問題上不一致,是利是弊,取決于使用的人作何期望。當(dāng)程序的語(yǔ)義要求兩個(gè)NaN不應(yīng)該被認(rèn)為相等時(shí)(例如用NaN來(lái)代表兩個(gè)無(wú)窮大,學(xué)過高等數(shù)學(xué)的朋友們都記得,兩個(gè)無(wú)窮看上去符號(hào)是一樣,但不應(yīng)該認(rèn)為是相等的兩樣?xùn)|西),就使用==判斷;如果NaN被看得無(wú)足輕重(畢竟,我只關(guān)心數(shù)字,兩個(gè)不是數(shù)字的東西就劃歸同一類好了嘛)就使用Float.compare()。
另一個(gè)在==和compare()方法上表現(xiàn)不一致的浮點(diǎn)數(shù)就是正0和負(fù)0(當(dāng)然這也是計(jì)算機(jī)表示有符號(hào)數(shù)字的老大難問題),我們(萬(wàn)能的)人類當(dāng)然知道0.0f和-0.0f應(yīng)該是相等的數(shù)字,但是試試下面的代碼:
返回的結(jié)果是true和-1??吹搅嗣?,==認(rèn)為正0和負(fù)0相等,而compare()方法認(rèn)為正0比負(fù)0要大。所以對(duì)0的比較來(lái)說(shuō),==是更好的選擇。
Float.NaN嚴(yán)格說(shuō)來(lái)不是一個(gè)數(shù)字(它的字面意思也就是Not a Number),但是因?yàn)檫@個(gè)值可以被保存在一個(gè)float型的變量中(因?yàn)樗3J浅?的結(jié)果),所以暫且當(dāng)它是個(gè)數(shù)字吧。但它與一般的浮點(diǎn)數(shù)有些許不同,就是兩個(gè)NaN用==比較的結(jié)果會(huì)得到false。
可以用下面的代碼驗(yàn)證:
float nan=Float.NaN;
float anotherNan=Float.NaN;
System.out.println(nan==anotherNan);
float anotherNan=Float.NaN;
System.out.println(nan==anotherNan);
輸出結(jié)果為false
我用另一種除0的方法得到NaN,可以看到使用==判斷仍然得到false。代碼如下:
float overFlow=0.0f/0.0f;
System.out.println(overFlow);
System.out.println(nan==overFlow);
System.out.println(overFlow);
System.out.println(nan==overFlow);
而當(dāng)我們使用Float.compare()這個(gè)方法來(lái)比較兩個(gè)NaN時(shí),卻會(huì)得到相等的結(jié)果??梢杂孟旅娴拇a驗(yàn)證:
System.out.println(Float.compare(nan,anotherNan));
System.out.println(Float.compare(nan,overFlow));
System.out.println(Float.compare(nan,overFlow));
compare()方法如果返回0,就說(shuō)明兩個(gè)數(shù)相等,返回-1,就說(shuō)明第一個(gè)比第二個(gè)小,返回1則正好相反。
上面這兩行語(yǔ)句的返回結(jié)果都是0。
一般來(lái)說(shuō),基本類型的compare()方法與直接使用==的效果“應(yīng)該”是一樣的,但在NaN這個(gè)問題上不一致,是利是弊,取決于使用的人作何期望。當(dāng)程序的語(yǔ)義要求兩個(gè)NaN不應(yīng)該被認(rèn)為相等時(shí)(例如用NaN來(lái)代表兩個(gè)無(wú)窮大,學(xué)過高等數(shù)學(xué)的朋友們都記得,兩個(gè)無(wú)窮看上去符號(hào)是一樣,但不應(yīng)該認(rèn)為是相等的兩樣?xùn)|西),就使用==判斷;如果NaN被看得無(wú)足輕重(畢竟,我只關(guān)心數(shù)字,兩個(gè)不是數(shù)字的東西就劃歸同一類好了嘛)就使用Float.compare()。
另一個(gè)在==和compare()方法上表現(xiàn)不一致的浮點(diǎn)數(shù)就是正0和負(fù)0(當(dāng)然這也是計(jì)算機(jī)表示有符號(hào)數(shù)字的老大難問題),我們(萬(wàn)能的)人類當(dāng)然知道0.0f和-0.0f應(yīng)該是相等的數(shù)字,但是試試下面的代碼:
float negZero=-0.0f;
float zero=0.0f;
System.out.println(zero==negZero);
System.out.println(Float.compare(zero,negZero));
float zero=0.0f;
System.out.println(zero==negZero);
System.out.println(Float.compare(zero,negZero));
返回的結(jié)果是true和-1??吹搅嗣?,==認(rèn)為正0和負(fù)0相等,而compare()方法認(rèn)為正0比負(fù)0要大。所以對(duì)0的比較來(lái)說(shuō),==是更好的選擇。
答案是1,而不是-1,博主寫錯(cuò)了