java中的原码、反码和补码

来源:互联网 发布:淘宝3c证书编号怎么弄 编辑:程序博客网 时间:2024/05/21 11:06

转载地址:http://blog.csdn.net/xiaohai0504/article/details/6925553

 为什么要用?
计算机内部采用二进制表示数值。如十进制数10用二进制数表示为1010。设计算机字长为8,即1Byte。最高位表示符号,0为正,1为负
来看看用原码表示的数在进行加减乘除运算是会有什么问题:
十进制:1-1=1+(-1)=0
原码:(0000 0001)-(0000 0001)=(0000 0001)+(-0000 0001)=(0000 0001)原+(1000 0001)原=(1000 0010)原=-2,显然不正确
以上的运算说明了负数(也就是带符号数字,正数没问题)原码运算在某些时候得不到正确结果。
再来看反码表示进行加减乘数运算会有什么问题:
十进制:1-1=1+(-1)=0
反码:(0000 0001)-(0000 0001)=(0000 0001)+(-0000 0001)=(0000 0001)反+(1111 1110)反=(1000 0000)反=-0,出现了负0.
一般不区分+0、-0,用反码就会出现这样的问题。
最后看看补码运算:
十进制:1-1=1+(-1)=0
补码:(0000 0001)-(0000 0001)=(0000 0001)+(-0000 0001)=(0000 0001)补+(1111 1111)补=(0000 0000)补=0
补码具有自己独特的优点,用补码连同符号位一起运算没有出现原码、反码的问题,这就是为什么现代计算机普遍采用补码运算的原因。
计算方法:
         由于正数加减运算不存在此问题,所以正数没有反码、补码,或者说正数的原码、反码、补码都一样
          原码:负数的原码为1|x|
          反码:负数的反码,符号位不变,数值取反
          补码:负数的反码加1(会影响符号位)
范围解疑
          这里以byte为例来解释一下取值的范围。byte占一个字节,是8位。如果是无符号类型的整数,那么原码最大值11111111,所以原码范围就是0---255(也就是0~~2^8-1),总共256个数。
          对于有符号类型的byte值,那么原码最大值应该是01111111(第一位的1代表负数符号),最小值应该是11111111,所以原码范围是(-127~-0 +0~127),总共256个数。但是在有符号原码进行加减运算时的问题(原码运算不正确,反码出现+0、-0),所以出现了补码。对于十进制:127 + 1 = -128 ,补码算法:01111111 + 00000001 = 10000000 ,这里的10000000原码就是-0,所以在计算机中1000000的补码表示的就是 -128。需要注意的是:-128是没有原码和反码的,只有补码!
总结:
1>补码的设计目的是:
        ⑴ 使符号位能与有效值部分一起参加运算,从而简化运算规则。补码机器数中的符号位,并不是强加上去的,是数据本身的自然组成部分,可以正常地参与运算。
        ⑵ 使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计。
2>反码是原码与补码转换的一个中间过渡,使用较少。
3>所有这些转换都是在计算机的最底层进行的,而在我们使用的汇编、c等其他高级语言中使用的都是原码。