我想在 Java 中将字节转换为 int。我想假设字节是无符号字节。假设如果
byte a = (byte)0xFF; int r = (some operation on byte a);
r 应该是 255 而不是十进制的 -1。
然后我想从 3 个字节创建 int 值。假设如果
byte b1 = (byte)0x0F; byte b2 = (byte)0xFF; byte b3 = (byte)0xFF; int r = (some operation in bytes b1, b2 and b3);
那么 r 应该是
0x000FFFFF
。在 int 值中,字节 b1 将放置在较高的第 3 位,而字节 b3 将放置在较低的第 1 位。此外,我的 b1 范围从 0x00 到 0x0F ,其他字节将从0x00
到0xFF
,假设字节的无符号性质。如果字节 b1 大于 0x0F,我将只提取最低 4 位。简而言之,我想从 3 个字节中提取 int,但只使用 3 个字节的 20 位。(来自 b2 和 b3 的总共 16 位,以及来自 b1 的 4 个最低位)。int r 必须为正,因为我们从 3 个字节创建并假设字节的无符号性质。
问问题
10088 次
5 回答
6
您必须小心此处的符号扩展 - 不幸的是,字节是用 Java 签名的(据我所知,这只会引起悲伤)。
所以你必须做一些掩蔽。
int r = (b3 & 0xFF) | ((b2 & 0xFF) << 8) | ((b1 & 0x0F) << 16);
于 2012-10-31T09:31:24.697 回答
3
我会假设你想要无符号字节值
int r = ((b1 & 0xF) << 16) | ((b2 & 0xFF) << 8) | (b3 & 0xFF);
每个字节都需要被屏蔽并移动到正确的位。
于 2012-10-31T09:34:27.400 回答
2
这对于移位运算符和二进制 AND 来说非常简单。您只想使用 b1 的低 4 位,这正是这样b1 & 0x0F
做的。剩下的就是将位移动到不同的位置
int r = ( (b1 & 0x0F) << 16) + ((b2 & 0xFF) << 8) + (b3 & 0xFF)
正如@harold 指出的那样编辑,前一种解决方案(在较低字节上没有 0xFF 掩码)会由于符号扩展而导致异常......
EDIT2天哪,在处理这些问题时,我总是被运算符优先级打脸……
推荐阅读:
于 2012-10-31T09:27:36.490 回答
1
这是一个“仅班次”版本:
int r = ((b1 << 28) >>> 12) | (b2 << 8) | b3;
左移 28 位会切断前 4 位,然后右移 12 位会将其返回到净左移 16 位。
我测试了这段代码,它可以工作:)
于 2012-10-31T09:26:41.497 回答
1
我比较了一些答案,因为我很好奇哪个答案最快。
似乎 Bohemian 的方法是最快的,但我无法解释为什么它在第一次运行时慢了 11%。
PS.:我没有检查答案的正确性。
这里的代码:
public class Test
{
public static void main(String[] args)
{
final int RUNS = 10;
final int TRIPLE = 3;
final int N = 100000000;
byte[] bytes = new byte[TRIPLE * 32768]; // 96 kB
Random r = new Random();
r.nextBytes(bytes);
List<ByteConvertTester> testers = Arrays.asList(new Harold(), new Bohemian(), new Ppeterka());
for (int i = 0; i < RUNS; i++)
{
System.out.println("RUN#" + i);
System.out.println("----------------------");
Integer compare = null;
for (ByteConvertTester tester : testers)
{
System.out.println(tester.getClass().getSimpleName());
long time = testAndMeasure(tester, bytes, N);
System.out.print("time (in ms): " + time);
if (compare != null) {
System.out.println(" SpeedUp%: " + (double) ((int) (10000 * (1.0d - (double) time / compare))) / 100);
} else {
compare = (int) time;
System.out.println();
}
}
System.out.println("----------------------");
}
}
private static long testAndMeasure(ByteConvertTester bct, byte[] bytes, int loops)
{
Calendar start = Calendar.getInstance();
int r;
for (int i = 0; i < loops; i += 3)
r = bct.test(bytes[i % bytes.length], bytes[(i + 1) % bytes.length], bytes[(i + 2) % bytes.length]);
Calendar end = Calendar.getInstance();
long time = (end.getTimeInMillis() - start.getTimeInMillis());
return time;
}
}
interface ByteConvertTester
{
public int test(byte msb, byte mid, byte lsb);
}
class Harold implements ByteConvertTester
{
@Override
public int test(byte msb, byte mid, byte lsb)
{
return (lsb & 0xFF) | ((mid & 0xFF) << 8) | ((msb & 0x0F) << 16);
}
}
class Bohemian implements ByteConvertTester
{
@Override
public int test(byte msb, byte mid, byte lsb)
{
return ((msb << 28) >>> 12) | (mid << 8) | lsb;
}
}
class Ppeterka implements ByteConvertTester
{
@Override
public int test(byte msb, byte mid, byte lsb)
{
return ((msb & 0x0F) << 16) + ((mid & 0xFF) << 8) + (lsb & 0xFF);
}
}
输出
RUN#0
----------------------
Harold
time (in ms): 489
Bohemian
time (in ms): 547 SpeedUp%: -11.86
Ppeterka
time (in ms): 479 SpeedUp%: 2.04
----------------------
RUN#1
----------------------
Harold
time (in ms): 531
Bohemian
time (in ms): 521 SpeedUp%: 1.88
Ppeterka
time (in ms): 537 SpeedUp%: -1.12
----------------------
RUN#2
----------------------
Harold
time (in ms): 531
Bohemian
time (in ms): 539 SpeedUp%: -1.5
Ppeterka
time (in ms): 532 SpeedUp%: -0.18
----------------------
RUN#3
----------------------
Harold
time (in ms): 529
Bohemian
time (in ms): 519 SpeedUp%: 1.89
Ppeterka
time (in ms): 531 SpeedUp%: -0.37
----------------------
RUN#4
----------------------
Harold
time (in ms): 527
Bohemian
time (in ms): 519 SpeedUp%: 1.51
Ppeterka
time (in ms): 530 SpeedUp%: -0.56
----------------------
RUN#5
----------------------
Harold
time (in ms): 528
Bohemian
time (in ms): 519 SpeedUp%: 1.7
Ppeterka
time (in ms): 532 SpeedUp%: -0.75
----------------------
RUN#6
----------------------
Harold
time (in ms): 529
Bohemian
time (in ms): 520 SpeedUp%: 1.7
Ppeterka
time (in ms): 532 SpeedUp%: -0.56
----------------------
RUN#7
----------------------
Harold
time (in ms): 529
Bohemian
time (in ms): 520 SpeedUp%: 1.7
Ppeterka
time (in ms): 533 SpeedUp%: -0.75
----------------------
RUN#8
----------------------
Harold
time (in ms): 530
Bohemian
time (in ms): 521 SpeedUp%: 1.69
Ppeterka
time (in ms): 532 SpeedUp%: -0.37
----------------------
RUN#9
----------------------
Harold
time (in ms): 529
Bohemian
time (in ms): 527 SpeedUp%: 0.37
Ppeterka
time (in ms): 530 SpeedUp%: -0.18
----------------------
于 2013-08-21T11:40:33.457 回答