源码,反码,补码间的关系

原码,反码,补码间的关系

原码: 就是二进制定点表示法,最高位为符号位, 最高位是“0”,表示该数为正数,最高位是“1”,表示该数为负数。
反码: 正数的反码与其原码相同,负数的反码是对其原码除开符号位以外的数值位逐个位取反。
补码: 正数的补码和其原码相同,负数的补码是在其反码的末尾进行加1;

因为所有参与计算的数据都是二进制的补码,所以我们要得到计算过程就得先得到这些数据对应的补码。
正数的 原码,反码 ,补码都是一样的。
负数的 反码等于 符号位 除外的其他位取反,补码等于反码最后一位加一,符号位不变;
如下:

eg:  byte类型数据,一个字节等于 8 个bits
+5 
                 符号位          数值位
原码              0           0000101
反码              0           0000101
补码              0           0000101

-7  
                符号位          数值位
  原码           1            0000111
  反码           1            1111000
  补码           1            1111001

+5  +  -7 byte 类型 进行计算是会自动提升为 int 类型,就得用 32位 ,4个字节来表示了。
如下
                 符号位                         数值位
       负数 
           原码: 1     0000000  00000000 00000000 00000111
           反码: 1     1111111   11111111   11111111   11111000      符号位不变,其他位取反
           补码: 1     1111111   11111111   11111111   11111001       反码末尾加1
       正数      0    0000000  00000000  00000000  00000101       原,反,补一个样。
 结果的补码: 1    1111111   11111111    11111111  11111110        从最右边开始两数的 0和1,逢2进1;
 再通过这个补码就可以得到结果的原码,也就可以得到十进制的结果的数值,如下:
  结果的反码: 1   1111111   11111111  11111111  11111101     补码末尾减去1
  结果的原码: 1   0000000   00000000  00000000 00000010    符号位不变,其他位取反 结果就是 -2了

+127  +  -125 byte 类型 进行计算是会自动提升为 int 类型,就得用 32位 ,4个字节来表示了。
如下
                 符号位                数值位
       负数 
           原码: 1   0000000  00000000  00000000  01111101
           反码: 1   1111111    11111111   11111111    10000010     符号位不变,其他位取反
           补码: 1   1111111    11111111   11111111    10000011     反码末尾加1
          正数 : 0   0000000  00000000  00000000   01111111    原,反,补一个样。
 结果的补码:(1) 0  0000000  00000000 00000000 00000010        从最右边开始两数的 0和1 ,逢2进1;超出的部分去掉,得到了 2
因为结果的最高位是0 ,所以是个正数,原码,反码,补码都一样,所以结果就是2了。
  
  

 ** 位运算的符号有 & , I ,^ , ~ , >> , << , >>>  ** 
3的二进制 : 00000000 00000000 00000000 00000011
4的二进制 : 00000000 00000000 00000000 00000100
(这里的两个数都是正数,所以原码,反码,补码都是一样的,但是记住在计算的时候一定是他的补码参与运算)
& 位 与 运算 (与逻辑运算符类似,相同都为1则是1,有0或者都是0结果是0,是不是和  true & false 类似呢)
  00000000 00000000 00000000 00000011
  00000000 00000000 00000000 00000100
  -----------------------------------------------------
  00000000 00000000 00000000 00000000  3 & 4 == 0(可以 验证结果 System.out.println(3 & 4);)

| 位 或 运算 (与逻辑运算符类似,有1则是1,都是0结果才是0,这个是不是也和  true & false 类似呢)
  00000000 00000000 00000000 00000011
  00000000 00000000 00000000 00000100
  -----------------------------------------------------
  00000000 00000000 00000000 00000111  3 | 4 == 7 (可以 验证结果 System.out.println(3 | 4);)

^  位 异或 运算 (与逻辑运算符类似,相同则是0,不同则是1,这个是不是也和 逻辑运算符的判断类似呢,相同则是false,不同则是true)
  00000000 00000000 00000000 00000011
  00000000 00000000 00000000 00000100
  -----------------------------------------------------
  00000000 00000000 00000000 00000111  3 I 4 == 7 (可以 验证结果 System.out.println(3 ^ 4);)

