你了解计算机的原码、反码、补码吗?

一. 机器数和真值在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.1、机器数一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号

大家好,感谢邀请,今天来为大家分享一下你了解计算机的原码、反码、补码吗?的问题,以及和的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!

1、机器数

一个数在计算机中的二进制表示形式称为该数的机器号。机器编号已签名。在计算机中,数字的最高位用于存储符号。正数为0,负数为1。

例如,十进制数字+3的计算机字长为8位。转换成二进制后为00000011 。如果为-3 ,则为10000011 。

所以,这里的00000011 和10000011 是机器号。

2、真值

由于第一位是符号位,机器号的形式值不等于实际值。例如,上面的有符号数10000011,最高位1代表负数,其实际值为-3,而不是形式上的值131(10000011转换为十进制等于131)。因此,为了区分,将带有符号位的机器号对应的真实值称为机器号的真实值。

示例:0000 0001 的真实值=+000 0001=+1,1000 0001 的真实值=000 0001=1

二. 原码, 反码, 补码的基础概念和计算方法.

在探讨机器为什么使用补码之前,我们先了解一下原码、补码和补码的概念。对于一个数字,计算机必须使用一定的编码方式来存储它。原码、补码和补码是机器用来存储特定数字的编码方法。

1. 原码

原码是符号位加上真值的绝对值,即用第一位表示符号,其余位表示数值。例如,如果是8位二进制:

[+1]原始=0000 0001

[-1]原始=1000 0001

第一位是符号位。因为第一位是符号位,所以8位二进制数的取值范围是:

[1111 1111, 0111 1111]

现在

[-127, 127]

原始代码是人脑最容易理解和计算的表示形式。

2. 反码

的表达式为:

正数的补码是它本身

负数的补码以其原码为基础,符号位不变,其余位取反。

[+1]=[00000001]原值=[00000001]逆值

[-1]=[10000001]原始=[11111110]逆

可见,如果补码代表负数,人脑无法直观地看到它的值。通常需要将其转换为原始代码,然后进行计算。

3. 补码

补码表示为:

正数的补码是它本身

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

[+1]=[00000001] 原值=[00000001] 逆值=[00000001] 补码

[-1]=[10000001] 原=[11111110] 逆=[11111111] 补

对于负数,人脑无法直观地看到二进制补码表示中的值。通常还需要将其转换为原始代码来计算其值。

三. 为何要使用原码, 反码和补码

在开始深入学习之前,我的学习建议是熟记上面的原代码、补码和补码的表示以及计算方法。

现在我们知道计算机可以用三种编码方法来表示数字。对于正数,三种编码方式的结果是一样的:

你了解计算机的原码、反码、补码吗?

[+1]=[00000001] 原值=[00000001] 逆值=[00000001] 补码

所以没必要解释太多。但对于负数:

[-1]=[10000001] 原=[11111110] 逆=[11111111] 补

可以看出,原码、补码和补码是完全不同的。既然原码是直接被人脑识别并用来计算表示的,为什么还存在补码和补码呢?

于是人们开始探索如何让符号位参与运算而只保留加法。首先我们看一下原始代码:

计算十进制表达式: 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。

所以补码的出现解决了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]。

因为机器使用的是二进制补码,所以对于编程中常用的32位int类型来说,因为第一位代表的是符号位,所以可以表示的范围是:[-231, 231-1]。当使用二进制补码表示时,多保存一个最小值。

四 原码, 反码, 补码 再深入

计算机巧妙地将符号位参与运算,将减法变成加法。它背后有哪些数学原理?

将时钟视为一位十六进制数。如果当前时间是6点,我想将时间设置为4点,该怎么办?我们可以:

1. 回拨2 小时: 6 – 2=4

2. 向前拨10 小时: (6 + 10) mod 12=4

3. 向前拨10+12=22 小时: (6+22) mod 12=4

2,3法中的mod指的是取模运算,16 mod 12=4,即16除以12后的余数为4。

所以将时钟向后转动(减法)的结果可以用向前转动(加法)来代替!

现在的重点是如何用正数代替负数。从上面的例子中,我们可以感受到一些端倪,发现一些规律。但数学是严谨的。我们不能依靠感觉。

首先介绍一下数学中的一个相关概念:同余

同余的概念

如果两个整数a 和b 除以整数m 所得的余数相等,则称这两个整数a 和b 模m 全等。

写为a==b (mod m)

读作a 和b 模m 全等。

示例:

4 模12=4

你了解计算机的原码、反码、补码吗?

16 模12=4

28 模12=4

所以4、16、28 模12 全等。

负数取模

对正数进行取模运算非常简单。但是负数呢?

以下是mod运算:的数学定义

上面是截图。我找不到如何输入“删除边界”符号(粘贴到word中后代码是乱码)。下面是用’L’和’J’来代替上图:中的’removebounds’符号

x 模y=x – y L x/y J

上式的意思是:

x mod y 是x 减去y 乘以x 和y 的商的下限。

以-3 mod 2为例:

-3 模2

=-3 – 2xL -3/2J

=-3 – 2xL-1.5J

=-3 – 2x(-2)

=-3 + 4=1

所以:

(-2) 模12=12-2=10

(-4) 模12=12-4=8

(-5) 模12=12 – 5=7

开始证明

返回时钟问题:

向后2 小时=向前10 小时

向后拨4 小时=向前拨8 小时

向后拨5 小时=向前拨7 小时

注意,这里发现的模式!

结合上面学到的同余的概念。事实上,

(-2) 模12=10

10 模12=10

-2 和10 一致。

(-4) 模12=8

8 模12=8

-4 和8 一致。

我们离成功越来越近了。要将负数替换为正数,我们只需应用同余数的两个定理:

反身性:

你了解计算机的原码、反码、补码吗?

a=a (mod m)

这个定理是非常明显的。

线性运算定理:

如果a=b (mod m), c=d (mod m) 则:

(1)a c==b d (mod m)

(2)a * c==b * d (mod m)

如果想看这个定理的证明请看:http://baike.baidu.com/view/79282.htm

所以:

7=7 (模12)

(-2)==10 (模12)

7 -2==7 + 10 (模12)

现在我们求负数的正同余。但不是7-2=7+10,而是7 -2 7 + 10 (mod 12),即计算结果的余数相等。

接下来我们回到二进制问题,看看: 2-1=1的问题。

2-1=2+(-1)=[0000 0010] 原值+ [1000 0001] 原值=[0000 0010] 逆值+ [1111 1110] 逆值

让我们先进行这一步。 -1的补码表示为1111 1110。如果将[1111 1110]视为原码,则[1111 1110]原来=-126。这里去掉了符号位,认为是126。

发现以下规则:

(-1) 模127=126

126 模127=126

那是:

(-1)==126 (模127)

2-1=2+126 (模127)

2-1和2+126的余数结果是一样的!而这个余数就是我们期望的计算结果: 2-1=1

所以一个数的补码实际上是这个数与膜的同余。而这个膜并不是我们的二元系统,而是能够表示的最大值!这就好比一个钟表,旋转一圈后总能在可表示的范围内找到正确的值!

而2+126显然相当于时钟转了一圈,而且由于符号位参与计算,正好与溢出的最高位形成正确的运算结果。

既然补码可以把减法变成加法,那么现在计算机使用的补码呢?为什么补码加1还能得到正确的结果呢?

2-1=2+(-1)=[0000 0010] 原+ [1000 0001] 原=[0000 0010] 补数+ [1111 1111] 补数

若将[1111 1111]视为原码,去掉符号位,则为:

[0111 1111]原始=127

事实上,基于反码的+1只相当于将膜的值增加:

(-1) 模128=127

127 模128=127

2-1=2+127 (模128)

此时表盘相当于每128个刻度转一圈。因此,用补码表示的运算结果的最小值和最大值应为[-128, 128]。

但由于0的特殊情况,没有办法表示128,所以补码的取值范围是[-128, 127]

我的数学一直不太好,所以如果文章中有错误的地方,请指出并给我一些建议!

用户评论

你了解计算机的原码、反码、补码吗?
←极§速

我也是刚接触这些概念,感觉有点绕! 原码还好理解,反码和补码就脑阔疼了,希望能再详细一点讲解一下

    有7位网友表示赞同!

你了解计算机的原码、反码、补码吗?
迷路的男人

小时候学过计算机基础知识,现在看到这标题就想起当年课堂上的解释了!那些原理确实很神奇,让人印象深刻

    有14位网友表示赞同!

