从计算机中数据类型的存储方式,思考理解原码,反码,补码

Posted muahao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从计算机中数据类型的存储方式,思考理解原码,反码,补码相关的知识,希望对你有一定的参考价值。

从计算机中数据类型的存储方式,思考理解原码,反码,补码

1. 数据类型

首先,我们知道,在C中,设计了两个类型的数据:

  1. 有符号数据类型
  2. 无符号数据类型
==== signed & unsigned 

打印方式: signed: %d, unsigned: %u
数据范围: 
signed: [-128, 127]
unsigned: [0, 255]

2. 无符号数据类型 - 原码,反码,补码

在学习计算机的过程中,很快出现了:原码,反码,补码的概念。这里你肯定不会理解为什么要设计这个玩意儿的! 因为你不知道 “有符号数据类型” 在 计算机中是怎么存储的。你需要看下一段。

1. 反码,补码是针对有符号类型的数来讲的,对于unsigned 没有意义;
2. 补码 一般用来表示负数;

对于一个带符号的数字来说,比如:signed int i = 7和 signed int j = -7
正数:(7)(正数首位为0)
原码:0000 0111 
补码:0000 0111 (正数的补码等于原码,这个是规定,不要考虑正数是否有反码)

负数:(-7)(负数首位为1)
原码:1000 0111 
反码:1111 1000  反码=(对于负数来说,首位不变,其他位反转)
补码:1111 1001

3. 数据的存储:

在这里,你需要理解一下,计算机对有符号数据类型,和无符号数据类型的存储方式不同;

无符号数的存储:

无符号数没有原码,补码之说,直接转换成二进制;

有符号数的存储:

  • 有符号数采用补码的形式存储,无论你是正数还是负数,只要你是有符号数;(重要)
  • 正数的补码,等于其原码
  • 负数的补码,等于反码加1

4. 特殊的0的编码问题

在有符号的数据类型下,0会出现两个表达方式:+0, -0

那么首先,我们看看如果按照其他负数的逻辑,+0 和 -0的反码分别怎么表示?

原则: 对于负数,首位不参与运算,负数的补码等于反码加一;那么,-0的补码等于:1000 0000 +0的补码等于:0000 0000

+0 和 -0
+0:
原码:0000 0000 
补码:0000 0000 

-0:
原码:1000 0000 
反码:1111 1111
补码:1000 0000 

什么?0 虽然在signed情况下,有两种表达方式(+0,和-0),但是毕竟都是一个数0啊,怎么0可以有两个补码?不允许啊,这台浪费了吧!!!

因此,在不能浪费的理念下,计算机又新增规定:对于0有+0, -0这个特殊情况下,这个时候,最高符号位要参与运算;此时,无论是数字0来说,无论是+0 还是 -0,其补码只有一个,那就是0000 0000;

这个时候,你又会发现,多余了一个1000 0000 没人用吗?怎么办呢? 在计算器中,又出台规定将这个没有用的1000 0000表示-128;

所以,你会看到,对于有符号数,数据存储范围多了一个:-128

数据范围:

  • 有符号数:[-128, 127]
  • 无符号数:[0, 255]

5. 使用补码的好处?

看到了特殊的0的解释之后,你会发现,在有符号数据类型中,使用补码的好处是:

  1. 解决了0的编码问题
  2. 可以多保存一个数:-128, 如signed char 可以多保存一个:-128
  3. 多保存的一个数:-128,没有原码和反码

6. 为什么使用补码来存储数据?

  1. 解决0的编码问题
  2. 减法运算可以转化为加法运算,省去硬件上的减法电路,CPU只需要有:全加器,求补电路

7. 思考 - 为什么设计补码?

规则: 补码 = 反码 + 1

我们已经知道对于“符号类型的数”,他的补码等于反码加一,我们思考一下,这个规则是怎么来的?想明白了,也就明白为什么要设计“补码”了!

首先,我们知道 7的二进制原码是:0000 0111

那么我们思考一下,什么值 和 7 相加等于0?

小学生都知道,答案是:-7,于是,你会发现好几个二级制数字,都能满足这个条件,难道让他们都表示-7吗? 肯定不可能啊!

1111 1001
1111 1010
1111 1100

现在核心思想就在这里,计算机用巧妙之处体现出来了! 计算机想了,既然他们都满足条件,我是不可能让他们都表示为-7的,我要重新设计一个规则,使得,只有一个数满足!于是这个规则就出现了:

先设计一个数,可以和7相加后等于: 1111 1111 , 然后再加1 就等于0了;

所以:

7: 
0000 0111   = 1111 1111 
+ 
1111 1000 

所以,-7在存储的时候一定要存成:1111 1001 ,而不是:-7的原码(1000 0111), 那么我们就设计一个概念“补码”, 使得-7的补码等于要存储的值(1111 1001), 从-7的原码到-7的补码就是我们的规则:首位不变,其他位反转成“反码”,然后再加1;

以上是关于从计算机中数据类型的存储方式,思考理解原码,反码,补码的主要内容,如果未能解决你的问题,请参考以下文章

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

原码反码补码&浮点类型的存储

从java toBinaryString() 看计算机数值存储方式(原码反码补码)

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

深入理解计算机系统

课堂动手动脑