将Little Endian转换为Big Endian

nam*_*ked 17 java portability

所有,

我一直在网上练习编码问题.目前,我的工作问题说明问题,我们需要大端转换< - >小尾数.但考虑到给出的例子,我无法记下步骤:

123456789 converts to 365779719
Run Code Online (Sandbox Code Playgroud)

我正在考虑的逻辑是:
1>获取整数值(因为我在Windows x86上,输入是Little endian)
2>生成相同的十六进制表示.
3>反转表示并生成大端整数值

但我显然在这里遗漏了一些东西.

任何人都可以指导我.我在Java 1.5中编码

Wol*_*ied 29

由于编写软件的很大一部分是重用现有的解决方案,所以首先应该始终查看语言/库的文档.

reverse = Integer.reverseBytes(x);
Run Code Online (Sandbox Code Playgroud)

我不知道这个功能的效率如何,但是为了切换大量的数字,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);
Run Code Online (Sandbox Code Playgroud)

正如eversor在注释中指出的那样,ByteBuffer.putInt()是一种可选方法,可能并非在所有Java实现中都可用.

DIY方法

Stacker的答案非常简洁,但有可能对其进行改进.

   reversed = (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
Run Code Online (Sandbox Code Playgroud)

我们可以通过调整位掩码来摆脱括号.E. g.,(a & 0xFF)<<8相当于a<<8 & 0xFF00.无论如何,最右边的括号不是必需的.

   reversed = i<<24 & 0xff000000 | i<<8 & 0xff0000 | i>>8 & 0xff00 | i>>24 & 0xff;
Run Code Online (Sandbox Code Playgroud)

由于左移位为零位,因此第一个掩码是冗余的.我们可以通过使用逻辑移位运算符来消除最右边的掩码,该运算符仅移位零位.

   reversed = i<<24 | i>>8 & 0xff00 | i<<8 & 0xff0000 | i>>>24;
Run Code Online (Sandbox Code Playgroud)

这里的运算符优先级,移位运算符的粗略细节在Java语言规范中


sta*_*ker 25

看一下这个

int little2big(int i) {
    return (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
}
Run Code Online (Sandbox Code Playgroud)

  • 另外,我会使用| 而不是+,假设使用bitwise或者可能更快,并且编译器/运行时更容易优化. (5认同)
  • 也许更清楚:`return((i << 24)+((i << 8)&0x00FF0000))+((i >> 8)&0x0000FF00))+(i >>> 24))` (4认同)
  • 此外,这将切换到大*和*大到小,所以方法名称不够广泛.也许是swapEndian? (2认同)

Bry*_*yan 21

你需要意识到的是,endian交换处理代表整数的字节.所以4字节数字27看起来像0x0000001B.要转换该数字,需要转到0x1B000000...以您的示例为例,123456789的十六进制表示0x075BCD15需要转到0x15CD5B07或以十进制形式365779719.

Stacker发布的函数是通过位移来移动这些字节; 更具体地说,该语句i&0xff最低字节i,<< 24然后将其向上移动24位,因此从位置1-8到25-32.所以通过表达的每个部分.

例如代码,看看这个实用程序.


glf*_*f4k 9

自1.5使用reverseBytes方法以来,Java原始包装类支持字节反转.

Short.reverseBytes(short i)
Integer.reverseBytes(int i)
Long.reverseBytes(long i)
Run Code Online (Sandbox Code Playgroud)

对于那些在2018年寻找这个答案的人来说,这只是一个贡献.