4

私は以前に C# で書いたコードを Java で書いています (私は Java にはかなり慣れていません)。C# のコードと例を次に示します。

ushort number = 0xAABB; // 43707
byte[] data = new byte[2];
EndianBitConverter.Big.CopyBytes(number, data, 0); // value[0] = 170, value[1] = 187

デフォルトでリトル エンディアンに設定されているため、.NET でカスタム ビット コンバーターを使用しています。とにかく、Java について私が理解していることから、byte[] と同じ結果を使用したい場合、値 (170 と 187) が 128 (Byte.MAX_VALUE + 1)、つまり (42, 59) だけ小さくなると予想する必要があります。 - .net と Java ではバイト型の範囲が異なるため。上記のロジックを模倣するためにJavaで書いたものを次に示します。

public class Ushort {
    private int value = 0;

    public Ushort(int i) {
        value = i - (Short.MAX_VALUE + 1);
    }

    public int get() {
        return value;
    }

    public byte[] getBytes() {
        byte[] result = new byte[]{
                (byte) (value >>> 24),
                (byte) (value >>> 16),
                (byte) (value >>> 8),
                (byte) value};

        return new byte[]{result[2], result[3]};
    }
}

ただし、上記のコードを呼び出すと

new Ushort(0xAABB).getBytes()

結果は [42, 59] ではなく [42, -69] です。最後のバイトは、本来よりも 128 小さくなっています。これを適切に行う方法と、私のロジックが正しいかどうかについて、いくつかの指針が本当に必要です。uint や ulong などについても同様に行う必要があるため、これを正しく理解する必要があります。

4

2 に答える 2

5

あなたが行おうとしている変換の背後にある理由を理解していないか、それらが間違って考えられているため、実装にエラーがあるかどうかについて意見を述べることができません。

Java の型は C#byteの型とまったく同じであるsbyteため、C# を使用してすべてのテストを行いsbyte、Java に移植する前に正しく動作することを確認できます。

(byte)0xaa = 170
(sbyte)0xaa = -86
(byte)0xbb = 187
(sbyte)0xbb = -69

したがって、Java では、バイト配列は { -86, -69 } である必要があります。

于 2011-11-29T16:27:14.123 に答える
3

私はそれをテストしませんでしたが、私がすることはこれです:

public class Ushort {
    private int value = 0;

    public Ushort(int i) { // Changed
        if (i > 0xFFFF || i < -(0xFFFF))
            throws IllegalArgumentException("integer overflow")
        value = i;
    }

    public int get() {
        return value;
    }

    public byte[] getBytes() { // Changed! (Use & 0xFF)
        return new byte[]{
                (byte) ((value >>> 8) & 0xFF),
                (byte) (value & 0xFF)};

    }
}
于 2011-11-29T16:27:48.433 に答える