原码 (true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小。
例如,我们用8位二进制表示一个数,+11的原码为00001011,-11的原码就是10001011
原码不能直接参加运算,可能会出错。例如数学上,1+(-1)=0,而在二进制中原码00000001+10000001=10000010,换算成十进制为-2。显然出错了。所以计算机并不是以原码的形式存储整数的。
百度百科:https://baike.baidu.com/item/%E5%8E%9F%E7%A0%81/1097586?fr=aladdin
反码:正数的反码与其原码相同;负数的反码是对正数逐位取反,符号位保持为1。例如对于二进制原码10010求反码:11101。
例如,我们用8位二进制表示一个数,+11的反码为00001011(和原码一样),-11的反码就是1111 0100(把-11的原码10001011 符号位保持1,数值为取反)
虽然反码能存储数值,但是我们很容易可以看到,这样存储方式很不容易被人类思维理解。所以多数计算机不采用反码表示数值
百度百科:https://baike.baidu.com/item/%E5%8F%8D%E7%A0%81/769985?fr=aladdin
补码:正整数的补码是其二进制表示,与原码相同。求负整数的补码,将其原码除符号位外的所有位取反(0变1,1变0,符号位为1不变)后加1。
例如,我们用8位二进制表示一个数,+11的补码为00001011,-11的补码就是1111 0101(把-11的原码10001011 符号位保持1,数值为取反,得到数之后再+1)。
从上面的例子可以看出,对于负数来说 , 补码=原码的反码+1,对于正数来说 补码=原码=反码。
我们用4个Bit 来做个示例:
十进制数 | 原码 | 反码 | 补码 |
+7 | 0111 | 表示方式不变 | 表示方式不变 |
+6 | 0110 | 表示方式不变 | 表示方式不变 |
+5 | 0101 | 表示方式不变 | 表示方式不变 |
+4 | 0100 | 表示方式不变 | 表示方式不变 |
+3 | 0011 | 表示方式不变 | 表示方式不变 |
+2 | 0010 | 表示方式不变 | 表示方式不变 |
+1 | 0001 | 表示方式不变 | 表示方式不变 |
+0 | 0000 | 表示方式不变 | 表示方式不变 |
-0 | 1000 | 1111 | [1]0000 |
-1 | 1001 | 1110 | 1111 |
-2 | 1010 | 1101 | 1110 |
-3 | 1011 | 1100 | 1101 |
-4 | 1100 | 1011 | 1100 |
-5 | 1101 | 1010 | 1011 |
-6 | 1110 | 1001 | 1010 |
-7 | 1111 | 1000 | 1001 |
-8 | 超出4个bit所能表达范围 | 超出4个表达范围 | 1000 |
其实可以举例简单说明,
补码加法:51+41,51补码=0011 0011,41补码=0010 1001。所以 00110011+00101001=01011100(十进制92)
补码减法:51+(-41),51补码=0011 0011,(-41)原码= 1010 1001,反码=1101 0110,补码=1101 0111。所以 00110011+11010111=[100001010] 00001010 (十进制10)
注:因为计算机中运算器的位长是固定的(定长运算),上述运算中产生的最高位进位将丢掉,所以结果不是100001010,而是00001010。
最后再强调一下,计算机内存都是以补码的形式存储整数的。
百度百科:https://baike.baidu.com/item/%E8%A1%A5%E7%A0%81/6854613?fr=aladdin
了解了原码反码和补码,之后,我们就可以比较容易理解有符号和无符号整数的概念了
有符号整数:正整数+负整数+0
无符号整数:正整数+0
当数据类型是有符号类型时,就需要用一个位来标记正负号,当数据类型为无符号整数时,就不需要用位来标记正负。有无符号取值范围对比如下:
所以一个字节Byte=8bit 的范围就可以知道
有符号 |
无符号 |
|
最大值 | 0111 1111=127 | 1111 1111=255 |
最小值 | 1000 0000=-128 | 0000 0000=0 |
有符号:0111 1111 = 2^6+2^5+2^4+2^3+2^2+2^1+2^0 = 127; ==> 范围是 -128 ~ 127
无符号:1111 1111 = 2^7+2^6+2^5+2^4+2^3+2^2+2^1+2^0 = 255;==> 范围是 0 ~ 255
但是我们或许还有一个疑问。1111 1111在有符号时 = -1,在无符号时 =255 。那是不是矛盾了呐?
(以下内容是我个人的理解,不一定完全正确,仅供参考)
我觉得可以这么理解,计算机怎么存储整数,是和你定的数据类型有关。
C#中定义的整数数据类型有
|
有符号 |
无符号 |
8位 |
SByte ,sbyte, |
Byte ,byte |
16位 |
Int16,short |
UInt16,ushort |
32位 |
Int32,int |
UInt32,uint |
64位 |
Int64,long |
UInt64,ulong |
对于sbyte类型来说-1在计算机内存中就用1111 1111来存储,对于byte类型来说255在计算机内存中就用1111 1111来存储。
原文:https://www.cnblogs.com/xiaoZhang521/p/11561200.html