先了解什么是二进制原码:

二进制中一个字节(byte)是存储信息的最小单位,大小为8bits,即8个位,每个0或1就是一个位(bit),规定数据的最高位是符号位。符号位是1表示负数,是0表示正数。正数存储二进制原码,负数存储的是二进制的补码,补码是负数的绝对值反码加1。

 

8bits = 1byte

byte (1个字节) 

char (2个字节) 

short (2个字节) 

int (4个字节) 

long (8个字节) 

float (4个字节) 

double (8个字节)

 

看代码:

public static String bytesHexString(byte[] b) {
    String ret = "";
    for (int i = 0; i < b.length; i++) {
        String str = Integer.toHexString(b[i] & 0xFF);
        if (str.length() == 1) {
            str = '0' + str;
        }
        ret += str.toUpperCase();
    }
    return ret;
}

函数将byte[] b转化成十六进制字符串的过程中,for循环中的byte和0xFF进行与运算后使用Integer.toHexString转化出十六进制字符串。b[i] & 0xFF运算后得出的仍然是int,为什么要进行这一步?直接用Integer.toHexString(b[i])将byte强转为int行不行?

 

看例子:

0000 0001代表的是数字1 
1000 0000代表的是-1 
所以一个byte
正数最大是0111 1111,也就是数字127 
负数最大是1111 1111,也就是数字-128

 

什么是反码:

反码就是把它的原码除符号位都取反(0变1,1变0)
一个数如果是正数,则它的反码与原码相同;
一个数如果是负数,则符号位为1,其余各位是对原码取反

 

什么是补码:

补码是在反码的末位上加1,正数的原反补码是相同的

 

在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,

在内存中情况为(100000000),进位1被丢弃。

  • 一个数为正,则它的原码、反码、补码相同
  • 一个数为负,符号位为1,其余各位是对原码取反,然后整个数加1

 

例如:    

0的原码为    00000000

    0的反码为    11111111(正零和负零的反码相同)              
    0的补码为    100000000(舍掉开头的1,正零和负零的补码相同)
    1的原码为    10000001
    1的反码为    11111110                                      
    1的补码为    11111111

 

那么-1的三码如下:

首先正1的原码:

0000 0001

然后按位取反(每个位上的0变成1,1变成0):

1111 1110

最后加1:

1111 1111

 

java采用的是补码的形式,利用溢出将减法变成加法对于十进制数,从5得到1

用减法:
  5-4=1    
因为4+6满10,我们可以将6作为4的补数
用加法:
  5+6=11(去掉高位1,也就是减10)得到1.
对于十六进制数,从f到5
用减法:
  f-a=5    
因为a+6满16,将6作为a的补数
用加法:
  f+6=15(去掉高位1,也就是减16)得到5.

补充了一些知识点,回到最初的疑问:

当系统检测到byte可能会转化成int或者说byte与int类型进行运算的时候,会将byte的内存空间高位补1(也就是按符号位补位)扩充到32位,再参与运算,其二进制补码其实已经改变了,&0xff可以将高的24位置为0,低8位保持原样。这样做的目的就是为了保证二进制数据的一致性。

 

最后一个梨java bit 转换byte java byte类型转int_java

-12的二进制表示:
1111 0100
高位补齐1后变成(按符号位补位)
1111 1111 1111 1111 1111 1111 1111 0100
十六进制0xFF的二进制表示是:
1111 1111。
高24位补0(按符号位补位)
0000 0000 0000 0000 0000 0000 1111 1111
-12补码与0xFF进行与&操作,就是
1111 1111 1111 1111 1111 1111 1111 0100 &
0000 0000 0000 0000 0000 0000 1111 1111
---------------------------------------
0000 0000 0000 0000 0000 0000 1111 0100

 

 

最后:byte类型的数字要&0xff再赋值给int类型,其本质原因就是想保持二进制补码的一致性。