我对补码的理解

我对补码的最初的印象是大一的时候老师说按位取反再加一,却不知道为什么这样做,最近看了一下资料,总结一下我的理解吧。

一、计数系统

一个计数系统可以存多少容量状态的数,我叫它作为计数系统的Mod。一个计数系统不断地加一,那么它表示的数的状态也会周期性地变化,我叫这个周期的大小叫做Mod。

举个两个例子,1、一个包含两个bit的存储单位,它可以表示00,加一变成01,加一变成10,加一变成11,再加一又变成了00。即该计数系统的Mod为4。2、一个时钟显示十二个小时,时针旋转一周后回到原来的状态,即该系统的Mod为12。

由此,可以得到一个结论。这种周期性变化的计数系统,一个状态加减整数倍的Mod,其状态不会有不会发生变化。00加上4次之后还是00,12点时阵转两圈后还是12点。

二、变减为加

在计算机中使用加法器对数据进行计算,那么如何进行减法的运算呢?

设Mod=16

若a=3,b=-4,则a+b=a+b+Mod=-1+Mod=a+(Mod-4)=15(在计数系统中-1和15等价)

实际上Mod-4就是b的补数,所有的减法在计算机中都可以转化为加上减数的补数,对应计算机上的概念就是补码

因此,计算机是使用补码(补数)进行计算

三、约定的正负号

设现有一个4位的计数系统,那么我们可以知道该系统的Mod=16,即该系统一共可以表示16个状态。我也约定这个四位系统的0000状态为0,向前连续加十六得到0000本身,对应表示的数字如下:

1111 = 15    0000 = 0

1110 = 14    0001 = 1

1101 = 13    0010 = 2

1100 = 12    0011 = 3

1011 = 11    0100 = 4

1010 = 10    0101 = 5

1001 = 9    0110 = 6

1000 = 8    0111 = 7

如果这个计数系统是无符号位的,显然可以知道它表示的数据范围为:0~15

如果这个计数系统是有符号位的呢?

首先要对这些数据进行分配,现在的教科书上的做法就是把Mod前一半划分给0~7,后一半Mod划分给-8~-1,即如下图(这里二进制都是补码):

1111 = -1    0000 = 0

1110 = -2    0001 = 1

1101 = -3    0010 = 2

1100 = -4    0011 = 3

1011 = -5    0100 = 4

1010 = -6    0101 = 5

1001 = -7    0110 = 6

1000 = -8    0111 = 7

现在约定最高位为符号位,则显然正数的补码就是它本身,负数的补码和原码对照图如下

1111 = -1    1001  ->  1110  +1  ->  1111

1110 = -2    1010  ->  1101  +1  ->  1110

1101 = -3    1011  ->  1100  +1  ->  1101

1100 = -4    1100  ->  1011  +1  ->  1100

1011 = -5    1101  ->  1010  +1  ->  1011

1010 = -6    1110  ->  1001  +1  ->  1010

1001 = -7    1111  ->  1000  +1  ->  1001

1000 = -8    1000  ->  1111  +1  ->  1000

这不正是按位取反再加一么。

时间: 2024-10-29 19:10:40

我对补码的理解的相关文章

对于补码的理解

对于补码的理解,一直以来都觉得太巧合,但又明知这不是巧合干的出来的.这次思考补码的意义中,突然发现之前所做的都是那么白痴. 二进制数就应该从它本身出发来思考,而不是利用各种同余(mod 8)来”验证“(分类讨论最没意思了). (以下均用4位二进制数来描述) 对于二进制,我们知道它的符号位是最高位,因此我们就把它当做,正数无可厚非就是本身,负数的话除了数值本身要加8.(即将最高位变成1,这里因为是4位二进制数,所以是+8 ) 补码又是什么呢?正数补码不变,负数补码是符号位不变,其余位取反+1,比如

Java Integer 进制转化的实现(附源码),对模与补码的理解

