随着计算机以及编程语言的不断发展,或许我们现在对于各种类型变量的上限已经不如C语言中的那么敏感。例如,int类型(整型)的变量,它的上限值已经远远超过以前C语言中的整型变量的上限。在一个典型的C语言中,int型变量的范围为-32768~32767,而在java中,int型的变量的范围就达到了-2147483648 到2147483647。因此,通常情况下,我们不用考虑溢出问题。但是,最近我在使用java计算时间差的时候,却遇到了一个诡异的错误,经过一段时间的检查,才发现居然是整型溢出的错误。
例如,我们现在打算计算两个时间点的年份之差,虽然有很多的函数能够帮我们解决这个问题(例如,先都取出年份值,再相减)。但是也可以直接通过两个时间点之间的数值差(因为,时间类型的数据在计算机中实际上是以long型的数值来存储的),来计算这种时间差。
下面演示的是错误的代码:
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse("2008-05-24 00:00:00");
Date date2 = sdf.parse("2009-05-24 00:00:00");
System.out.println((date2.getTime()-date.getTime())/((long)(1000*3600*24*365)));
其中,这段代码的最主要思想就是利用时间点2(date2)的数值,减去时间点1(date)的数值,然后除以1000,将毫秒数值转为秒;再除以3600*24,转为天;最后除以365转成年。代码的逻辑上是没有错误的(当然,严格上来说,应该区分365天或是366天,因而计算年份差是不推荐这么做的),但是执行的时候却总是出错,得到的结果为21!明眼人应该一下子就能够看出这两个时间点的年份差为1年吧。于是考虑将最后一行代码改为如下:
System.out.println((date2.getTime()-date.getTime())/((long)(1000*3600*24)));
发现就能够得到正确的结果:366天。于是再次将代码改为如下:
System.out.println((date2.getTime()-date.getTime())/((long)(1000*3600*24))/365);
发现就能够得到正确的结果了:1年。但是如果将代码又改为第一种情况,就发现还是计算错误。在这种情况下,最有可能的原因就是变量的溢出问题。我们可以计算一下,1年的毫秒数为:
1000*3600*24*365 = 31536000000 ms/year
原来已经远远超过了int型变量的最大值:2147483647了。于是将计算代码改为如下,也能够正确获得结果:
System.out.println((date2.getTime()-date.getTime())/(((long)(3600*24*1000))*((long)(365))));
看来,虽然计算机的支持能力以及编程语言的发展,已经能够然我们很便捷的使用各种变量,但是有时候还是需要注意一下这些类型变量所支持的范围,避免以为超过范围,造成莫名其妙的溢出错误。
分享到:
相关推荐
编写程序,将一个整数倒排过来,例如:给定整数:453268751,得到的结果:157862354
Description ...第一行是一个整数n,表示有n个测试用例; 第2至n+1每行一个正整数。 Output 对应每组输入,输出正整数n的不同划分个数。 Sample Input 2 5 6 Sample Output 7 11
给定一个正整数a,以及另外的5个正整数,问题是:这5个整数中,小于a的整数的和是多少? 输入要求 输入一行,只包括6个小于100的正整数,其中第一个正整数就是a。 输出要求 输出一行,给出一个正整数,是5个数中...
设有n个正整数,将他们连接成一排,组成一个最大的多位整数。 如:n=3时,3个整数13,312,343,连成的最大整数为34331213。 如:n=4时,4个整数7,13,4,246连接成的最大整数为7424613。 输入描述: 有多组测试样例,每组...
求一个整数各位数字之和。求一个整数各位数字之和。求一个整数各位数字之和。求一个整数各位数字之和。
# 题目: # 给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。 # 分析: # 学会分解出每一位数。
c代码-输入2个整数,求:和,差,积,商 输入:2个整数(第二个数是非零整数) 输出:4个整数,依次为和、差、积和商,数据间用空格分隔。
JAVA中判断一个整数是否为质数, 有空可以看看.
编写一个Java程序从键盘获分别取读取两个整数,并计算这两个整数之和
利用Java编写程序从键盘输入一个整数,计算并输出该数的数字之和。例如:请输入一个整数:8899123各位数字之和为:40
java代码-使用java输入参数为一个整数,输出为该整数各个位上的最大数字的源代码 ——学习参考资料:仅用于个人学习使用!
java求一个整数的因子.rar
正整数n的一个分划是指把n表示成若干个正整数的和。这里的分划与顺序无关,例如6=5+1 和 6=1+5即被认为是同一种分划。另外,这个整数本身也算一种分划。 例如,正整数n=6,可以分划为 6 5+1 4+2, 4+1+1 3+3, 3+2+1, ...
java小程序。猜数字游戏:随机产生一个100以内的正整数,用户通过键盘输入所猜的数字,并给与相应的提示(有代码详细解释)
java求一个整数的因子.7z
java代码-使用java输入参数是一个正整数,输出该整数所对应的二进制数对应的字符串的源代码 ——学习参考资料:仅用于个人学习使用!