2012-04-17 32 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而不是添加。