1.toBinaryString方法的实现 1 public static String toBinaryString(int i) { 2 return toUnsignedString0(i, 1); 3 } 4 private static String toUnsignedString0(int val, int shift) { 5 // assert shift > 0 && shift <=5 : "Illegal shift value";

原码、反码、补码的理解与思考

原码.反码.补码都是二进制表示数的方式 原码原码:首位为符号位,0表示整数,1表示负数,其余位表示数值,例如0011表示+3,而1011表示-3.优点:符合人类阅读习惯,无论正数负数都能马上读出来缺点:计算机做运算的时候不会把符号位提取出来,然后单独计算数值位的,而是把整个数包括符号位一起参与运算,于是就导致了问题一:0011+1011=1110(-6)的错误计算结果.问题二:0存在着两种表示方式.正零和负零的问题0000(+0).1000(-0) 思考:如果世界上只有加法,没有减法:只有正数,

对char类型的理解以及对补码的理解分析

今天遇到这样一个小程序,觉得当中有些问题很容易让人忽略的! 这个程序代码如下: 程序的结果为: 我想很多像我一样的小白可能才开始是想不明白为什么最后的结果是255吧!首先,我们得知道 strlen()是计算字符串长度的函数,但为什么最后得到的字符串长度是255呢?定义的数组a中不是有1000个元素,并且for循环也是执行999次吗? 对于char来说,我们得知道其隐含的结束标记是\0,当编译器识别一个char类型的变量时,读取到\0,则标志着结束:对于这个程序,我们还得注意char的取值围:-1

java中二进制反码补码的理解

7句真言 1,二进制最高位是符号位 0正数 1负数 2,正数的原码,反码,补码都一样 3负数的原码反码 补码 (符号位不变,其他的位数取反 0->1 1->0) 4 0的反码补码都是0 5java中没有无符号数,换句话说,java中的数都是有符号的 6计算机运算的时候,都是以补码的方式来运算的 7,负数的补码 = 他的反码+1

对补码的理解

图上第一行signed char 占了8位,其中一位是符号位.其余7位是数字位,可以存2的7次方个数(0-127共128个数). 十进制-128--1在存储时用二进制-0000000(0)--1111111(127)表示 十进制0-127在存储时用二进制+0000000(0)-+1111111(127)表示 正数的补码等于源码,负数的补码等于:原码的符号位不变,数值位逐位取反再加1 十进制 二进制 -231,...,-1,0,1,...,231 -1,...,-231,0,1,...,231 

补码如何理解

补码就是同余,这其实就是一个环 比如八位的带符号的数,所以8位只能表示256个数,即0-255 同余定理:给定一个正整数m,如果两个整数a和b满足a-b能够被m整除,即(a-b)/m得到一个整数,那么就称整数a与b对模m同余,记作a≡b(mod m).对模m同余是整数的一个等价关系. -128与+128模256 同余 -128的补码就是128的原码 128的原码就是-128的补码 +-原码------补码-----原码二进制--+ | 255 -1 11111111 | | 254 -2 111

补码理解

关于补码的理解 1.理解周期: 以时间为例,12小时制,13点就代表了1点.对于处于3点的位置如何移动到8点? 1.顺时针移动5个点位.3 + 5 = 8 2.逆时针移动7个点位.3  - 7 = 8 2.加法减法: 在一个周期计数体制里进行减法可以归并为加法,以上述例子为准:3-7=3+5 推导过程:3-7 = 3-7 + 12 = 3 + (12-7) = 3+5 所以在进行减法计算时被减数可以存储为:(周期数-被减数) 3.关于补码: 为什么要以补码存储负数,如何让符号位参与运算? 计算机

深入理解计算机系统 第二章 信息的表示和处理

欣哥划重点: @所有人, 第二章比较难,我建议至少掌握下面几个知识点: 1. 字节顺序 : 大端和小端 2. 运行 图2-24, 图2-25程序 show-bytes.c 观察结果,看看有什么问题 3. 理解布尔运算,位运算 4. 理解无符号数和有符号数, 给一个数,能计算出补码 5. 理解浮点数的表示法,给一个十进制小数,能转换成二进制的浮点数表示 原文地址:https://www.cnblogs.com/stone94/p/9824395.html