ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用字节掩码防止符号扩展

2019-06-13 14:51:28  阅读:465  来源: 互联网

标签:java bytearray networking endianness


我一直在阅读Java,第2版中的TCP / IP套接字.我希望能够更清楚地了解某些内容,但由于该书的网站没有论坛或任何内容,我想我会问这里.
在几个地方,本书使用字节掩码来避免符号扩展.这是一个例子:

private final static int BYTEMASK = 0xFF; //8 bits

public static long decodeIntBigEndian(byte[] val, int offset, int size) {
    long rtn = 0;
    for(int i = 0; i < size; i++) {
        rtn = (rtn << Byte.SIZE) | ((long) val[offset + i] & BYTEMASK);
    }
    return rtn;
}

所以这是我对正在发生的事情的猜测.如果我是对的,请告诉我.
二进制的BYTEMASK应该看起来像00000000 00000000 00000000 11111111.
为了简单起见,我们只说val字节数组只包含1个short,因此偏移量为0.所以让我们将字节数组设置为val [0] = 11111111,val [1] = 00001111.在i = 0时,rtn是所有0都是如此rtn<< Byte.SIZE只保持值相同.然后有(长)val [0]因为符号扩展而使其全部为1个8字节.但是当你使用& BYTEMASK,它将所有额外的1设置为0,将最后一个字节保留为1.然后你得到rtn | val [0]基本上翻转了rtn的最后一个字节中的任何1.对于i = 1,(rtn<<< Byte.SIZE)将最低有效字节推过并使所有0保持原位.然后(长)val [1]使用所有零加上00001111得到一个长的最低有效字节,这就是我们想要的.所以使用& BYTEMASK不会改变它.然后当rtn |使用val [1],它将rtn的最低有效字节翻转到所有1.最终返回值现在为rtn = 00000000 00000000 00000000 00000000 00000000 00000000 11111111 11111111.
所以,我希望这不会太久,这是可以理解的.我只是想知道我正在考虑这个问题的方式是否正确,而不仅仅是完全消除了逻辑.另外,令我困惑的一件事是BYTEMASK是0xFF.在二进制中,这将是11111111 11111111,所以如果它被隐式转换为int,那么它实际上是不是11111111 11111111 11111111 11111111由于符号扩展?如果是这样的话,那么对我来说BYTEMASK甚至不会有效.谢谢你的阅读.

解决方法:

除了最后一点,一切都是正确的:

0xFF已经是一个int(0x000000FF),因此它不会被符号扩展.一般来说,Java中的integer number literals是整数,除非它们以L或l结尾然后它们是长的.

标签:java,bytearray,networking,endianness
来源: https://codeday.me/bug/20190613/1233365.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有