让你很容易忽视的一个整数运算

    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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值