`
haowenxin
  • 浏览: 4364 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
最近访客 更多访客>>
社区版块
存档分类
最新评论

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

阅读更多

    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

分享到:
评论

相关推荐

    大整数运算.doc

    大整数的表示和存储可以采用数组或链表的方式,而大整数的运算实现可以采用模块化的思想,建立一个基础框架,并在此框架上讨论并实现多精度大整数的基本加法、减法、乘法、除法、平方算法、缩减、模乘、模幂乘等算法...

    设计一个程序实现两个任意长的整数求和运算

    用线性表实现整数加法,属于一个整数运算的计算器

    长整数的运算

    第一行输入第一个大整数A。A前带正负号,后面是任意多位的数字序列。 2. 第二行只有一个字符,可以是“+”、“-”、“*”,分别代表加、减、乘三种运算符。 3. 第三行输入大整数B,格式与A相同。 注: ...

    C++大整数运算

    C++关于大整数类的相关运算包括重载加减乘除,赋值,输出和比较运算

    c++编写程序实现两个超长正整数(每个最长80位数字)的减法运算

    要求:若结果为0,则只输出一个0;否则输出的结果的最高位不能为0,并且各位数字紧密输出。[输入样例] 234098 134098703578230056 [输出样例] -134098703577995958 [样例说明] 进行两个正整数减法运算,234098-...

    大整数的运算

    有关如何进行大整数的运算的问题,属于很小的一个问题

    C语言编写无符号大整数运算

    使用c语言实现的无符号大整数的加、减、乘、除(取整和求余运算),可直接运行

    c语言大整数运算

    由于编程语言提供的基本数值数据类型表示的数值范围有限,不能满足较大规模的高精度数值计算,因此需要利用其他方法实现高精度数值...大数运算主要有加、减、乘三种方法,该资料主要是利用C语言来解决大整数计算的问题

    整数乘法运算定律推广到小数练习题及答案精选.doc

    * 解决实际问题,例如一辆汽车一天节约汽油1.25千克,照这样计算,8辆汽车一个月可节约汽油多少千克? 通过这些练习题,我们可以更好地理解整数乘法运算定律的推广到小数的应用,并且掌握如何使用这种知识来解决...

    128位大整数运算源代码

    源代码包含128位大整数的加减乘除、取模、乘幂、2进制和10进制转换等运算,可用于大整数运算和加解密算法。

    长整数运算.zip

    利用双向循环链表实现长整数的存储, 每个结点含一个整型变量. 任何整型变量的范围是 -(215-1)~(215-1)。输入和输出形式: 按中国对于长整数的表示习惯, 每四位一组,组间用逗号隔开。 [ 测试数据 ] (1) 0;0;应...

    C++实现的大整数四则运算

    自己实现的一个大整数类,实现了一些基本运算功能,但是还有很多不足,传上来是想请大家提一些修改建议,谢谢各位了。

    整数乘法运算定律推广到分数练习题及答案精选.doc

    整数乘法运算定律是指在整数乘法中的一种运算规则,包括交换律、结合律和分配律等。这些定律在日常生活和数学计算中都有着重要的应用价值。 计算方法 从练习题中可以看到,整数乘法运算定律推广到分数的计算方法...

    长整数四则运算加减法

    1、本程序实现计算任意长的整数的加、减法运算....按中国对于长整数的表示习惯,每四位一组,除数字和位于首位置的负号外,其它一切字符都将作为分隔符,连续多个分隔符当一个处理。但不使用分隔符也不影响结果。

    适合初学者的大整数运算库

    适合初学者的大整数运算库,支持8进制,10进制,16进制的运算及混合运算,也可方便的扩展其他的进制。

    双向循环链表来实现长整数四则运算

    选择该数据结构来完成长整数的加减运算是因为要对长整数进行运算,需要对长整数进行存储,所以选择用链表对长整数存储,又由于存储的顺序是从左到右,而运算的顺序则是从右到左,这样位了操作方便选择循环链表,在...

    数据结构 大整数运算

    数据结构 C++的大整数运算 加减乘除。

    一位整数立方运算EDA

    EDA课设,一位整数立方运算器的工程文件。

    C语言:超长正整数的减法

    要求:若结果为0,则只输出一个0;否则输出的结果的最高位不能为0,并且各位数字紧密输出。 【输入样例】 234098 134098703578230056 【输出样例】 -134098703577995958 【样例说明】 进行两个正整数减法...

Global site tag (gtag.js) - Google Analytics