2012-04-17 89 views
0

以下代码尝试在一个字节数组中存储4个long。随机访问是重要的,这就是为什么我没有使用字节流进行此操作。为什么下面的代码不工作?你能想出一个更有效的方法来做到这一点吗?Java按位运算符未按预期工作

public static void storeLong(long value, byte[] buf, int offset) { 
    buf[offset] = (byte) (value & 0xFFL); 
    buf[offset+1] = (byte) ((value >>> 8) & 0xFFL); 
    buf[offset+2] = (byte) ((value >>> 16) & 0xFFL); 
    buf[offset+3] = (byte) ((value >>> 24) & 0xFFL); 
    buf[offset+4] = (byte) ((value >>> 32) & 0xFFL); 
    buf[offset+5] = (byte) ((value >>> 40) & 0xFFL); 
    buf[offset+6] = (byte) ((value >>> 48) & 0xFFL); 
    buf[offset+7] = (byte) ((value >>> 56) & 0xFFL); 
} 

public static long retrieveLong(byte[] buf, int offset) { 
    return ((long)buf[offset]) 
     + (((long)buf[offset+1])<<8) 
     + (((long)buf[offset+2])<<16) 
     + (((long)buf[offset+3])<<24) 
     + (((long)buf[offset+4])<<32) 
     + (((long)buf[offset+5])<<40) 
     + (((long)buf[offset+6])<<48) 
     + (((long)buf[offset+7])<<56); 
} 


public static void main(String[] args) { 
    byte[] buf = new byte[32]; 
    storeLong(-1, buf, 0); 
    storeLong(1, buf, 8); 
    storeLong(Long.MAX_VALUE, buf, 16); 
    storeLong(Long.MIN_VALUE, buf, 24); 

    System.out.println(-1); 
    System.out.println(1); 
    System.out.println(Long.MAX_VALUE); 
    System.out.println(Long.MIN_VALUE); 

    System.out.println(retrieveLong(buf, 0)); 
    System.out.println(retrieveLong(buf, 8)); 
    System.out.println(retrieveLong(buf, 16)); 
    System.out.println(retrieveLong(buf, 24)); 

} 

我从上面得到的输出如下。你可以看到前四个号码不匹配,未来4:

-1 
1 
9223372036854775807 
-9223372036854775808 

-72340172838076673 
1 
9151031864016699135 
-9223372036854775808 
+3

什么是行不通的?你会得到什么结果,你期望得到什么结果? – 2012-04-17 19:19:52

+0

那么你应该可以像这样使用循环:'buf [offset + 2] =(byte)((value >>> 16)&0xFFL);' – Coffee 2012-04-17 19:20:01

+0

你得到的输出是什么? – 2012-04-17 19:20:17

回答

2

我做了一些测试,发现使用java.nio.LongBuffer中的是快两倍,我的代码

ByteBuffer bb = ByteBuffer.allocate(4*8); 
    LongBuffer lb = bb.asLongBuffer(); 

    lb.put(0, -1); 
    lb.put(1, 1); 
    lb.put(2, Long.MAX_VALUE); 
    lb.put(3, Long.MIN_VALUE); 

    System.out.println(lb.get(0)); 
    System.out.println(lb.get(1)); 
    System.out.println(lb.get(2)); 
    System.out.println(lb.get(3)); 

然后我就可以使用bb.array得到字节数组()

谢谢以Louis Wasserman和Rene Jeschke的努力

8

不要使用+byte签署:

public static long retrieveLong(byte[] buf, int offset) { 
    return ((long)buf[offset]  & 255) 
     | (((long)buf[offset + 1] & 255) << 8) 
     | (((long)buf[offset + 2] & 255) << 16) 
     | (((long)buf[offset + 3] & 255) << 24) 
     | (((long)buf[offset + 4] & 255) << 32) 
     | (((long)buf[offset + 5] & 255) << 40) 
     | (((long)buf[offset + 6] & 255) << 48) 
     | (((long)buf[offset + 7] & 255) << 56); 
} 

你必须and 255每个字节,使其“无符号”。你也必须使用二进制or而不是添加。