繁体   English   中英

Java 中对任意长度的位模式进行符号扩展的最有效方法是什么?

[英]What is the most efficient way in Java to sign extend an arbitrary length pattern of bits?

例如,假设我已将三个 10 位有符号整数打包成一个 Java 整数。

我可以轻松提取 10 位:

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

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

也许有一种更好的打开包装方式可以将标志留在原处。

int signed = (packed << (32 - 10)) >> (32 - 10);

因为>>>是无符号右移,而>>是有符号右移。

(我仍然有“错误”,谢谢@rghome)

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

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

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

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

这有一些优点,

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM