位转移 - 为什么在用24,16和8的代码右移?

问题描述 投票:0回答:2

我在看这个java代码,并试图了解它。我了解一切,除了位偏移部。

我知道下面,代码使用比特移位正在建立的一些值以字节[]填满但我不知道为什么具体地说,它使用右移位和为什么24,然后如图16所示,然后8位?在哪里,为什么这些值回升,而不是其他一些价值?

private void Send(NetSocket out, int MsgID, byte MsgSeq, char MsgLetter, String data) 
{
    int msglen = data.length() + 2; 
    byte[] msg = new byte[msglen + 8];
    byte[] md = data.getBytes();
    msg[0] = (byte) (msglen >> 24);
    msg[1] = (byte) (msglen >> 16);
    msg[2] = (byte) (msglen >> 8);
    msg[3] = (byte) (msglen);
    msg[4] = (byte) (MsgID >> 24);
    msg[5] = (byte) (MsgID >> 16);
    msg[6] = (byte) (MsgID >> 8);
    msg[7] = (byte) (MsgID);
    msg[8] = (byte) MsgLetter;
    msg[9] = MsgSeq;
    System.arraycopy(md, 0, msg, 10, msglen - 2);

    // send
}
java bit-shift
2个回答
1
投票

如果你有一个32位整数,你可以把它当作4个8位整数:

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01
\---------------------/ \---------------------/ \---------------------/ \------------------/
  bits 24-31 (8 bits)     bits 16-23 (8 bits)      bits 8-15 (8 bits)     bits 0-7 (8 bits)

大端编码是您第一次发送的最显著字节,所以你要24-31位的第一个字节,位在第二个字节16-23,等等。对于网络通信的标准字节顺序是大端。 (小端是周围的其他方法,并且通常用于在x86和一些其他平台的内存存储。)

如果转换为字节的整数,最显著位被扔掉。

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01
\---------------------/ \---------------------/ \---------------------/ \------------------/
  bits 24-31 (8 bits)     bits 16-23 (8 bits)      bits 8-15 (8 bits)     bits 0-7 (8 bits)


             cast to (byte)
                                                                        07 06 05 04 03 02 01
                                                                        \------------------/
                                                                          bits 0-7 (8 bits)

如果你右移,你搬过来的位,这样就可以转换为(byte),先后获得32位整数的其他部分:

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01
\---------------------/ \---------------------/ \---------------------/ \------------------/
  bits 24-31 (8 bits)     bits 16-23 (8 bits)      bits 8-15 (8 bits)     bits 0-7 (8 bits)
          |
          \---------------------------- >> 24 -----------------------------------\
                                                                                 |
                                                                        07 06 05 04 03 02 01
                                                                        \------------------/
                                                                        previously bits 24-31
                                                                        now bits 0-7 (8 bits)


1
投票

这简直是​​装箱4个字节的32位整数为4个连续字节的,小心使用特定的字节序(在这种情况下大端)。它只是说:

// put the "biggest" 8 bits into the first byte,
// by right shifting the value 24 bits
msg[0] = (byte) (msglen >> 24);

右移位32位的整数24个比特意味着您保留与在至少显著8个地方8最显著位,准备包成byte。在接下来的3行处理的下一个8位(右移16),那么下一个(右移8)等。

投射到一个byte简单地丢弃除了至少显著8位一切,所以(在最后一个移位的或缺乏),每个换档之后,我们把32个比特的四分之一。

所以,再一次:这只是实现了一个帧的大端长度前缀。接收代码将通过左移位和或-ING扭转这种,为了从第一个4个字节重建的长度。

© www.soinside.com 2019 - 2024. All rights reserved.