-
2016-08-27 00:23:12
首先得知道,在java中,int类型占4个字节,1个字节等于8位二进制,所以int类型32位,范围是-2147483648到2147483647,
因为1000 0000, 0000 0000, 0000 0000, 0000 0000这个是-2^31=-2147483648,所以负数多一个。
然后,因为计算机CPU的运算器中只有加法器,所以减法要转化成加法来计算,所以引入了补码。
补码可以解决两同号数相减或两异号数相加的问题。
举个例子,A表示十进制数“+6”,B表示十进制数“-8”,如果把这两个数的原码直接相加,那么
0000 0110
+ 1000 1000
————————
1000 1110
结果为-14,很明显是错的。
如果把这两个数的补码相加,那么
0000 0110 “+6”补码
+ 1111 1000 “-8”补码
————————
1111 1110 “-2”补码
结果是-2的补码,结果是正确的。
要理解上面的补码运算,得先知道一下3点:
1、正数的原码 反码 补码完全相同。
2、负数的反码是将原码按位取反,补码=反码+1。
3、补码转原码和原码转补码的方法是一样的。
最后根据上面的计算方法,计算INT_MIN - 1的结果,看是不是等于 INT_MAX。
1000 0000, 0000 0000, 0000 0000, 0000 0000 “-2147483648”补码
+ 1111 1111,1111 1111, 1111 1111,1111 1111 “-1”补码
————————————————————————
1 0111 1111,1111 1111, 1111 1111,1111 1111
很明显,运算溢出了。舍去溢出的最高位,最后运算的结果是0111 1111,1111 1111, 1111 1111,1111 1111。
又因为正数的原码 反码 补码完全相同。所以0111 1111,1111 1111, 1111 1111,1111 1111就是“2147483647”补码、源码= INT_MAX。
所以,综上所述:INT_MIN - 1的结果等于 INT_MAX。
更多相关内容 -
二进制加减溢出问题详解,byte类型加减溢出详解。
2020-07-16 20:02:45剩余7位表示数值,根据二进制的计算方法,byte8位一共可以表示-128~127。 为什么正数只能表示到127,而负数可以表示到-128呢? 这涉及到了0的问题 1000 0000 按照之前的规定来看,首位1代表符号位,说明是负数,后7...byte类型的数在JAVA中占1个字节,也就是8位,那么8位中除去一个符号位,表示数值的共有七位。
例如:1000 0000 中1就是符号位,表示负数。
0111 1111 中0也是符号位,表示正数。
剩余7位表示数值,根据二进制的计算方法,byte8位一共可以表示-128~127。
为什么正数只能表示到127,而负数可以表示到-128呢?
这涉及到了0的问题
1000 0000 按照之前的规定来看,首位1代表符号位,说明是负数,后7位代表数值0。这样看来,1000 0000就代表了-0这个数。
0000 0000 同理,按照之前的规定来看,首位0代表符号位,说明是负数,后7位代表数值0。这样看来,1000 0000就代表了+0这个数,0这个数是不需要使用2种正负去表示的,+0和-0这样就浪费了一个表示数值。所以规定1000 0000代表-128,第一位不止是符号位了,或者说,规定1000 0000就是-128,这样就导致了我们可以表示-128~127的数,正数比负数可以表示的数少一,就少在了这个-0上。
再说溢出问题byte a = 127; byte b = -128; (byte)(a+1); (byte)(b-1);
这样就出现了一个问题,也就是溢出问题,因为byte只能表示8位,数值就是-128~127,现在127+1和-128-1都导致超出了byte所能表示的范围,那么就代表数据溢出了。
现在需要大家明白一个问题就是,计算机中,是使用补码进行运算的,正数的补码和原码还有反码都一样。但是负数就不一样。补码是源码取反+1.同理原码是补码取反+1.
明白了以上这个概念,我们就可以继续往下走了。
127是正数,所以表示为0111 1111.
127 + 1 = 128 表示位 1000 0000.
你可以发现现在符号值变成了1,从0变成1.那么现在在系统中就是表示为一个负数,我们可以发现这个数1000 0000和之前我们规定的-128的值是一样的,对127+1现在就转化成了-128.
同理-128是1000 0000,我们对它进行减一,那么就是-129 转化成二进制就是 11000 0001而在计算时需要转化成补码也就是 原码取反10111 1110 再+1 10111 1111,而我们byte只能放下8位,所以原本的符号位顶掉了,所以值就变为0111 1111,也就是127.这就是byte的溢出问题。 -
有符号二进制加法溢出判断以及溢出后该如何计算正确答案
2020-07-22 13:46:55我想从五个方面来说说有符号二进制加法溢出以及溢出后该如何计算这些个问题: ·什么是有符号二进制数 补码的计算以及还原 有符号数的加法 什么是溢出、什么是自然丢弃 溢出后该如何正确计算结果 一.什么是有符号...我想从五个方面来说说有符号二进制加法溢出以及溢出后该如何计算这些个问题:
- ·什么是有符号二进制数
- 补码的计算以及还原
- 有符号数的加法
- 什么是溢出、什么是自然丢弃
- 溢出后该如何正确计算结果
一.什么是有符号二进制数
二进制数分为有符号和无符号两种形式,在未标明的情况下,二进制数指的是无符号二进制数,即没有负数形式。反之,有符号二进制数,是指有正负号的二进制数。
有符号二进制数即在无符号二进制数的基础上,在最左边添加符号位,‘0’为正,‘1’为负。
举例说明:-2 1(符号位 ‘1’表明是负数)10(2的二进制表达) --> 110
+2 --> 010
二.补码的计算以及还原
在计算机的运算中,是以补码的形式进行加减法运算的(减法其实就是带负数的加法,2-3 其实就是2+(-3))。那补码是怎么计算的呢?
分为两种情况:
1.正数补码。 记住正数的补码就是其本身。如:+2 -->010 补码–> 010
2.负数补码。 符号位不变,将符号位后面的所有数取反,之后进行加一操作。如:-2 --> 110 补码 --> 101 + 1 -->110. 可以发现它的补码和原码相同,这里大家留个心眼,为后面的溢出埋下伏笔。
学会了原码转补码,怎么能不会补码转原码呢。
补码转原码其实就是再将补码进行一次求补码的操作,即补码的补码是原码。
三.有符号数的加法
接下来就是开始进行加法操作了。在补码的加法运算中,符号位就当成是整个二进制数的一部分,进行加法运算。
如:+3 + 4
3 --> 0011
4 --> 0100
相加 --------
结果 0111然后对所得结果求补码(这点很重要,前面例子发现有些负数的补码就是其本身,为了后面不弄混淆,建议对所得结果求补码)。此处,正数的补码是其本身。计算结果就是0111。
0 表示正数 111的十进制是7,解为+7。完全正确。
提一点如果两个相加数的位宽不同,将小的位宽的数左起填充0,然后再进行补码操作。
如-2+8 110 + 01000 此处将-2做如下处理。10010(五位保持和+8一样位宽) 再将10010做补码处理,–>11101+1–>11110。补码形式加法为:11110+01000
接下来请看什么是溢出,以及溢出的危害是什么。
四.什么是溢出、什么是自然丢弃
对于溢出的理解,稍微解释的不详细很可能会把初学者带入沟里,今天我就被带进沟里了。作为一个过来人我很愿意和大家分享,让初次接触的朋友们能很快的理解,避免和我一样花大量时间从沟里爬出来。言归正传。
说到溢出,还是要先提一下自然丢弃。
前面的例子是很简单的例子,请看下面这个例子:
-2 - 6
-6 --> 1110
-2 --> 1010
相加 --------
结果 11000结果的位数比原先的多出了一位,此处最左边的1,是会被自然丢弃的(就是不要了)。再看结果,对1000求补码(其实可以看出它就是0)。这和我们想要的-8有天壤之别。为什么会出现这个情况呢?
原因就是这里出现了溢出!
首先来看溢出的定义:
对一个N位二进制补码,其可以表达的范围是 - 2^(N-1) 到 2^(N-1) - 1之间。如果超出这个范围就称为溢出了。
拿上面的-2-6来说,我们刚刚在计算时,转换为二进制补码是4位的。它的取值范围是-8到+7之间。而我们想要的结果是-8,比范围的最小值还要小,这个叫做负溢出。同理如果想要的结果比最大值还要大,那么就叫做正溢出,如取值范围是-7~+7之间,想要的结果是+8,那么就是正溢出。
说完了溢出的定义,我们来说说溢出的判定,就是怎么在计算开始时知道自己算的结果是不是溢出了?
还是拿前面-2-6为例,即1110 + 1010,大家可以看到我拿两种不同颜色标注了它们最开头的两个数,我们把红色的(左起第一位)符号位进位值和蓝色(左起第二位)相加的进位值进行比较。如果两者相同(即00或者11),则不溢出,如果两者不同(即01正溢出,10负溢出),则发生溢出,最后的解必定会出错。
拿-2-6为例,它们补码形式为1110+1010,符号位相加发生了进位,进位值为1,数字位左起第一位相加没有发生进位,进位值为0,即10型溢出,为负溢出,就是说所得的值小于四位二进制补码的取值范围,和我们计算的-8<-7结果相匹配,判断成功。
到这里我们已经成功了一大半,与最终正确解的就值就差一步之遥。
五.溢出后该如何正确计算结果
在通过判断之后,我们知道这个结果定是溢出了,该怎么求正确的解呢?
答:将位宽扩大一位,还是按前面的判定方法进行判定。
举例,-2-6 前面说了这是一个负溢出,我们在转换为二进制时进行位宽扩大,以提升取值范围。
此处 -2 二进制写成 10010(5位比开始多一位),-6二进制写成10110(5位比开始多一位)。再进行补码运算,10010–> 11101+1–>11110,10110–>11001+1–>11010.
11110
11010
相加---------
111000 最高位超出位宽,自然舍弃,剩下的11000求补码,10111+1-->11000 即-8,和我们所求的结果一致,bingo答对了。
转载:负数二进制计算
—————————————————————————————————————————————
计算-2 -6 = -8
思路:-2的补码 + -6的补码 = x; 再计算x的补码就是-8
-2——>100010 ——> 111101 + 1 ——>111110 (-2补码)
-6——>100110 ——> 111001 + 1 ——>111010 (-6补码)
-2 + -6 = 111110 +111010 = 1111000 ——> 111000 ——> 100111+ 1 = 101000 = -8 -
二进制补码加减运算的溢出检查
2020-06-08 23:41:07二进制中加减运算的溢出检查前言
此文章不涉及相应的二进制补码的加减运算,仅对其溢出的问题进行讨论。
例题中有包含相应的解释,如果通过这三个方法检测都没有问题时,结果不溢出。
有任何的错误可在评论区指出。注:在补码中以0开头为正数,以1开头为负数
法一(较少使用)
对于两个符号相同的补码数相加,如果和的符号与加数的符号相反时,结果溢出。
两个符号相反的补码数相减,差的符号与减数的符号相同时,结果溢出如果两个同为正,相加后为负时,结果溢出
如果两个同为负,相加后为正时,结果溢出
法二
两个补码数相减,若最高数值位向符号位送的进位值,与符号位送向更高位的进位值不同时,结果溢出。
符号位的进位和最高数值位的进位不同时,结果溢出
注:符号位为二进制最左边的一位(双符号位的情况下为两位),最高数值位为二进制最左边的第二位(双符号位的情况下为第三位)。
法三(常用)
在采用双符号位运算时,若两个符号位的值不同,则结果溢出。
即运算结果出现了以01开头时正溢出,出现了以10开头时负溢出。
两个情况都为溢出。例题
【例1】两个单符号位的补码分别为01011和01000
法一:
在补码中开头为0表示为正数,开头为1表示负数。
相当于两个正数相加后变成了负数,与正+正=正的事实不符,所以结果溢出
【例2】两个单符号位的补码分别为10101和11000法二:
两个符号位都为1,可以进位。而最高数值位分别为0和1,不能进位。
一个可以进位,一个不能进位,所以结果溢出。
【例3】两个单符号位的补码分别为10100和11001法二:
两个符号位都为1,可以进位。而最高数值位分别为0和1,不能进位。
一个可以进位,一个不能进位,所以结果溢出。
【例4】两个单符号位的补码分别为10111和10101法二:
两个符号位都为1,可以进位。而最高数值位都为0,不能进位。
一个可以进位,一个不能进位,所以结果溢出。
【例5】两个双符号位的补码分别为001011和001000法三:
因为双符号位结果中出现了以01或10开头,所以结果溢出
【例6】两个双符号位的补码分别为110111和110101法二:
两个符号位都为11,可以进位。而最高数值位都为0,不能进位。
一个可以进位,一个不能进位,所以结果溢出。 -
二进制负数的补码为什么是符号位不变,其他位取反加一?
2019-10-29 22:45:44今天看了《逻辑设计基础》才明白了为什么二进制负数的补码是符号位不变,其他位取反加一 1. 什么是补码? 补码:计算机是用来将减法转换成加法的一种手段,在计算机系统中,数值一律用补码来表示和存储。 2. 如何... -
包含负数的二进制补码的加减运算
2021-08-01 08:49:27本篇文章是我的第一篇博客,用于帮助那些和我一样处于迷茫中的朋友。如若对你有帮助的话请点个赞(不介意的可以投个币)。如若引用还请注明出处!...如果我想用八位二进制补码表示怎么办? 答案是从 -
随手笔记-二进制的正负计算
2019-10-07 16:48:01负数的二进制一般通过正数反推导出,即(正数二进制 -> 取反 -> 补码(加1)),举个例子: 99的二进制为:0110 0011 那么-99的二进制计算方法为 0110 0011 1.取反: 1001 1100 即0... -
深入理解计算机底层为什么采用补码运算【如何理解二进制计算高位溢出】
2021-11-07 16:18:10因为对8-3做分解就只有8和-3这两部分,所以在数学中就是8和-3做相加),因此计算机底层设计模拟数学就需要负数,这个负数就可以使用反码进行充当–》本质上是为了将减法运算转换为加法运算。补码是为了解决数字“0”... -
负数的二进制和十进制之间的转换
2021-03-13 12:13:22十进制负数转换为二进制的方法为:1、将十进制转换为二进制数。2、对该二进制数求反。3、再将该二进制数加1.总之就是将十进制数转换为二进制数求补码即为结果。比如:-32第一步:32(10)=00100000(2)第二步:求反:... -
二进制有符号数运算及溢出判别
2019-09-02 16:32:19上面都是两个8bit相加,从左至右第一个bit位是符号位,第二个bit位是最高数值位,如果结果超出8bit,则超出的位不会在计算机中存储,因此造成溢出现象 //-------------------------------------... -
二进制负数的一些问题
2017-02-14 17:36:00对于8位二进制来说,反码与原码相加一定得:1111 1111,这是因为反码是将原码的每一位都取反了,相加的时候,每一位上都是1个1,一个0。而补码与原码相加,就是反码+1+原码,也就是: 1111 1111+0000 0001=1 -
负数的二进制表示方法
2017-07-14 10:17:25负数的二进制表示方法 假设有一个 int 类型的数,值为3,那么,我们知道它在计算机中表示为: 00000000 00000000 00000000 00000011 因为int类型的数占用4字节(32位),所以前面填了一堆0。 在计算机中,负数以其... -
二进制表示负数的方法:“ 补数 ”
2020-04-01 17:34:50在十进制中表示正负数会有专门的符号来区分,而在二进制中,怎样表示正负数呢??? 在二进制中表示负数时,一般会把位权的最高位上的数字作为符号来使用,因此,位权的最高位也称为符号位。 符号位为 0,表示正数;... -
【计算机原理】负数的二进制
2021-05-10 12:13:00若符号位为1,则表示负数 另:对具有相同字节数的整型数而言,由于有符号整数的数据位比无符号整数的数据位少了1位,而且少的这一位恰好是最高位,因此有符号整数能表示的最大整数的绝对值只有最大无符号整数的一半 ... -
怎么让加法器实现两个负数相加
2021-07-26 04:47:23请点评我们已经了解了计算机中正整数如何表示,加法如何计算,那么负数如何表示,减法又如何计算呢?本节讨论这些问题.为了书写方便,本节举的例子都用8个bit表示一个数,实际计算机做整数加减运算的操作数可以是8位、16位... -
计算机系统基础知识——详解二进制正负数及补码设计
2020-10-24 15:40:18前言:关于二进制数的补码反码等各种码,上学时候只学会了死记硬背却还是一头雾水,不懂这样设计的意义。所以总是隔很多时间后还是记不住,今天就尝试用自己的理解解释下正负数以及补码的设计,如果有不对的地方或者... -
Matlab 十进制负数转换十六进制,简单实用
2020-12-08 22:19:08对于负数转十六进制,matlab没有相关的函数可以直接转换。 原理 一个是在计算机中表达,一个是科学计数方式表达。 714 原码: 0000 0010 1100 1010 02CA -714的原码: 1000 0010 1100 1010 负数的 -
由一道二进制溢出题引发的进制_原码反码补码回顾(操作系统原理)
2018-10-30 15:13:24(我就直接写上去)在符号位中 0代表正数,1代表负数,剩下的7位二进制码表示数值。 二进制转换十进制 十进制 转换 二进制 这上面的二进制码呢,它叫原码, 注意一点,只有符号码才有原码反码补码!!! ... -
C语言中负数在计算机内部的二进制表示方式(以补码表示负数、整数的范围及所占字节数)
2020-06-15 15:41:39整数在计算机内部的表达 众所周知 在计算机的内部 ...事实上 在计算机中 二进制使用的是补码的方式来表示负数 补码 即为二进制中的11111111(请注意 并不是作为纯二进制 而是补码 若是纯二进制那么就是255了) 由于十进 -
正负数的二进制(转)
2019-05-14 18:16:47** 八位二进制数能表示数的范围...如果想要表示有符号整数,就要将最前面一个二进制位作为符号位,即0代表正数,1代表负数,后面7位为数值域,这就是原码定义。这样在现实生活中完全没有问题,但在计算机中就出现... -
二进制正负数的表示方式:原码,反码,补码
2018-03-18 09:06:25二进制正负数的表示方式:原码,反码,补码 今天学习汇编语言标志寄存器那一节,关于正负,忽然发现这个当初学的已经忘记了,特地来记录复习一下。 原码:最普通的二进制数字 反码:对源码取反 补码:反码的基础... -
二进制的减法
2020-12-09 10:15:44这里需要说明的是,在计算机中做二进制数运算时,一定要明确是在多少位的整型前提下进行的,这样才能够正确处理位数溢出的问题。 其实减法也可以看成加法 6+(-4) 无论加减法总结:补码相加 结果再求补码 1... -
计算机组成原理---二进制
2021-07-22 03:33:09一、二进制概念基于计算机内部组成原理,在内存中字节是可寻址的最小单位,每个1字节由8个0或1的二进制位组成(有时二进制位也称为比特,英文bit),最左边的二进制位称为最高位,最右边的二进制位称为最低位。... -
关于二进制补码及补码加法的思考
2021-09-06 19:56:13笔者刚学数字电路,就在二进制补码处踩了许多坑,下面就来写一下我对二进制补码的感悟。 提示:以下是本篇文章正文内容,下面案例可供参考 一、生活中了解补码 首先展示一下求补码的公式N(补)=R^n-N 这里的N是原码... -
二进制数与十进制数的相互转换、二进制数的乘除运算、移位运算
2020-04-17 11:11:28二进制数与十进制数的转换 聊二进制数的运算前,我们先看看二进制数的值与十进制数的值是如何相互转换的, 十进制转换成二进制 ...只需将二进制数的各数位的值和位权相乘,然后将相乘的结果相加即可,有木有...