引入:
昨天在做一个求从1到1,000,000,000(10亿)累加和的竞赛题遇到了一个小问题,就是伪 · “long类型的溢出” 问题,代码重现如下:
int number = 1000000000;
// 第一种
long result = (1+number)*number/2;
// 获取result数据的长度
System.out.println(String.valueOf(result).length());
System.out.println(result);
输出结果:
10
-243309312 // 结果溢出
// 第二种
// 将result强制使用long类型
long result = 0L;
// 对计算结果进行强转
result = (long)((1+number)*number/2);
// 获取result数据的长度
System.out.println(String.valueOf(result).length());
System.out.println(result);
输出结果:
10
-243309312 // 结果溢出
// 正确结果
long result = (1+number)*(long)number/2;
System.out.println(String.valueOf(result).length());
System.out.println(result);
输出结果:
18
500000000500000000
以上的代码不难看出结果的位数并未超过long类型的最大长度,但是都溢出了,这是为何?
原因:
*先将 (1+number)number/2 看成算式A
第一种:
A中number是int类型,整个A式的结果也是int类型,然而整个A式的结果是18位,已经超出了int最大长度10位,结果溢出,溢出的结果-243309312给long类型的result赋值,result的值是int溢出后的-243309312,因此得不到正确结果,产生溢出现象。
第二种:
和第一种相似,第二种是对A式已经溢出的结果-243309312进行强转,小转大,不会溢出,但是long类型result的值仍然是-243309312,依然得不到正确结果,产生溢出现象。
正确结果:
对A式的int类型的number进行强转成long类型,那么整个A式产生的结果就是long类型,而long类型的最大长度是19位,可以放得下18位的结果,完全没问题,因此能够得出正确结果,也不会产生溢出问题。
总结:
对于基本类型的相互转换与自动类型提升的理解不深入,建议发现这种问题的各位看官老爷们多多关注java的基础知识。
感谢浏览,顺便点个赞呗~