关于int的范围以及溢出问题
最近在练一些算法题目的时候恰巧碰到了几道关于int范围与溢出相关的问题,于是就整理一下。
1、原码、补码
在计算机中数值都是用补码表示和存储的(正数补码与原码一致,负数补码是原码符号位不变,其余位取反,然后+1即反码+1)。
可以通过将这个数每一位和1做&运算得到具体的二进制表示,代码如下。代码部分参考https://www.geek-share.com/detail/2706548997.html
/** * 将n的每一位与1做&运算 得到具体的二进制表示 * @param n * @return */ public static void converseToBinary(int n) { int value = 1; int[] arr = new int[32]; int i = 31; while (value != 0) { if ((value & n) != 0) { arr[i] = 1; } else { arr[i] = 0; } i--; value = value << 1; //左移右边补0,当移完32为value为0. } for (int index = 0;index < 32;index++){ System.out.print(arr[index]); if ((index+1)%4 == 0){ System.out.print(" "); } } }
例如-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进制的数。
/** * A constant holding the minimum value an {@code int} can * have, -2<sup>31</sup>. */ @Native public static final int MIN_VALUE = 0x80000000; /** * A constant holding the maximum value an {@code int} can * have, 2<sup>31</sup>-1. */ @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
溢出为 1 0111 1111 1111 1111 11111 1111 1111 1111为 2^31 - 1。
本人只是个小白,以上只是个人拙见,如果有问题还请大家指出,有更好的想法欢迎大家留言,一起进步,谢谢!
- C语言的整型溢出问题 int、long、long long取值范围 最大最小值
- 关于ZM问到C中int数据范围溢出
- 【转】关于int范围中负数最小值的绝对值比整数最大值大初学C,问题源自:为什么C中的int类型(16位)的下溢下限为-32768而上溢上限却是32767。 首先说吧,32767很容易理解,32767
- 关于int取值范围的问题
- 关于int类型取值范围的计算以及为何16位int类型范围是- 32768 ~ 32767
- C语言的整型溢出问题 int、long、long long取值范围 最大最小值
- mysql中关于int()范围的问题
- 关于java中float和int 精度和范围的问题
- 关于解决tomcat的一些问题-内存溢出 PermGen space以及超时
- 【转】关于int范围中负数最小值的绝对值比整数最大值大初学C,问题源自:为什么C中的int类型(16位)的下溢下限为-32768而上溢上限却是32767。 首先说吧,32767很容易理解,32767=
- 关于int范围中负数最小值的绝对值比整数最大值大初学C,问题源自:为什么C中的int类型(16位)的下溢下限为-32768而上溢上限却是32767。 首先说吧,32767很容易理解,32767=
- 关于int(4字节)的取值范围由来(-2^31~2^31-1)问题
- 关于int类型取值范围的计算 以及为何16位int类型范围是- 32768 ~ 32767
- 关于为什么需要设置request.setCharacterEncoding以及适用范围问题
- int 和 long int float 以及 double 和点云的取值范围
- 关于Hive的中文注释以及hwi查询中文结果的问题
- 【JSP】关于jsp文件存放以及引用的路径问题
- 关于通过http请求访问Linux下的ftp的问题以及解决办法
- 关于使用POI创建表格合并单元格兼容wps以及office等问题