2

如何使用按位运算符更改 int 的符号?显然我们可以使用x*=-1or x/=-1。有没有最快的方法来做到这一点?

我做了一个小测试,如下所示。只是为了好奇...

public class ChangeSign {
    public static void main(String[] args) {
        int x = 198347;
        int LOOP = 1000000;
        int y;
        long start = System.nanoTime();
        for (int i = 0; i < LOOP; i++) {
            y = (~x) + 1;
        }
        long mid1 = System.nanoTime();
        for (int i = 0; i < LOOP; i++) {
            y = -x;
        }
        long mid2 = System.nanoTime();
        for (int i = 0; i < LOOP; i++) {
            y = x * -1;
        }
        long mid3 = System.nanoTime();
        for (int i = 0; i < LOOP; i++) {
            y = x / -1;
        }
        long end = System.nanoTime();
        System.out.println(mid1 - start);
        System.out.println(mid2 - mid1);
        System.out.println(mid3 - mid2);
        System.out.println(end - mid3);
    }
}

输出几乎类似于:

2200211
835772
1255797
4651923
4

3 回答 3

15

在几乎所有机器上,非浮点(例如 int 数学)加法/乘法和按位运算之间的速度差异都可以忽略不计。

没有一般的方法可以仅使用按位运算将 n 位有符号整数转换为其负等效项,因为求反运算看起来像x = (~x) + 1,它需要一次加法。但是,假设有符号整数是 32 位,您可能可以编写一个按位方程来进行此计算。注意:不要这样做。

否定一个数字的最常见、最易读的方法是x = -x.

于 2012-07-23T15:48:09.780 回答
8

Java 使用补码二表示。为了改变一个符号,这意味着你必须做一个按位否定(它相当于与 FFFF 的异或)并加 1。

x = ~x + 1;

我几乎可以肯定-x,如果有的话,比这更快。

于 2012-07-23T15:51:36.347 回答
1

使用高级语言的解决方案

像这样的问题在面试和竞争激烈的编程世界中很流行。

我来到这里研究更多不使用 - 或 + 运算符的否定数字解决方案。

为了这 :

  1. 使用 ~ 运算符补数
  2. 然后使用半加法器逻辑将步骤 1 中获得的数字加 1:

    int addNumbers(int x, int y) { 
                if(y==0) return x; // carry is 0 return 
                addNumbers(x^y,(x&y)<<1); }
    

这里 x^y 执行位相加, x&y 处理进位操作

于 2018-02-05T07:04:04.887 回答