int与Long需要注意的值范围

电玩女神 2022-04-18 03:29 292阅读 0赞

今天使用程序计算一个算式,算出的结果一点不对,当时就气死我了。

然后用计算器算了好几遍,先证明自己逻辑没有混乱。

这个算式什么样子?

  1. System.out.println( "不加L,丢失精度:"+(-1387053568*31 + 19287));

运行结果:明显不对。

  1. 不加L,丢失精度:-48968361

这个计算肯定超过了int的最大值,所以使用Long算一下,

  1. System.out.println( "加上L,正确结果:"+(-1387053568L*31 + 19287));

结果正确:

  1. 加上L,正确结果:-42998641321

接着思考这个是怎么丢失精度的:

先列出int最大,最小值:

  1. System.out.println("测试Integer的值:");
  2. System.out.println( "最大:"+Integer.MAX_VALUE);
  3. System.out.println( "最小:"+Integer.MIN_VALUE);

结果:

  1. 测试Integer的值:
  2. 最大:2147483647
  3. 最小:-2147483648

猜想是不是利用最小的值进行计算的:

  1. System.out.println( "猜想是不是溢出后变成最小值计算,模拟:"+(Integer.MIN_VALUE*31 + 19287));

结果不是用最小值进行计算的,因为与上面的结果不一致:

  1. 猜想是不是溢出后变成最小值计算,模拟:-2147464361

看一下这个转换,这样就看出丢失精度的过程了:乘法的时候数值超过int最小值范围,先转换为一个数,用这个数加的19287

  1. int i =-1387053568*31;
  2. System.out.println("输出int溢出值:"+i);

溢出结果:

  1. 输出int溢出值:-48987648

这个int超过值范围是怎么计算的:这就涉及导java的溢出机制,

涉及到,先转为二进制,然后截取32位(int类型4个字节,1个字节八位),然后正负数的补码,反码等操作,再转回十进制。

有空再继续写一下把。//TODO

最后所有程序:

  1. System.out.println("测试Integer的值:");
  2. System.out.println( "最大:"+Integer.MAX_VALUE);
  3. System.out.println( "最小:"+Integer.MIN_VALUE);
  4. int i =-1387053568*31;
  5. System.out.println("输出int溢出值:"+i);
  6. System.out.println( "加上L,正确结果:"+(-1387053568L*31 + 19287));
  7. System.out.println( "不加L,丢失精度:"+(-1387053568*31 + 19287));
  8. System.out.println( "猜想是不是溢出后变成最小值计算,模拟:"+(Integer.MIN_VALUE*31 + 19287));
  9. System.out.println((int)(-1387053568L*31+ 19287));
  10. //十进制转换为二进制
  11. //二进制截取低位32位 原码 补码 反码之类,这里没写完,有兴趣可以了解一下
  12. String a=Long.toBinaryString((int)(-1387053568L*31));
  13. System.out.println(a);
  14. String sub =a.substring(a.length()-32,a.length());
  15. System.out.println(sub);
  16. System.out.println(sub.length());
  17. System.out.println(Long.valueOf(sub,2).toString());

结果:

  1. 测试Integer的值:
  2. 最大:2147483647
  3. 最小:-2147483648
  4. 输出int溢出值:-48987648
  5. 加上L,正确结果:-42998641321
  6. 不加L,丢失精度:-48968361
  7. 猜想是不是溢出后变成最小值计算,模拟:-2147464361
  8. -48968361
  9. 1111111111111111111111111111111111111101000101001000001000000000
  10. 11111101000101001000001000000000
  11. 32
  12. 4245979648

发表评论

表情:
评论列表 (有 0 条评论,292人围观)

还没有评论,来说两句吧...

相关阅读