用同余理解补码

机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了.

1-1 = 1 + (-1) = 0

于是人们开始探索将符号位参与运算, 并且只保留加法的方法. 首先来看原码:

一、原码

计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [00000001] + [10000001] = [10000010] = -2

如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使用原码表示一个数.

二、反码

为了解决原码做减法的问题, 出现了反码:

正数的反码是其本身

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [0000 0001] + [1000 0001]= [0000 0001] + [1111 1110] = [1111 1111] = [1000 0000] = -0

发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的,

但是0带符号是没有任何意义的. 而且会有[0000 0000]和[1000 0000]两个编码表示0.

三、补码

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

于是补码的出现, 解决了0的符号以及两个编码的问题:

1-1 = 1 + (-1) = [0000 0001] + [1000 0001] = [0000 0001] + [1111 1111] = [0000 0000]=[0000 0000]

这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:

(-1) + (-127) = [1000 0001] + [1111 1111] = [1111 1111] + [1000 0001] = [1000 0000]

-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000] 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128,

所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000], 这是不正确的)

使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制,

使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].

四、同余

7 ≡ 7 (mod 12)

(-2) ≡ 10 (mod 12)

7 -2 ≡ 7 + 10 (mod 12)

参考:

1.补码

2.补码

时间: 2024-11-08 19:24:41

用同余理解补码的相关文章

理解 补码

引出问题为什么使用补码表示二进制: 因为方便计算. 理解补码:在十进制中9-3=6,因为3+7=10,对于加减运算 -3其实可以看做是7,也即9+7=16(高位移去即减10)=6.二进制也是如此理解. 在程序中所有的二进制都用补码来表示的话,就不会有+,-符号的处理. 验证一下: 1的原码.反码.补码:00000000000000000000000000000001 -1的原码:10000000000000000000000000000001 -1的反码(除符号位其余为取反):111111111

负整数为什么存成补码?

--理解补码的正确姿势 一.计算机为什么对负整数使用补码的形式存储 出于简化计算机基本电路的考虑,让加减法都只需要用加法电路实现.所以需要把减去一个正数或加上一个负数都用加上一个正数的方式来表示,于是在存储的时候,负数被直接存储成一种可以直接当成正数加的形式,这种形式就是补码 二.那么补码具体是什么?补码是怎么做到加一个数跟减另一个数一样效果的? 1. 先从时钟这个身边的例子理解 "加一个数跟减另一个数一样效果" 假设你对钟的时候如果发现它是6点,但实际上现在是2点,也就是它走快了4个

计算机中的原码,反码,补码,以及他们在内存中的存储形式。

1.原码 原码就是早期用来表示数字的一种方式: 一个正数,转换为二进制位就是这个正数的原码.负数的绝对值转换成二进制位然后在高位补1就是这个负数的原码 举例说明: int类型的 3 的原码是 11B(B表示二进制位), 在32位机器上占四个字节,那么高位补零就得: 00000000 00000000 00000000 00000011 int类型的 -3 的绝对值的二进制位就是上面的 11B 展开后高位补零就得: 10000000 00000000 00000000 00000011 但是原码有

聊一下补码1

对于补码一直只知道应用方法,就是正数的补码是其本身,负数的补码是其对应正数的每一位取反后加一,这样减法操作就可以用加法来实现.但是一直不太明了其原理,今天就来掰开揉碎了聊一下. 补码源自于数学上补数的概念和方法,所以理解补码必须先理解补数. 补数 补数(radix comletment)的定义:有一个以b为基数,位数为n的数字y,y的补数即是b的n次方减去y.例如,基数是10,三位数123的补数就是877(1000-123). 缩减基数补数(diminished radix complement

关于补码

关于补码: 为什么要用补码? 计算机中只有加法,所谓的减法也是加法.为了理解补码,我们可以考虑到钟表的例子.钟表一圈是12个时辰, 也就是12小时,3点+4点 = 7点,3点 + 10点 =?(对不起,越界了,不能表示),因为它是12进制,也就是说只 能表示0-11这12个点,超过了就越位了,就不能计算了.所以针对这个范围,我们只能计算结果在(0-11)的数. 那么针对减法诸如 8点 - 7点 该怎么计算呢?这时候就用到了补码的知识了,8点 - 7点 = 8点 + (-7点)= 8 点 + 5点

原码、反码、补码的产生、应用以及优缺点有哪些?

作者:张天行链接:https://www.zhihu.com/question/20159860/answer/119405396来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 二.重温运算规则 首先我想把整套关于原码反码补码的运算规则准确清晰地写一遍,方便急需应用的知友参考,也希望大家首先能记住这套规定,再开始进一步的探讨. 所谓原码就是机器数,是加了一位符号位的二进制数,正数符号位为0,负数符号位为1,计算机中存储.处理.运算的数据通常是8位.16位.32位或

对C语言整数类型的一点理解

1.先从一个列子引出问题: //sample_1 unsigned char  #include <stdio.h> #include <stdlib.h> int main() { unsigned char a = 255; a = a + 1; printf("a = %d\n", a); return 0; } 输出结果: 为什么是0 而不是256, 这是很显然的发生了溢出.现在从机器存储的角度来看这个问题: 在C语言中,char表示占用一个byte空间

补码原理——负数为什么要用补码表示

https://blog.csdn.net/leonliu06/article/details/78685197 文首   我们都知道负数在计算机中是以补码(忘了补码定义的戳这里)表示的,那为什么呢?本文尝试了解补码的原理,而要想理解它,首先得理解算术中“模”的概念.所以首先看一下什么是模,然后通过一个小例子来理解补码. 1 模(Modulo) 1.1 什么是模数 In mathematics, modular arithmetic is a system of arithmetic for i

补码一位乘法(Booth算法,C语言实现)

补码一位乘法 首先了解下什么是补码? 补码概念的理解,需要先从“模”的概念开始. 我们可以把模理解为一个容器的容量.当超出这个 容量时,会自动溢出.如:我们最常见到的时钟,其容量 是 12,过了 12 点之后,就会变为 1 点, 2 点……也就是 说,超过12的部分将被丢弃.那么,在这个例子当中,时钟 的模就是12.模的概念可以帮助我们理解补码的含义. 补码的引出:假设现在时钟的时针指向 4 点的位 置,要使其指向 3 点,可以怎么操作呢?很明显,共有 2 种方法,顺时针拨 11 格(+11),