zoukankan      html  css  js  c++  java
  • 原码,补码,反码 和 有符合,无符号 整数知识总结

    原码 (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
    计算机中的符号数有三种表示方法,即原码反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。
    在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

    其实可以举例简单说明,

    补码加法: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。

    补码只是一种相对合理的编码方案。这个方案在负数的机器表示中解决了3个问题:
    1. 数的表示
      在数的表示上通过人为的定义来消除编码映射的不唯一性,对转换后的10000000强制认定为-128。当然对原码和反码也可以做这种强制认定,那为什么原码和反码没有流行起来?原码和反码没有流行起来,是因为在数的运算上对符号位的处理无法用当时已有的机器物理设计来实现。由于原码和反码在编码时采用了硬性的人工设计,这种设计在数理上无法自动的通过模来实现对符号位的自动处理,符号位必须人工处理,必须对机器加入新的物理部件来专门处理符号位,这加大了机器设计难度,加大的机器成本,不到万不得已,不走这条路。
    2. 数的运算
      设计补码时,有意识的引用了模运算在数理上对符号位的自动处理,利用模的自动丢弃实现了符号位的自然处理,仅仅通过编码的改变就可以在不更改机器物理架构的基础上完成的预期的要求,所以补码沿用至今。
    3. 自身逻辑意义的完整性
      补码这个编码方案要解决的是如何在机器中表示负数,其本质意义为用一个正数来表示这个正数对应的负数。所谓-20的补码是指:如何在机器中用补码形式表示-20。具体过程是这样的:将20的二进制形式直接写出00010100,然后所有位取反变成11101011,再加1变成了11101100。最简单的补码转换方式,不必去理会转换过程中的符号位,只关注转换前和最终转换后的符号位就行了。
      那么对11101100求出其补码又具有什么现实含义呢?对一个数求补,逻辑过程是对这个数的所有的二进制位按位取反再加1。现实含义是求出这个数对应的负数形式。对11101100求补就是求出这个数对应的负数的形式,直接操作下11101100,先所有位取反00010011,再加1就成了00010100。对11101100求出其补码的含义:11101100按照现行补码码制表示的有符号数是-20,对于-20求补就是求出其对应的负数-(-20),现实中-(-20)是+20,那么求补运算的结果符合现实情况吗,00010100转换成有符号数正是+20,这就说明了补码自身逻辑意义是完整的,是不会自相矛盾的。
    4. 最后,补码的总前提是机器数,不要忘了机器数的符号位含义,最高位为0表示正数,最高位为1表示负数,而最高位是指机器字长的最左边一位。字节数100B,最高位为00000100中的最左边的0。

    最后再强调一下,计算机内存都是以补码的形式存储整数的。


    百度百科: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来存储。

  • 相关阅读:
    POJ 3070 Fibonacci【矩阵连乘】
    hdu 3038 How Many Answers Are Wrong【并查集的简单应用】
    POJ 2236 Wireless Network 【并查集的简单应用 判断是否在同一连通分量】
    POJ 1984 Navigation Nightmare【并查集思路总结】
    POJ 2492 A Bug's Life【并查集的简单应用同类的判断】
    POJ 1703 Find them, Catch them【典型并查集:判断在不同的集合】
    POJ 1456 Supermarket【贪心 + 并查集】
    ZOJ 3261 Connections in Galaxy War【并查集】
    POJ 1984 Navigation Nightmare
    POJ 1988 Cube Stacking【并查集的简单应用 堆木块】
  • 原文地址:https://www.cnblogs.com/xiaoZhang521/p/11561200.html
Copyright © 2011-2022 走看看