int与Long需要注意的值范围
今天使用程序计算一个算式,算出的结果一点不对,当时就气死我了。
然后用计算器算了好几遍,先证明自己逻辑没有混乱。
这个算式什么样子?
System.out.println( "不加L,丢失精度:"+(-1387053568*31 + 19287));
运行结果:明显不对。
不加L,丢失精度:-48968361
这个计算肯定超过了int的最大值,所以使用Long算一下,
System.out.println( "加上L,正确结果:"+(-1387053568L*31 + 19287));
结果正确:
加上L,正确结果:-42998641321
接着思考这个是怎么丢失精度的:
先列出int最大,最小值:
System.out.println("测试Integer的值:");
System.out.println( "最大:"+Integer.MAX_VALUE);
System.out.println( "最小:"+Integer.MIN_VALUE);
结果:
测试Integer的值:
最大:2147483647
最小:-2147483648
猜想是不是利用最小的值进行计算的:
System.out.println( "猜想是不是溢出后变成最小值计算,模拟:"+(Integer.MIN_VALUE*31 + 19287));
结果不是用最小值进行计算的,因为与上面的结果不一致:
猜想是不是溢出后变成最小值计算,模拟:-2147464361
看一下这个转换,这样就看出丢失精度的过程了:乘法的时候数值超过int最小值范围,先转换为一个数,用这个数加的19287
int i =-1387053568*31;
System.out.println("输出int溢出值:"+i);
溢出结果:
输出int溢出值:-48987648
这个int超过值范围是怎么计算的:这就涉及导java的溢出机制,
涉及到,先转为二进制,然后截取32位(int类型4个字节,1个字节八位),然后正负数的补码,反码等操作,再转回十进制。
有空再继续写一下把。//TODO
最后所有程序:
System.out.println("测试Integer的值:");
System.out.println( "最大:"+Integer.MAX_VALUE);
System.out.println( "最小:"+Integer.MIN_VALUE);
int i =-1387053568*31;
System.out.println("输出int溢出值:"+i);
System.out.println( "加上L,正确结果:"+(-1387053568L*31 + 19287));
System.out.println( "不加L,丢失精度:"+(-1387053568*31 + 19287));
System.out.println( "猜想是不是溢出后变成最小值计算,模拟:"+(Integer.MIN_VALUE*31 + 19287));
System.out.println((int)(-1387053568L*31+ 19287));
//十进制转换为二进制
//二进制截取低位32位 原码 补码 反码之类,这里没写完,有兴趣可以了解一下
String a=Long.toBinaryString((int)(-1387053568L*31));
System.out.println(a);
String sub =a.substring(a.length()-32,a.length());
System.out.println(sub);
System.out.println(sub.length());
System.out.println(Long.valueOf(sub,2).toString());
结果:
测试Integer的值:
最大:2147483647
最小:-2147483648
输出int溢出值:-48987648
加上L,正确结果:-42998641321
不加L,丢失精度:-48968361
猜想是不是溢出后变成最小值计算,模拟:-2147464361
-48968361
1111111111111111111111111111111111111101000101001000001000000000
11111101000101001000001000000000
32
4245979648
还没有评论,来说两句吧...