web-dev-qa-db-ja.com

リトルエンディアンからビッグエンディアンへの変換

すべて、

私はコーディングの問題をオンラインで実践しています。現在、私は問題文 Problems に取り組んでいます。ビッグエンディアン<->リトルエンディアンに変換する必要があります。しかし、以下の例を考慮して、手順を書き留めることはできません。

123456789 converts to 365779719

私が考えている論理は:
1>整数値を取得します(Windows x86を使用しているため、入力はリトルエンディアンです)
2>同じの16進数表現を生成します。
3>表現を逆にしてビッグエンディアン整数値を生成します

しかし、私は明らかに何かが不足しています。

どなたかご案内頂けますか? Java 1.5でコーディングしています

17
name_masked

エンディアンスワップは、整数を表すバイトを処理することを理解する必要があります。したがって、4バイトの数値27は0x0000001Bのようになります。その数値を変換するには、0x1B000000に移動する必要があります。例では、123456789の16進表現は0x075BCD15であり、0x15CD5B07または10進形式365779719に移動する必要があります。

Stackerが投稿した関数は、これらのバイトをビットシフトして移動します。より具体的には、ステートメントi&0xffiからlowestバイトを取得し、<< 24はそれを上に移動します24ビットなので、位置1-8から25-32まで。それでは、式の各部分について説明します。

コード例については、 this ユーティリティをご覧ください。

21
Bryan

ソフトウェアの作成の大部分は既存のソリューションを再利用することであるため、まず最初に、常に言語/ライブラリのドキュメントを調べる必要があります。

_reverse = Integer.reverseBytes(x);
_

この関数の効率はわかりませんが、多数の数値を切り替えるには、ByteBufferが適切なパフォーマンスを提供する必要があります。

_import Java.nio.ByteBuffer;
import Java.nio.ByteOrder;

...

int[] myArray = aFountOfIntegers();
ByteBuffer buffer = ByteBuffer.allocate(myArray.length*Integer.BYTES);

buffer.order(ByteOrder.LITTLE_ENDIAN);
for (int x:myArray) buffer.putInt(x);

buffer.order(ByteOrder.BIG_ENDIAN);
buffer.rewind();
int i=0;
for (int x:myArray) myArray[i++] = buffer.getInt(x);
_

コメントで指摘したように、ByteBuffer.putInt()はオプションのメソッドであり、すべてのJava実装で使用できない場合があります。

DIYのアプローチ

スタッカーの答えはかなりきちんとしていますが、それを改善することは可能です。

_   reversed = (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
_

ビットマスクを調整することで、括弧を取り除くことができます。たとえば、_(a & 0xFF)<<8_は_a<<8 & 0xFF00_と同等です。とにかく、右端の括弧は必要ありませんでした。

_   reversed = i<<24 & 0xff000000 | i<<8 & 0xff0000 | i>>8 & 0xff00 | i>>24 & 0xff;
_

左シフトはゼロビットでシフトするため、最初のマスクは冗長です。ゼロビットのみシフトする論理シフト演算子を使用して、右端のマスクを取り除くことができます。

_   reversed = i<<24 | i>>8 & 0xff00 | i<<8 & 0xff0000 | i>>>24;
_

演算子の優先順位 ここで、シフト演算子の詳細は Java言語仕様 にあります

30
Wolfram Schmied

これをチェック

int little2big(int i) {
    return (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
}
25
stacker

Javaプリミティブラッパークラスは、1.5からreverseBytesメソッドを使用してバイト反転をサポートしています。

Short.reverseBytes(short i)
Integer.reverseBytes(int i)
Long.reverseBytes(long i)

2018年にこの回答を探している人のための貢献です。

11
glf4k

これも役立つと思います:

int littleToBig(int i)
{
    int b0,b1,b2,b3;

    b0 = (i&0x000000ff)>>0;
    b1 = (i&0x0000ff00)>>8;
    b2 = (i&0x00ff0000)>>16;
    b3 = (i&0xff000000)>>24;

    return ((b0<<24)|(b1<<16)|(b2<<8)|(b3<<0));
}
1
Venu

次のメソッドは、バイト値のビットの順序を逆にします。

public static byte reverseBitOrder(byte b) {
    int converted = 0x00;
    converted ^= (b & 0b1000_0000) >> 7;
    converted ^= (b & 0b0100_0000) >> 5;
    converted ^= (b & 0b0010_0000) >> 3;
    converted ^= (b & 0b0001_0000) >> 1;
    converted ^= (b & 0b0000_1000) << 1;
    converted ^= (b & 0b0000_0100) << 3;
    converted ^= (b & 0b0000_0010) << 5;
    converted ^= (b & 0b0000_0001) << 7;

    return (byte) (converted & 0xFF);
}
0
Lukas Z.