java - 在 Java 中否定整数

标签 java bitwise-operators primitive

我在相当多的 Java 代码中看到过类似这样的代码:

int blah = ~someFunc() + 1;

代替

int blah = -1 * someFunc();

这里的输出有什么真正的区别吗? javac 是否认识到这两种情况之间的区别?看起来编译器应该能够将这两行转换为相同的字节码。

编辑:这不是关于位翻转如何工作的问题,而是关于为什么实现者可能选择某种操作方法的问题。

Edit2:我在一个简单的测试中执行了 javap -c,这里是一些 JVM 字节码:

int one = -1 * someFunc();
0: iconst_m1     
1: invokestatic  #2                  // Method someFunc:()I
4: imul          
5: istore_1      

int two = ~someFunc() + 1;
6: invokestatic  #2                  // Method someFunc:()I
9: iconst_m1     
10: ixor          
11: iconst_1      
12: iadd          
13: istore_2    

因此还有 3 条用于位翻转的 java 指令(即 iconst_m1, ixor)加一条,但是如何将其转换为机器周期可能是非常特定于体系结构的。

最佳答案

严格来说指令成本,第一种方法确实更快(在某些处理器上): 例如,访问 http://www.agner.org/optimize/instruction_tables.pdf并比较运营成本:

IMUL r32 = 3 ops
ADD = 1 op
NOT = 1 op

因此,您可能会节省一个操作。另一方面,每个函数调用都需要您将变量放入寄存器堆栈并从中检索它们,这会增加额外的成本。

关于java - 在 Java 中否定整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31030854/

相关文章:

java - @Transactional 回滚问题

java - Netbeans 找不到外部 jar

c++ - 而在std::cout , what does it work for?之前使用左移运算符(<<)

c - 为什么将整数左移 24 位会产生错误的结果?

c# - int (Int32) 是否被视为 .NET 中的对象或原语(不是 int?)?

c++ - 自定义字节大小?

java - 使用rest模板java获取Auth0管理 token

swift - 为什么负数的计算中会包含 "sign bit"?

c# - 如何修复: Object must be an array of primitives. 参数名称:src

java - 关于将单例的构造函数说明符从 private 更改为 protected