简单的说,比较两个int型或long型的数据没有什么问题,可以用==来判断,但对浮点数(float与double)来说,需要对float.nan和0.0这个两个特殊数字作额外的处理。
float.nan严格说来不是一个数字(它的字面意思也就是not a number),但是因为这个值可以被保存在一个float型的变量中(因为它常常是除0的结果),所以暂且当它是个数字吧。但它与一般的浮点数有些许不同,就是两个nan用==比较的结果会得到false。
可以用下面的代码验证:
float nan=float.nan;
float anothernan=float.nan;
system.out.println(nan==anothernan);
输出结果为false
我用另一种除0的方法得到nan,可以看到使用==判断仍然得到false。代码如下:
float overflow=0.0f/0.0f;
system.out.println(overflow);
system.out.println(nan==overflow);
而当我们使用float.compare()这个方法来比较两个nan时,却会得到相等的结果。可以用下面的代码验证:
system.out.println(float.compare(nan,anothernan));
system.out.println(float.compare(nan,overflow));
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的比较来说,==是更好的选择。