举例来说,我已经将三个10位带符号整数打包为Java整数。
我可以轻松提取10位:
int unpacked = packed & 0x3FF;
packed >>= 10;
etc ...
但是现在我需要对最高位(右边的第9位)进行符号扩展。有没有一种快速的方法可以通过测试最高位和设置来做到这一点?
也许有一种更好的拆箱方法可以将标牌留在原地。
最佳答案
移位两次的另一种方法是翻转符号,然后减去它:
int unpacked = packed & 0x3FF;
int extended = (unpacked ^ 0x200) - 0x200;
如果未设置符号,则将其翻转将其设置,然后将其减去则将其重置。
如果设置了符号,则将其翻转会重置它,将其减去会再次设置它,但也会一直借用到顶部,并沿途设置所有位。
这有一些优点,
该代码不依赖于目标整数类型的大小,如果
unpacked
和extended
为long
,则相同的内容将起作用。XOR和减法可能会便宜一些,例如,在Skylake上,每个周期可以执行4个这些基本操作,但只有2个班次。延迟是相同的,并且仅在代码中的可用ILP高时才重要。
移位并不是真正的代数结合,但是XOR和减法可以结合。例如,如果下一个操作是向
extended
添加一些常量,则可以将该加法和“减去符号”步骤合并为一个操作。