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客团队成员随时欢迎!
相关推荐
克里奇洛乘法計算機可能提供了一个直观的输入框让用户输入数字,以及简洁的按钮进行操作。可能还有结果显示区,清晰地显示计算结果,甚至可能包含错误检查和异常处理机制,确保在输入无效或超出预期范围时给出适当的...
通常,这种密码会选取一个密钥K,将明文的每一个字符(假设是数字)与K相乘,然后取结果对一个大整数M取模,得到对应的密文字符。解密过程则需要进行逆运算,即除以K再对M取模。这种方法虽然提高了安全性,但由于...
一个整洁的草稿可以帮助学生更好地展示解题过程,减少因卷面不整洁而扣分的情况。 因此,要改善学生的数学学习效果,必须重视草稿纸的使用。建议学生使用专用草稿本,保持书写清晰,按顺序进行计算和分析。教师应当...
在小学四年级数学的教学中,小数加减法是一个重要的知识点,它标志着学生从整数运算进入到了更为复杂的数字世界。这一阶段的学习不仅要求学生掌握基本的运算规则,还要求他们能够灵活应用到实际问题中去。以下是对人...
例如,在反馈回路并接电容,反馈信号的相位会发生改变,很容易就会发生振荡。为了降低纹波,可以把C3与R1并联,适当增大纹波的负反馈作用,抑制输出纹波。 4. 注意运放的输出摆幅 任何运放都不可能是理想运放,...
在C语言中,不同类型之间的转换如果不谨慎,很容易造成数据丢失或意外的行为。例如,将一个较大的整型值赋给较小的整型变量时,高位的数据会被截断;浮点数与整数之间的转换也可能导致精度丢失。 2. **指针操作...
在逻辑与运算中,如果第一个操作数为假,则不会评估第二个;在逻辑或运算中,如果第一个操作数为真,则不会评估第二个。这在条件赋值和默认参数中很常见。 3. 三元运算符:`条件 ? 结果1 : 结果2`,它是最简洁的条件...
如果不注意,很容易丢失小数点,从而导致计算结果出错。 除了小数乘法,PPT还介绍了小数除法的计算步骤。小数除法首先要在被除数前点上小数点,然后按照整数除法的规则进行计算。过程中需要注意,商的小数点不能...
总的来说,死区时间是数字示波器设计中的一个重要考量因素,它关乎到示波器能否准确、实时地呈现信号。随着技术的进步,尽管死区时间无法完全消除,但可以通过各种方法进行优化,以满足不同领域、不同层次的测试需求...
在本主题中,我们将深入探讨“Java基础之计算器”的实现,这是一个典型的编程...同时,这也是一个很好的练习,帮助理解如何将抽象概念转化为实际代码,以及如何调试和优化程序。在实际工作中,这些技能都是必不可少的。
浮点运算在单片机中是一个容易被忽视但实际上很重要的问题。许多低性能单片机不支持浮点运算,因此在需要进行浮点计算时,编译器会自动调用库函数进行近似处理,这将导致运算效率低下。为了提高效率,通常会采用定点...
对于浮点数,你可以先将其转换成整数类型再进行取模运算,或者使用其他方法实现类似功能。 #### 四、“=”与“==”的区别 **问题描述**:很多语言中使用 `=` 表示等于,但在C语言中,`=` 是赋值运算符,`==` 才是...
因此,在比较浮点数时,建议使用`Math.abs()`函数和一个很小的容差值来判断两个浮点数是否足够接近,从而避免因舍入误差引起的误判。 #### 七、`equals`方法的正确实现 Java中的`equals`方法用于比较对象的逻辑...
8. **浮点数精度**:C语言的浮点数运算不是精确的,因此比较浮点数时需要特别注意,通常使用一个很小的误差范围来判断是否相等。 9. **函数调用约定**:不同的编译器和平台可能使用不同的函数调用约定,不兼容的...
在C#的学习过程中,往往有一些不那么显眼但至关重要的知识点容易被初学者忽视,这些便是所谓的“盲点”。为了帮助大家深入理解C#并避免这些常见误区,我们将通过两个文档——"c#中的盲点1.txt"和"c#中的盲点2.txt...
Go语言的程序结构清晰,它将代码分为包(package),一个程序可以包含多个包,每个包具有独立的作用域。Go语言的编译过程可以生成独立的二进制文件,也可以生成可复用的共享库。Go语言对代码格式和文档生成有一套...