eg:^ 运算的特点是,每个数被另一个数 ^ 两次其值不改变,
int a = 10;
int b = 20;
 System.out.println(a^b^b); 
  System.out.println(b^a^a);

~  按位取反运算符  3
              00000000 00000000 00000000 00000011  补码
 (取反)11111111  11111111   11111111   11111100   补码
  这里的最高位是1 ,没错最高位是 1 的话是一个负数。
     所以我们先得到他的反码,也就是补码末尾减去 1;
              11111111  11111111   11111111    11111011    反码
               10000000 00000000  00000000 00000100  原码  
               所以结果为-4 ,验证结果(System.out.println(~3);)
~  按位取反运算符  -4
              10000000 00000000  00000000 00000100  原码
               11111111  11111111   11111111    11111011   反码
               11111111  11111111   11111111   11111100   补码
               用补码来进行 按位取反的运算 
               00000000 00000000 00000000 00000011    补码
               最高位是0,所以是个正数,原码,反码,补码相同,所以原码如下:
               00000000 00000000 00000000 00000011  原码  
               所以结果为 3 ,验证结果(System.out.println(~(-4));)
 << : 左移,左边最高位不变,右边补零。
 >>: 右移, 左边最高位是 0,左边补0,最高位是1,左边补 1;
 >>>: 无符号右移,无论最高位是1还是0,左边补0;
eg :  -24 <<< 2
 原码: 10000000 00000000  00000000 00011000  (取反,符号位不变,得到反码)
 反码:  11111111  11111111   11111111   11100111     (末尾加1,得到补码)
 补码:  11111111  11111111   11111111   11101000
左移2位: (11)11111111 11111111 11111111 10100000   补码  (最高位是1,末尾减去1,得到反码)
      反码:11111111  11111111  11111111  10011111        反码 (按位取反,最高位的符号位除外,得到原码)
      原码:10000000  00000000  00000000  01100000  原码 结果等于 -96
      验证结果:System.out.println(-24 << 2);  -24*2^2
位移计算相当于: 
左移 ==  该数 *2^位移次方
右移 == 该数 / 2^位移次方   (结果除不尽时,对结果 ceil)
 
   

进制之间的转换:

十进制的128, 用二进制来表示是: 10000000 (一个字节用 8 bits 表示) 根据二进制的公式来计算过程如下所示
byte b = 128 ;二进制数据以0b 开头 即: 0b10000000
字节表示: 10000000 == 将二进制计算成十进制数据 128= 127+0+0+0+0+0+0+0*20;
那如果用八进制来表示 128 会是什么样的呢?把二进制的源码,三位一组排列,位数不够的在右边补0,然后分别根据二进制计算十进制
的方法计算出来每一个八进制位数上数值,再跟所在的八进制 数 位数-1 次幂 相乘得到每一个8进制位数上的结果再相加得到最后结果。
八进制是三个位表示一组 ,如下: 010 000 000 得到公式 : 1
21*82+020*81+020*80=264=128 就得到了八进制对应的十进制数据 以0开头 0200;(28^(3-1))
再转换成 十六进制我们该怎么表示呢? 原理与8进制大同小异,可以参考8进制的算法。
十六进制是 4个位表示一组,如下: 1000 0000 得到公式: 123*161+020*160 =816=128 就得到了十六进制对应的十进制数据 以0x开头 0x60(6161+0*160)
这些都是二级制快速转成其他进制数的方法

这里对这种方法做一个解释。
系数:每一个位上的数据表示该位的系数;
基数:X进制的基数就是X;
权:也相当于几次方(幂) ,从右往左依次编号,从0开始。

每一个数就等于 每一个位数 * 基数 * 权
就比如十进制的 1234 == 110(4-1)+2*102+3101+4*100


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值