Java运算溢出:一个常见陷阱的解析int->long却仍然导致结果溢出

Java运算溢出:一个常见陷阱的解析int->long却仍然导致结果溢出

当我们使用java进行数据运算时,常常会因为没有选择好数据类型而导致到数据溢出,导致程序异常。

正常的数据自动转换

数值型数据转换:byte→short→int→long→float→double

字符型转换为整型:char→int

手动/强制转换

当我们在进行两个int类型的计算时,通常会因为怕数据溢出而对运算结果进行一个手动类型转换。如下:

int b,c;
long a = (long)(b * c);

上述代码是正确的吗?仔细观察上述代码,有大部分人因为习惯或是一种错误的认知将(long)后的式子用括号括起来,认为已经完成的类型转换并且用恰当的数据类型进行接收,现在明确的告诉你上述写法是错误的或者说是无用的。

正确写法如下:

int b,c;
long a = (long)b * c;

分析

让我们分析两种情况:

  1. long a = (long)b * c;

在这种情况下,b首先被强制类型转换为long类型,然后与c进行乘法运算。因为cint类型,在运算时会自动提升为long类型(如前所述,这是因为运算中涉及的另一个操作数是long类型)。这样,运算就在long的范围内进行,相对于int类型,long类型有更大的数值范围,这减少了溢出的可能性。

  1. long a = (long)(b * c);

在这种情况下,bc首先作为int类型进行乘法运算。如果bc的乘积超过了int类型的最大值(),则会发生溢出,此时结果会被截断为一个不正确的int值。只有在乘法运算完成后,这个已经可能溢出的结果才被强制类型转换为long类型。因此,即使最终结果被赋给了一个long类型的变量,如果在乘法运算时发生了溢出,这个错误的结果也无法被纠正。

总结

根据上述分析可知:long a = (long)(b * c);更容易导致溢出,因为它允许在较小的int类型范围内进行乘法运算,而不是在较大的long类型范围内。为了避免溢出,应当优先使用long a =(long)b * c写法。

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容