【发布时间】:2011-02-28 21:24:36
【问题描述】:
我觉得这是一个相当微不足道的问题,但我很难过。在我的应用程序中,我用一对整数在查找表中键入内容。我认为将两个 int 连接成一个 long 并使用单个 long 作为键会更容易。来自 C 背景,我希望这样的事情能奏效:
int a, b;
long l = (long)a << 32 | b;
我在 Java 中复制这一点的尝试让我感到沮丧。特别是,因为没有无符号整数类型,我似乎无法避免 b 的自动符号扩展(a 左移,所以它无关紧要)。我试过使用b & 0x00000000FFFFFFFF,但令人惊讶的是没有效果。我也尝试了相当丑陋的(long)b << 32 >> 32,但它似乎被编译器优化了。
我希望严格使用带有原语的位操作来做到这一点,但我开始怀疑是否需要使用某种缓冲区对象来实现这一点。
【问题讨论】:
-
(long)b << 32 >> 32未优化。主要问题是 >> 是 sra 而 >>> 是 srl,这就是你想要的:(long)b << 32 >>> 32 -
表达式
b & 0x00000000FFFFFFFF必须有效,但为什么要用这些零来混淆它? -
@maaartinus:我对 Java 不够熟悉,不知道它在内部将十六进制文字存储为什么。我知道在 C 十六进制文字中是无符号的,但我担心 0xFFFFFFFF 会被符号扩展。事后看来,我只需要一个前导零就可以满足这种担忧。表达式仍然没有效果。
-
当然,
0xFFFFFFFF不会进行符号扩展。但是还有另一个问题,它只是一个int(我们都忘记了L后缀)并被提升为long- 当然是通过符号扩展。这就是为什么它不能工作。前导零没有任何变化,文字只是一个 int。看我的回答,肯定是对的,我用过很多次了。 -
你所做的就像C中的
(signed int) (b & 0xFFFFFFFF)。结果是一个有符号的int,并通过符号扩展提升为long。
标签: java