• 关于int的范围以及溢出问题


    最近在练一些算法题目的时候恰巧碰到了几道关于int范围与溢出相关的问题,于是就整理一下。

    1、原码、补码

    在计算机中数值都是用补码表示和存储的(正数补码与原码一致,负数补码是原码符号位不变,其余位取反,然后+1即反码+1)。

    可以通过将这个数每一位和1做&运算得到具体的二进制表示,代码如下。代码部分参考https://blog.csdn.net/youyou362/article/details/72667951

     1 /**
     2      * 将n的每一位与1做&运算 得到具体的二进制表示
     3      * @param n
     4      * @return
     5      */
     6     public static void converseToBinary(int n) {
     7         int value = 1;
     8         int[] arr = new int[32];
     9         int i = 31;
    10         while (value != 0) {
    11             if ((value & n) != 0) {
    12                 arr[i] = 1;
    13             } else {
    14                 arr[i] = 0;
    15             }
    16             i--;
    17             value = value << 1; //左移右边补0,当移完32为value为0.
    18         }
    19         for (int index = 0;index < 32;index++){
    20             System.out.print(arr[index]);
    21             if ((index+1)%4 == 0){
    22                 System.out.print(" ");
    23             }
    24         }
    25     }

    例如-3,程序运行结果为 1111 1111 1111 1111 1111 1111 1111 1101 ,正是-3的补码。由此得知在计算机中数值都是用补码表示和存储的。

    2、int的取值范围

    java中int四字节,一个字节8bit所以 int 32bit 即高16位和低16位,共32位,最高位符号位。

    在Integer类中,有两个常量 MIN_VALUE和MAX_VALUE是16进制的数。

     1 /**
     2      * A constant holding the minimum value an {@code int} can
     3      * have, -2<sup>31</sup>.
     4      */
     5     @Native public static final int   MIN_VALUE = 0x80000000;
     6 
     7     /**
     8      * A constant holding the maximum value an {@code int} can
     9      * have, 2<sup>31</sup>-1.
    10      */
    11     @Native public static final int   MAX_VALUE = 0x7fffffff;

    转化成二进制分别是MIN_VALUE = 1000 0000 0000 0000 0000 0000 0000 0000;

                                   MAX_VALUE =  0111 1111 1111 1111 1111 1111 1111 1111;

    网上看了好多文档,关于最大值和最小值为什么是这两个写的挺模棱两可的,一开始我猜想正数最大值的时候是因为一共32位,第一位符号位0,剩下都应该是1才是最大,得到正好是0111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111,即2^31 - 1,但已这种方式推算负数最大值时进行不下去,于是用数学归纳法进行总结:

    正数部分:1的补码为 0000 0000 0000 0000 0000 0000 0000 0001;

                      2的补码为0000 0000 ............................................. 0010 ;

                     3的补码为 0000 0000 ............................................. 0011;

         由此推出正数最大值的补码为 0111 1111 1111 1111 .......................1111,原码=补码,为2^31-1;

    负数部分:-1的补码为 1111 1111 1111 1111 1111 1111 1111 1111

                      -2的补码为 1111 1111 1111 1111 1111 1111 1111 1110

                      -3的补码为 1111 1111 1111 1111 1111 1111 1111 1101

                      -4的补码为 1111 1111 1111 1111 1111 1111 1111 1100

                      由此推出负数最小值的补码为 1000 0000 0000 0000 0000 0000 0000 0000 0000,求负数最小值补码的原码为-2^31

    所以int的范围为-2^31 ~ 2^31-1

    3、int的溢出问题,参考自https://www.jianshu.com/p/ffc97c4d2306

    溢出是针对有符号数的。

    int最大值为 2^31 - 1 补码为 0111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 加1为 1000 0000 0000 ................0000有溢出,为-2^31

    int最小值   -2^31 补码为 1000 0000 0000 0000 0000 0000 0000 0000 0000  ,-2^31 - 1为加-1的补码1111 1111 1111 1111 1111 1111 1111 1111

    溢出为 0111 1111 1111 1111 11111 1111 1111 1111为 2^31 - 1。

    本人只是个小白,以上只是个人拙见,如果有问题还请大家指出,有更好的想法欢迎大家留言,一起进步,谢谢!

  • 相关阅读:
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
    C语言II博客作业04
    C语言II博客作业03
    C语言II博客作业02
    C语言II博客作业01
    期末总结
    第一次作业
    C语言I博客作业08
  • 原文地址:https://www.cnblogs.com/wdfordream/p/10237516.html
Copyright © 2020-2023  润新知