从Integer / int / Long / long转换时的双重等式布尔值的准确性

时间:2013-10-30 15:10:22

标签: java double equals equality primitive

如果将以下数据类型转换为Double.equals()测试)或double==测试),则相等性测试的准确性是多少?

  • Long
  • long
  • Integer
  • int

如果相等测试仅在可能的LonglongIntegerint值范围内准确无误,那么此准确度所适用的精确范围是多少?

例如;

Long longTest = Long.MAX_VALUE;
Long longTest2 = Long.MAX_VALUE;
double doubleTest = (double) longTest;
double doubleTest2 = (double) longTest2;
if(doubleTest == doubleTest2) //Is this accurate? 
     return true;

3 个答案:

答案 0 :(得分:0)

考虑如下:

double和long都占用64位存储空间。对于float和int,它是32。

因为在指数上花费了一些位,所以在将long转换为double或int转换为float时,总是存在丢失精度的危险。

唯一的保存事项是int - >双

无论如何,至于你的例子:由于上述原因,double不能以绝对精度持有Long.MAX_VALUE。这将是一个近似值。但是,每次的近似值应该相同,因此您的示例应该返回true。

答案 1 :(得分:0)

尽管Java的创建者可能已经为所有数值类型组合定义了==重载,因此只有具有相同数值的事物才能比较相等[例如,暗示会有是没有float值比较等于16777217],或禁止在任何类型的组合上使用==,其中该运算符不会表现为等价关系,他们没有那些那些的东西。相反,他们认为应该可以将操作数与原始类型的任何组合进行比较,无论这是否有意义,并且这种比较应该使用与任何其他上下文中存在的相同的隐式转换(我真的不喜欢的决定,顺便说一句)

因此,例如, longfloat将执行近似转换为float并进行比较,而不考虑转换中是否丢失任何精度。 floatdouble之间的比较将通过执行到double的精确转换并进行比较来完成。这导致16777216.0f == 16777217和16777217 == 16777217.0,但是167772176.0f!= 16777217.0。有些时候,人们可能想知道float是否是其他值的最佳 float表示,而时间可能想知道它是否是精确表示,但是Java中的类型排名与==运算符回答的问题不一致。

答案 2 :(得分:0)

有几个案例......

如果两个类型都是包装器,则equals总是精确的 - 但请注意,equals是类型敏感的(例如,Integer.equals(Long)总是产生false,无论值如何)。否则...

如果一个类型是包装器而另一个类型是原始类型,则包装器将被取消装箱,并且使用==语义完成比较,两个类型都是从一开始就是基元。

基元的等式(==)对于任何整数类型(byte,short,int,long)都是精确的 - 较小的类型将被转换为较大的类型,然后进行比较。对于char,它会转换为更大的类型但 unsigned

一个操作数与浮点类型(float,double)相等,另一个类型转换为浮点类型,并且在这种情况下可能精度丢失。 Float可以表示精确地具有< = 24个有效位的任何整数值,double具有53位相关精度(由类型中的尾数位数确定,有关脏细节的信息,请参阅IEEE754)。

基本上,float ==(int)N仅在(约)abs(N)<=(1 <&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ; =(1 <52)。如果整数类型中有更多有效位,则当类型转换为float / resp时,最低位丢失。双。由于double有更多的尾数比int可以有重要的位,所以double和int之间的比较在这方面是准确的。