【问题标题】:Byte[] to Long Using Bit OperationsByte[] 到 Long 使用位操作
【发布时间】:2014-03-21 17:28:26
【问题描述】:

我有一个byte[],它将字节保存为很长。我想使用位操作将其转换为 long 。我尝试了以下方法:

byte[] b = new byte[]{127, 127};
long result = 0;
for (int i = 0; i < b.length; i++) {
    result <<= 8; // this is the same as l = l << 8;
    result |= (short)b[i] & 0xFF;
}

这适用于正字节。但是字节可以是正数也可以是负数,所以它不起作用。

举个例子:

byte[] b = new byte[]{-1, 2};
long result = 0;
for (int i = 0; i < b.length; i++) {
    result <<= 8; // this is the same as l = l << 8;
    result |= (short)b[i] & 0xFF;
}
System.out.println(result);
System.out.println(new BigInteger(b).longValue());

打印 65282 和 -254。我相信BigInteger 的结果是正确的,但由于内存问题我不想使用它。

知道我做错了什么吗?

【问题讨论】:

  • 你不能改用ByteBuffer吗?
  • A long 是 8 个字节,而不是 2 个。如果将负字节左移 56 位,则生成的 long 将为负数。您在测试中看不到它,因为您只左移了 8 位。
  • 你真的想如何处理字节?在这种情况下,我 expect 他们被当作 8 位 unsigned 整数来处理,在这种情况下 65282 对我来说是有意义的......

标签: java byte bit-manipulation long-integer


【解决方案1】:

这取决于您的应用程序需要什么。

byte[] b = new byte[] { -1, 2 }

另一种看待它的方式是十六进制数 0xFF02。这是否代表有符号的 64 位值(65282)?还是带符号的 16 位值 (-254)?还是一个无符号的 16 位值(又是 65282)?还是一个无符号的 64 位值(还是 65282)?

您的代码将其视为带符号的 64 位值。 BigInteger 将其视为带符号的 16 位值。 BigInteger 有另一个构造函数将字节数组视为幅度,使用另一个参数作为符号:new BigInteger(+1, b) 将导致 65282。

【讨论】:

  • 你是绝对正确的。我只使用两个字节进行测试,但如果我使用 8 个字节,它就可以工作。对我来说非常愚蠢的时刻:P。
  • 对于 little-endian 表示也可以是 767。
猜你喜欢
  • 1970-01-01
  • 2016-11-08
  • 2023-04-07
  • 2020-06-18
  • 1970-01-01
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 2021-05-17
相关资源
最近更新 更多