关于int的范围以及溢出问题
最近在练一些算法题目的时候恰巧碰到了几道关于int范围与溢出相关的问题,于是就整理一下。
1、原码、补码
在计算机中数值都是用补码表示和存储的(正数补码与原码一致,负数补码是原码符号位不变,其余位取反,然后+1即反码+1)。
可以通过将这个数每一位和1做&运算得到具体的二进制表示,代码如下。代码部分参考https://blog.csdn.net/youyou362/article/details/72667951
/**
* 将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。
本人只是个小白,以上只是个人拙见,如果有问题还请大家指出,有更好的想法欢迎大家留言,一起进步,谢谢!
关于int的范围以及溢出问题的更多相关文章
- 将 expression 转换为数据类型 int 时发生算术溢出
将 expression 转换为数据类型 int 时发生算术溢出错误 2种快速处理方法 1.CONVERT(bigint, 字段名): 2.Cast(字段名 as decimal(18,2)): 这个 ...
- 将 IDENTITY 转换为数据类型 int 时出现算术溢出错误。
IDENTITY标识列为int类型,取值范围为-2^32到2^31-1.当增长值超过这个最大值时,我在SQL Server 2008 R2 x64上试验的结果是: 将 IDENTITY 转换为数据类型 ...
- sql servel 报错:将 expression 转换为数据类型 int 时出现算术溢出错误。
执行sql语句:SELECT AVG( DATEDIFF(s,s.CreatedDate,s.SendDate) ) AS submitTime FROM dbo.SmsSend AS s ...
- 将expression转化为数据类型int时发生算术溢出错误
在SQL Server 中,某列的数据都在int范围之内,但是使用sum聚集函数求该列和的时候,出现“将expression转化为数据类型int时发生算术溢出错误”. 问题在于定义的数据类型: 首先, ...
- 两个int的和判断溢出
long a,b; cin>>a>>b; long i; i = a+b; if((i^a)<0 && (i^b)<0) cout<<& ...
- 【转载】小心 int 乘法溢出!
C/C++ 语言里, 绝大部分平台上 int 类型是 32 位的, 无论你的操作系统是否是 64 位的. 而一些常用的函数, 如 malloc(), 它接受的参数是 size_t 类型: void * ...
- C#中(int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别
转自:http://www.cnblogs.com/leolis/p/3968943.html 在编程过程中,数据转换是经常要用到的,C#中数据转换的方法很多,拿将目标对象转换为 整型(int)来讲, ...
- C#中(int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别 <转>
作者:Statmoon 出处:http://leolis.cnblogs.com/ 在编程过程中,数据转换是经常要用到的,C#中数据转换的方法很多,拿将目标对象转换为整型(int)来讲,有四种方法 ...
- (int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别
C#中(int).int.Parse().int.TryParse()和Convert.ToInt32()的区别 原文链接:http://www.cnblogs.com/leolis/p/3968 ...
随机推荐
- c++指针经典题目分析
首先看一下题目,下列程序会在那一行崩溃,程序如下: #include<iostream> using namespace std; struct S{ int i; int *p; }; ...
- C语言学习书籍推荐《C专家编程Expert C Programming Deep C Secrets》下载
Peter Van Der Linden (作者) <C和C++经典著作 C专家编程Expert C Programming Deep C Secrets>展示了C程序员所使用的编码技巧, ...
- 【深入浅出-JVM】(6):栈帧.
代码 package com.mousycoder.mycode.happy_jvm; /** * @version 1.0 * @author: mousycoder * @date: 2019-0 ...
- WPF 入门笔记之事件
一.事件路由 1. 直接路由事件 起源于一个元素,并且不能传递给其他元素 MouserEnter 和MouserLeave 就是直接事件路由 2. 冒泡路由事件 在包含层次中向上传递,首先由引发的元素 ...
- springcloud-路由Zull
1. 场景描述 今天接着介绍springcloud,今天介绍下springcloud的路由网关-Zull,外围系统或者用户通过网关访问服务,网关通过注册中心找到对应提供服务的客户端,网关也需要到注册中 ...
- shell_链接命令ln与nohup命令使用方法
ln命令是一个链接命令,工作中用的比较多的就是对一个文件或者是目录建立起软连接.软连接的概念类似于windows下的快捷方式.比如,在win下,我们经常在安装完word.ppt等office程序后,在 ...
- 我的it博客开张啦
今天怀着激动地心情,在这里写下第一篇开博.之前也在新浪.网易等申请过博客,并且将新浪博客作为我的个人技术博客,当有一天看到cnblog时,觉得这里的博客以一本精美的书的批复呈现时,顿觉得很有...咋说 ...
- WinForm控件之【Button】
基本介绍 普通按钮大部分情况下用作页面对某系列操作后的提交确认,应用较为广泛,在winfrom控件当中使用设置都相对的简单. 常设置属性.事件 Image:控件上显示的图片: Enabled :指示 ...
- dij模板
#include<cstdio> #include<vector> #include<queue> using namespace std; struct edge ...
- Feign挡板和Mock
背景: 在项目开发中,会有调用第三方接口的场景.当开发时,对方不愿意提供测试服务器给我们调用,或者有的接口会按调用次数进行计费.当联调时,第三方的测试服务器也可能会出现不稳定,如果他们的服务挂了,我们 ...