【问题标题】:Odd result when bit shifting in Java在 Java 中移位时出现奇怪的结果
【发布时间】:2014-04-16 16:19:14
【问题描述】:

我试图隔离两个相邻的字节并添加它们,但似乎有时会出现一个额外的位,我不知道如何摆脱它。它正在抛出答案。 代码是:

(acc & 0x00000000ff000000L) + ((acc << 8) & 0x00000000ff000000L);

我得到了诸如

之类的结果
0x0000000147000000

应该是什么时候

0x0000000047000000

我怎样才能摆脱 1?

编辑:acc 很长。我尝试添加第 5 和第 6 字节,然后该值将在第 5 字节位置进入新的 l​​ong。

【问题讨论】:

  • 你能澄清一下吗? acc 的值和类型是什么? 0000000147000000 是什么?你的意思是十进制值147000000
  • Java 中的一切都是用 int 完成的。如果你位移一个字节,你就是位移一个 int。您是否考虑到这一点?
  • 最好有一个可重现的例子。
  • 该代码确实将第 5 和第 6 个字节相加(如果从 msb 计算),显然结果大于 255。您可以输入另一个 AND

标签: java byte bit-manipulation


【解决方案1】:

你需要在最后屏蔽你想要的位,因为加法可能带有位:

((acc & 0x00000000ff000000L) + ((acc << 8) & 0x00000000ff000000L)) & 0x00000000ff000000L;

我认为如果你把它分解一下可能会更清楚:

acc&=0x00000000FFFF000000L; // isolate bytes 5 and 4
acc+=(acc<<8);              // add the two bytes (we'll strip bytes 6 & 4 next)
acc&=0x00000000FF00000000L; // reduce to byte 5 only

恰好也少了一个位运算。

【讨论】:

  • 好的。我试过了|而不是你之前的 + 答案,它没有用。
  • 是的,那是因为我看错了你的意图并得出了错误的结论。
【解决方案2】:

如果我理解正确,您想获取第 5 和第 6 字节的值,将它们加在一起,然后将它们存储在新的 long 中,其中仅包含第 5 字节中的总和。这将像这样完成:

long 5thByte = acc & 0xff00000000 >>> 32;
long 6thByte = acc & 0xff0000000000 >>> 40;
long sum = 5thByte + 6thByte;
long longWithNewByte = sum << 32;

如果总和高于 255,这当然会结转到第 6 个字节。要消除该结转,您可以使用另一个掩码。

long longWithNewByte &= 0xff00000000;

【讨论】:

  • 所有的按位&amp; 操作都是错误的; 0xF 屏蔽 nibble(4 位),而不是 byte(8 位)。消除同样的错误理解,2x 的转变是错误的。即使正确计算了它们的位,代码仍然会过度移位 1 个字节(要将字节 2 移动到字节 1 的位置,您需要移动 8,而不是 16)。
  • 你说得对。感谢您指出了这一点。我编辑了我的答案,现在我认为它是正确的。
猜你喜欢
  • 1970-01-01
  • 2012-07-23
  • 2023-01-27
  • 1970-01-01
  • 2015-01-18
  • 1970-01-01
  • 2018-06-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多