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

一. 机器数和真值在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.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

(0)
小su's avatar小su
上一篇 2024年8月29日 下午10:55
下一篇 2024年8月29日 下午10:57

相关推荐

  • 网络安全与IP安全网络安全 ip网络安全技术

    网络安全与IP安全网络安全网络安全与IP安全网络安全
    网络安全
    是指网络系统的硬件,软件以及系统中的数据收到的保护。
    保护的基本属性为:机密性,完整性和可用性;
    基本特征&#x

    网站运维 2024年6月27日
    0
  • 学习编程到底是什么?

    只有程序员需要学编程吗?今天,学习编程的大部分还是程序员和期望成为程序员的朋友。编程在大众眼中还是一种专门的职业技能,学了,是用来找工作的。我们可以类比“识字”

    2024年9月21日
    0
  • Spring Boot中使用LDAP来统一管理用户信息

    很多时候,我们在构建系统的时候都会自己创建用户管理体系,这对于开发人员来说并不是什么难事,但是当我们需要维护多个不同系统并且相同用户跨系统使用的情况下,如果每个

    2024年9月18日
    0
  • Eclipse 代码模板

    使用代码模板Eclipse 提供了通过定义和使用代码模板来提高工作效率与代码可预测性的能力。我们在开发 Java 程序过程中经常需要编写 main 方法:pub

    2024年9月19日
    0

发表回复

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