在论坛看到一个问题,花了点时间调查,自己随笔记录下来。
问题
ByteBuffer buf = ByteBuffer.allocate(32767);
buf.putLong(0,7477447194653012086L);
System.out.println("1 getLong = "+(buf.getLong(0)&0xffffffff));
System.out.println("2 getLong = "+(buf.getLong(0)&0xffffffffL));
1 getLong = 7477447194653012086
2 getLong = 940093558
解答
我来尝试解答一下。
楼主排版太难看了,我换成自己的排版。
ByteBuffer buf = ByteBuffer.allocate(32767);
buf.putLong(0,7477447194653012086L);
System.out.println("1 getLong = "+(buf.getLong(0))); // A
System.out.println("2 getLong = "+(buf.getLong(0)&0xffffffff)); // B
System.out.println("3 getLong = "+(buf.getLong(0)&0xffffffffL)); // C
1 getLong = 7477447194653012086
2 getLong = 7477447194653012086
3 getLong = 940093558
我多加了A。
对于BC之间的区别,我们单独看 后半部分。
0xffffffff // 对于数值类型,java中默认为int型,而且凑巧这个字段有是32个1,即int型中的-1,所以被解释成-1。(java中以补码的方式进行值的运算的,32个1的int型补码是-1)
0xffffffffL // long型,没达到最大位数。二进制为32个1,值就为2的32次方。(因为没到最大位,32个1的long型补码就是2的32次方)
当long型数值 &上述两个值时,
long & 0xffffffff // 后面的-1自动提升为long型,二进制为64个1,所以值不变。
long & 0xffffffffL // 后面的2的32次方为32个1,所以前面的long型会被截取后面的32位,即数值减小了。
例如上述 二进制为
110011111000101001110101001101100111000000010001011000001110110
截取后32位如下,数值就为940093558
00111000000010001011000001110110
之所以加上上述例子A,就是A和B算出的值时一样的(没有严格测试,基本测试及自己猜想)。
所以我感觉楼主可能 byte型转long型需要加 &0xff 这样的说法误导了。
正常byte型转数值,确实需要&0xff运算的。但是这里使用了工具类 ByteBuffer,我猜测在getLong中已经有了这样的操作,不然工具类就有潜在的bug了。
(工具类里面源码打开看了,没看懂。。。所以只能猜测)
这样应该解决楼主的问题了吧! 分分拿来