1

私は、Java 1.4 で使用するための非常に必要最小限の ByteBuffer に取り組んでいます。基本的に put/getInt() put/getLong() の実装が不十分な小さなスケルトンがあります。私の問題は、putInt と getInt が機能しているのに、getLong() (そうだと思います) が機能していないことです。

4 番目のバイトを読み込んで long にシフトすると、オーバーフローします。しかし、私の変数はすべて長いので、オーバーフローすることはありません。

コードは次のとおりです (これはほんの始まりにすぎないことに注意してください)。

public class ByteBuffer {

    private byte[] buffer;
    private int first = 0;
    private int last = 0;
    private int size;
    private int elements;

    public ByteBuffer(int size) {
        this.size = size;
        buffer = new byte[size];
    }

    public void putInt(int theInt) {
        for (int i = 0; i < 4; i++) {
            put((byte) (theInt >>> (8 * i)));
        }
    }

    public int getInt() {
        int theInt = 0;
        for (int i = 0; i < 4; i++) {
            theInt |= (0xFF & get()) << (8 * i);
        }
        return theInt;
    }

    public void putLong(long theLong) {
        for (int i = 0; i < 8; i++) {
            put((byte) (theLong >>> (8 * i)));
        }
    }

    public long getLong() {
        long theLong = 0L;
        for (int i = 0; i < 8; i++) {
            theLong |= (long) ((0xFF & get()) << (8 * i));
        }
        return theLong;
    }

    public void put(byte theByte) {
        buffer[last++] = theByte;
        if (last == size) {
            last = 0;
        }
        elements++;
    }

    public byte get() {
        byte theByte = buffer[first++];
        if (first == size) {
            first = 0;
        }
        elements--;
        return theByte;
    }

    public byte[] array() {
        return (byte[]) buffer.clone();
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        ByteBuffer buff = new ByteBuffer(512);

        buff.putLong(9223372036854775807L);
        buff.putLong(-9223372036854775808L);

        System.out.println(9223372036854775807L);
        System.out.println(-9223372036854775808L);

        long l1 = buff.getLong();
        long l2 = buff.getLong();
        System.out.println(l1);
        System.out.println(l2);
    }

}
4

2 に答える 2

6

getLong メソッドでは、32 ビット以上シフトする前に、(0xFF & get()) を long にキャストする必要があります。int リテラル (0xFF) の代わりに long リテラル (0xFFL) を使用することもできます。

これは、「int && byte」操作 (0xFF & get()) の結果の型が int であるためです。ビット シフト操作の仕様は、"a << b" は、a が int の場合は実際に "b modulo 32" ビットをシフトし、a が long の場合は "b modulo 64" ビットをシフトします。

于 2012-11-28T13:05:32.123 に答える
2
theLong |= (long) ((0xFF & get()) << (8 * i));

1バイトから伝搬されるint値をシフトし、32ビット位置のみをシフトできます。

解決:

theLong |= ((long) (0xFF & get())) << (8 * i);
于 2012-11-28T13:26:31.363 に答える