java - Java 中签署扩展任意长度位模式的最有效方法是什么?

标签 java bit-manipulation sign-extension

比方说,我已经将三个 10 位有符号整数打包成一个 Java 整数。

我可以轻松提取 10 位:

int unpacked = packed & 0x3FF;
packed >>= 10;
etc ...

但现在我需要对最高位进行符号扩展(右边的第 9 位)。有没有一种快速的方法可以通过测试最高位和设置来做到这一点?

也许有更好的开箱方式,将标牌留在原处。

最佳答案

移位两次的替代方法是翻转符号然后减去它:

int unpacked = packed & 0x3FF;
int extended = (unpacked ^ 0x200) - 0x200;

如果符号未设置,翻转它设置它并减去它再次重置它。

如果符号已设置,翻转它会重置它,减去它会再次设置它,但也会一直借到顶部,一路设置所有位。

这有一些好处,

  • 代码不依赖于目标整数类型的大小,如果 unpackedextendedlong 那么同样的事情会起作用.
  • XOR 和减法可能会更便宜一些,例如在 Skylake 上,您每个周期可以执行 4 次这些基本运算,但只有 2 个类次。延迟是相同的,并且仅当代码中的可用 ILP 较高时它才重要。
  • 移位并不是真正的代数组合,但 XOR 和减法可以。例如,如果下一个操作是将一些常量添加到 extended,那么该添加和“减去符号”步骤可以合并到一个操作中。

关于java - Java 中签署扩展任意长度位模式的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54675321/

相关文章:

java - 使用 JLayeredPane 创建棋盘游戏布局

constants - 选择常量的值

c# - 开源媒体播放器

java - 如何使 Java 和 Objective-C (iPhone) 之间的 AES 加密相同?

c - C语言中位反转(从MSB-> LSB到LSB-> MSB)的高效算法

c - 解码 C 中的位

c++ - char 数组到 long 导致意外值

c++ - 带符号和无符号操作数的按位 '&'

c - 符号扩展的必要性是什么?

java - hibernate 只更新部分字段