JavaSE - 原码,反码,补码和>>以及>>>

简介: JavaSE - 原码,反码,补码和>>以及>>>

【1】原码

原码表示法是机器数的一种简单表示法。

其符号位用0表示正数,用1表示负数,数值一般用二进制形式表示。

  • [x]原=符号位+绝对值
x=+1100110       [x]原=01100110   
x= -1100110      [x]原=11100110

所以用8位二进制数来表示整数原码时,其表示范围: 最大数:01111111,为(+127)D 最小数:11111111,为(-127)D


【2】反码


机器数的反码可由原码得到。

如果机器数是正数,则机器数的反码与原码一致;

若机器数是负数,则机器数的反码是它的原码(符号位除外)的各位取反而得到。

即:

正数:[x]反=[x]原


负数:[x]反=对[x]原除符号外的各位取反

x=+1100110       [x]反=01100110  ;
x= -1100110      [x]反=10011001


【3】补码

机器数的补码也可由原码得到。

如果机器数是正数,则机器数的补码与原码一致。


若机器数是负数,则机器数的补码是它的原码(符号位除外)的各位取反,并在末位加1而得到。即:反码是作为求补码的中间过程。

  • 正数:

[x]补=[x]原

  • 负数:

[x]补=[x]反+1

x=+1100110       [x]补=01100110  
x=-1100110       [x]补=10011010

注意:补码的0只有一种表示形式!

[+0]原=00000000    [-0]原=10000000 
 [+0]反=00000000    [-0]反=11111111    
 [+0]补=[-0]补=00000000

所以用8位二进制数来表示整数补码时,其表示范围: 最大数:01111111,为(+127)D 最小数:10000000,为(-128)D

这里需要特别注意的是,计算机是以有符号的补码的形式存储数据,最高位为符号位,在运算过程中符号位并无差别也直接当作普通值进行步进运算!


如下所示,分别打印byte类型的正数和负数:

byte a=33;
byte b1=-3;
System.out.println(Integer.toBinaryString(a&0xFF));
System.out.println(Integer.toBinaryString(b1&0xFF));


结果如下:

100001
11111101



20190118112044392.png


【4】>>(<<)和>>>(<<<)

① >>

有符号按位右移运算符。左操作数按位右移右操作数指定的位数,符号位不变,空出来的高位补符号位


输入1个参数b;n = 1;b为负数,第一个位符号位为1。

b对应位全部右移动n位得到c;b最右边n个位全部丢掉(红色框),c最左边n个位补充1(绿色框)。

这里需要注意的是其左边补充的值取决于b的最高位也就是符号位:符号位是1则补充1,符号位是0则补充0。


② >>>


无符号按位右移运算符。左操作数按位右移右操作数指定的位数,符号位跟着移动空出来的高位补0(左边补充的值永远为0,不管其最高位(符号位)的值)。

测试如下:

  @Test
  public void testFuHao(){
    int a = 6; 
    int b = -6; 
    System.out.println(a+","+Integer.toBinaryString(a) );//110
    int i1 = a>>2;
    System.out.println(i1+","+Integer.toBinaryString(i1) );//1
    int i2 = a>>>2;
    System.out.println(i2+","+Integer.toBinaryString(i2) );//1
    System.out.println("*********************************************************");
    System.out.println(b+","+Integer.toBinaryString(b) );//
    int i = b>>2;
    System.out.println(i+","+Integer.toBinaryString(i));//
    int j = b>>>2;
    System.out.println(j+","+Integer.toBinaryString(j));//
  }


结果输出如下:

6,110
1,1
1,1
*********************************************************
-6,11111111111111111111111111111010
-2,11111111111111111111111111111110
1073741822,111111111111111111111111111110


正数,原码、反码和补码一致。

负数计算就稍微麻烦一点,根据上面所讲的计算方法很快可以验证结果。

最后一个数据,只有30位,前面00没有展示出来。

当b>>>2之后,补码形式为正数,转为十进制为2^30-2=1073741822。

为什么是32位???

因为是 int !



【5】& | ^ 和取反

假设a b(注意是补码形式)如下:

byte a = (byte)0b01011000 //88
byte b = (byte)0b10101000 // -88


① 按位与 a & b

输入2个参数,a、b对应位都为1时,c对应位为1;反之为0。


② 按位或 a | b

输入2个参数,a、b对应位只要有一个为1,c对应位就为1;反之为0。


③ 按位异或 a^b

输入2个参数,a、b对应位只要不同,则c对应位就为1;反之为0。


④ 按位取反(非)

输入1个参数,c对应位与输入参数a完全相反;a对应位为1,则c对应位就为0;a对应位为0,则c对应位就为1。

【6】进制表示规范

① 前缀


  • 十进制:直接写数字即可
  • 二进制:0b或0B开头;如:0b01011000 代表十进制 88
  • 八进制:0开头;如:0130 代表十进制 88 (1x64+3x8)
  • 十六进制:0x或0X开头;如:0x58 代表 88 (5x16+8)


② 后缀

0x?? 若小于127 则按byte算,大于则按int类型算

0xFF默认为int类型

若声明为long添加后缀:L或l:如:0xFFL 或 0xFFl

带小数的值默认为double类型;如:0.1

若声明为float添加后缀:f 或 F:如:0.1F

若声明为double添加后缀:d或D:如:1D


③ 范围


  • 二进制:1、0
  • 八进制:0~7
  • 十进制:0~9
  • 十六进制:0~9 + A~F

【Tips】:

注意:计算机存放数字都是存放数字的补码,正数的原码、补码、反码都一样,负数的补码是其反码加一。符号位做取反操作时不变,做逻辑与、或、非、异或操作时要参与运算。


目录
相关文章
|
6月前
|
存储 编译器 C语言
【原码、反码、补码】小白看完都呲大牙
【原码、反码、补码】小白看完都呲大牙
190 1
【原码、反码、补码】小白看完都呲大牙
|
6月前
|
Java 程序员
Java基础之原码,反码,补码,位运算符
Java基础之原码,反码,补码,位运算符
|
1月前
深入解析计算机科学的基础:原码、反码与补码
深入解析计算机科学的基础:原码、反码与补码
|
5月前
|
存储
一分钟了解什么是原码-反码-补码
一分钟了解什么是原码-反码-补码
|
5月前
|
程序员
程序员必知:原码、反码、补码和移码详解
程序员必知:原码、反码、补码和移码详解
103 0
【软考学习2】数据表示——原码 反码 补码 移码
【软考学习2】数据表示——原码 反码 补码 移码
137 0
|
存储
寒假刷题之原码/反码/补码
寒假刷题之原码/反码/补码
68 0
数字逻辑基础:原码、反码、补码
数字逻辑基础:原码、反码、补码
184 0
|
存储
[软考]之原码、反码、补码和移码
[软考]之原码、反码、补码和移码
115 0
计算机原码反码补码
又把原码、反码、补码忘了,这里再来分析一下
计算机原码反码补码