我有这样的事情:
byte[0] = 0001 0100 0011 0100 (dec value: 5172)
byte[1] = 0000 0000 0111 1100 (dec value: 124)
byte[2] = 0000 0000 0000 0000 (dec value: 0)
byte[3] = 0000 0000 0000 0000 (dec value: 0)
我想将它们组合起来并在Java中创建一个long值。怎么做?
可以这样转换吗?
result = 0 +(0 x 2 ^ 16)+(0 x 2 ^ 16)+(124 x 2 ^ 32)+(5127 x 2 ^ 48)
即
result = byte [3] +(byte [2] x 2 ^ 16)+(byte [1] x 2 ^ 32)+(byte [0] x 2 ^ 48)
编辑:让我试着更好地解释一下。当我打开工具ModScan32并连接到我的设备时,我看到一些寄存器。在此工具中,有不同类型的选项如何显示数据。其中一个是将它们表示为二进制或十进制。当我选择二进制或十进制时,我得到的值与上面的例子中一样。当我用我的软件读取这些数据时,我得到十进制的完全相同(转换值)。现在我的问题是,是否有必要在4个16位寄存器中保存数据,并且我知道它们的十进制值是什么从寄存器组合这些值并获得实际值的正确方法?
答案 0 :(得分:1)
你的想法基本上没问题。有几点需要注意。
我相信你所处理的结果是0001010000110100000000000111110000000000000000000000000000000000
。
这是一种不起作用的尝试:
int[] registers = { 5172, 124, 0, 0 };
long result = registers[0] << 48 | registers[1] << 32 | registers[2] << 16 | registers[3];
System.out.println(Long.toBinaryString(result));
<< 48
表示向左移48位,这应该足够了,对吧? |
是一个按位逻辑或者,它将任一操作数中的1位填充到结果的相同位位置。如果您愿意,可以使用+
。
打印:
10100001101000000000001111100
我们只有结果的前32位,这还不够好。尝试阅读时,请注意Long.toBinaryString()
不包含前导零。想象一下这个数字前面有3个零。
但究竟是什么?最后32位去了哪里?即使他们都是零。问题是我们在int
s进行计算,它们是32位,而不是64位。编辑:我之前的解释在这一点上并不完全正确。事实是:在<<
上执行int
时,只考虑右操作数的最后5位,因此48是二进制的110000,只使用10000,所以移位是相同的为<< 16
。同样地,<< 32
与<< 0
相同,完全没有变化。因此,registers[0]
和[1]
最终处于错误的位置。当您知道它时,解决方案很简单:我们需要在进行计算之前转换为long
。现在使用右操作数的最后 6 位,因此48和32被理解为48和32:
long result = ((long) registers[0]) << 48 | ((long) registers[1]) << 32 | registers[2] << 16 | registers[3];
这次我们得到
1010000110100000000000111110000000000000000000000000000000000
再次,想象前面的3个零位,所有都是预期的。
还有一件事。假设你从寄存器中得到一个负值,例如:
int[] registers = { 5172, -124, 0, 0 };
现在正在运行的计算给了我们
1111111111111111111111111000010000000000000000000000000000000000
这次打印了64位,所以很容易看到开头有太多的1。它们来自int
-124的表示。解决方案是掩盖它们:
int[] registers = { 5172, -124, 0, 0 };
long result = ((long) registers[0] & 0xFFFF) << 48
| ((long) registers[1] & 0xFFFF) << 32
| (registers[2] & 0xFFFF) << 16
| (registers[3] & 0xFFFF);
System.out.println(Long.toBinaryString(result));
0xFFFF
为16 1位,&
为按位逻辑'和',仅在两个操作数均为1位的位置给出1位。现在-124被掩盖到1111111110000100
,因此结果是预期的:
1010000110100111111111000010000000000000000000000000000000000
应该这样做。