你了解计算机的原码、反码、补码吗?
你tm的滚

我学编程的时候也用到这些概念,当时觉得好复杂!还好老师给我们讲明白了。不过你写的博客比我的课本还直观啊!

    有6位网友表示赞同!

你了解计算机的原码、反码、补码吗?
旧爱剩女

这篇文章讲解的比较清楚了,终于理解了一下计算机码的转换方式,之前一直不知道为什么会有反码和补码这些奇怪的表示法!

    有7位网友表示赞同!

你了解计算机的原码、反码、补码吗?
败类

我一直觉得计算机程序员的工作好神秘,能用代码操控电脑完成各种复杂操作的简直太牛了!这篇文章让我更了解了计算机内部是怎么工作的

    有18位网友表示赞同!

你了解计算机的原码、反码、补码吗?
回忆未来

我觉得你写的博客内容很有深度,对理解计算机原理非常关键。不过有些概念还是挺难理解的,希望你能添加一些简单的例子来帮助读者更容易掌握

    有17位网友表示赞同!

你了解计算机的原码、反码、补码吗?
心悸╰つ

我学了一点电工知识,感觉码的一些本质与数字逻辑电路有关。这篇文章让我联想到我们课堂上学习的晶体管和布尔函数!

    有9位网友表示赞同!

你了解计算机的原码、反码、补码吗?
素婉纤尘

这种解释方式不太适合我理解,我更喜欢用图形或动画来展示概念之间的关系。也许你可以尝试不同的讲解方法?

    有10位网友表示赞同!

你了解计算机的原码、反码、补码吗?
相知相惜

虽然文章内容很不错,但对我来说还是不够深入。 我更想了解不同码的具体应用场景和优缺点!

    有18位网友表示赞同!

你了解计算机的原码、反码、补码吗?
强辩

这篇文章让我对计算机的底层原理有了更深入的认识,以前只知道计算机能算,现在才知道它还要编码才能表达信息!非常受益!

    有9位网友表示赞同!

你了解计算机的原码、反码、补码吗?
七级床震

我学嵌入式程序设计的时候,经常用到补码计算,这个博客帮我回顾了一次相关知识点。文章讲解清晰易懂,感谢分享!

    有10位网友表示赞同!

你了解计算机的原码、反码、补码吗?
我怕疼别碰我伤口

我一直以为计算机的工作原理都很复杂,看完这篇文章之后反而觉得很合理。原来这些码只是将数字变换后的一个方式,让人感觉更加有趣了!

    有17位网友表示赞同!

你了解计算机的原码、反码、补码吗?
心已麻木i

虽然标题解释了基本概念,但我觉得文章内容需要更详细的讲解,比如具体有哪些操作需要用到反码和补码等等,这样才能更有效地帮助读者理解

    有17位网友表示赞同!

你了解计算机的原码、反码、补码吗?
凉凉凉”凉但是人心

我感觉这篇文章对计算机新手来说可能太难懂了。如果你能添加一些简单的案例说明,或许更容易受到欢迎

    有6位网友表示赞同!

你了解计算机的原码、反码、补码吗?
月下独酌

这个博客很有价值!它让我对计算机原理有了更清晰的认识,即使不是专业的程序员也应该了解这些基础知识,毕竟科技时代离不开算法和编码

    有16位网友表示赞同!

你了解计算机的原码、反码、补码吗?
陌上花

学习编程的时候常常会遇到关于码的概念,这篇文章讲解得非常细致明确,帮助我梳理了许多之前模糊的理解,感谢作者!

    有13位网友表示赞同!

你了解计算机的原码、反码、补码吗?
神经兮兮°

文章内容很棒,逻辑清晰易懂。不过希望作者能在图片或图表方面多做一些补充说明,能够更直观地展现这些概念之间的关系

    有17位网友表示赞同!

你了解计算机的原码、反码、补码吗?
刺心爱人i

这篇文章让我对计算机的编码方式有了更深刻的认识,原来数字背后隐藏着这么多巧妙的设计! 真是佩服科学家的智慧

    有9位网友表示赞同!

原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/99500.html

Like (0)
小su的头像小su
Previous 2024年8月29日 下午10:55
Next 2024年8月29日 下午10:57

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注