让您很容易忽视的一个整数运算
Java中最普遍应用的基本数据类型数据当数int类型,其再内存中占4字节,取值范围为-2147483648~2147483647,这对一般计算足够了,也正因为如此,才更容易疏忽如下情况。
现在编写一个这样的小程序:如果一个人的心脏每分钟跳动70次,他活到70岁,那么他的心脏总共跳动了多少下?似乎这个问题在简单不过了,我们可以不假思索地就写出代码来:
public class HeartbeatTimes { public static void main(String[] args) { int lifeTimes=70*60*24*365*70; System.out.println(lifeTimes); } }
运行结果是:-1719527296
似乎情况不是我们想象的那样,一个人的心跳居然出现了负值!
程序只有一个运算语句,问题肯定出现在这一句代码中,我们用计算器可以算出这一句运算代码的真实结果是2575440000,将其赋值给
lifeTimes,而lifeTimes是一个int类型的变量,其取值方位为-2147483648~2147483647,这已经超过了int类型
所能标示的范围,势必造成lifeTimes的溢出,所以才会造成负值的心跳次数。
修改上面的代码:
public class HeartbeatTimes { public static void main(String[] args) { long lifeTimes=70*60*24*365*70; System.out.println(lifeTimes); } }
为了防止溢出,将lifeTimes修改为long类型,这次应该没有错误了,然而,运行程序后,输出了同样的结果-1719527296。看来需要好好
分析一下这个程序了,lifeTimes已经被声明为long类型,定然不会有溢出的风险。那么错误只能在于“70*60*24*365*70”这个表达
式了。在表达式中,几个操作数都是int类型的常量,而若干个int类型的计算结果即使超出了其所能表达的数值范围,也不会自动进行向更高数据类型的转化
(如自动转化为long)。那么也就是说,其运行结果任为int类型,但其结果已经超过了int类型所能容纳的最大值,所以,溢出便产生了。
既然知道了错误的根源,那么自然也就有了解决的方式,只要让表达式“70*60*24*365*70”的结果为long类型就可以了。在java中,如果低数据类型与高数据类型进行混合运算时,会自动将结果转化为高数据类型(byte、short与char会转换成int类型)。而要做到这一点,也只需增加一个long类型的操作数即可。自然而然,我们很快就会联想到“1L”这个数值,在此修改程序:
public class HeartbeatTimes { public static void main(String[] args) { long lifeTimes=70*60*24*365*70*1L; System.out.println(lifeTimes); } }
这次运行结果为:-1719527296
看来运算结果的表达式还是有错,再次进行分析,整个表达式都是乘法,计算顺序是从左到右,虽然运算结果是long类型的数据,但计算次表达式时并非从开始
(计算70*60时)就知道末尾还有一long类型数据“1L”,即运行结果并非从开始就确定了整个表达式的类型为long,而是在计算过程中,如果遇到
了更高的数据类型(如在int类型的数据运算中遇到long类型的数据)才做必要的转换。因此,当遇到“1L”时,已经计算了
70*60*24*365*70的结果,而此记过依然是存在int类型的数据中,所以,尽管表达式最终计算的结果会因“1L”而转化为long类型,但此
时溢出已经发生了,“1L”并没有起到预期的效果。
再次修改程序,将“1L”放在最前面:
public class HeartbeatTimes { public static void main(String[] args) { long lifeTimes=1L*70*60*24*365*70; System.out.println(lifeTimes); } }
这次,终于输出了我们想要的结果:2575440000
根据刚才的思路,是从低数据类型与高数据类型进行混合运算的角度考虑,才会联想到与“1L”相乘,其实只要把第一个操作数定义为long类型即可。
如:long lifeTimes=70L*60*24*365*70;或者long lifeTimes=(long)70*60*24*365*70;如果改成这样long lifeTimes=(long)(70*60*24*365*70);会得出正确的结果吗?嘿嘿,试试吧!有什么问题或见解,欢迎来八零客
团队博客来讨论,80客团队成员随时欢迎!
本文转载出处:http://www.balingke.com/archives/609.html