for循环使每800万次迭代暂停 - 为什么?

时间:2016-10-04 20:06:40

标签: java

当我在Intellij上运行以下代码并输入1000000000000时,该过程每隔800万次循环持有一个时刻。

为什么会这样?为什么直到最后都没有流畅地运行?

import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("Please type a number");
        long n = in.nextLong();
        System.out.println("Thanks.");

        long count = 0;
        for (long i=0; i<=n; i++) {
            if ((n+i) == (n^i)) {
                count++;
                if (count % 1000000 == 0)
                System.out.println(count);
            }
        }
        System.out.println(count);
    }
}

1 个答案:

答案 0 :(得分:7)

条件

(n + i) == (n ^ i)

将在ni中没有重叠位时发生,因为在这种情况下,加法和异或基本相同。

例如,如果是n == 4i == 3,则为二进制n == 100i == 011,那么

 n + i == 100 + 011 == 111 == 7
 n ^ i == 100 ^ 011 == 111 == 7

我不相信这个条件也没有共同的位数;但这些都是“显而易见”的案例。

1000000000000的二进制形式是

1110100011010100101001010001000000000000

此处的最低有效位是第12位(从右边的零开始)。

2的12次幂是4096.因此,所有小于4096的数字与n没有共同点,因此您将计算所有数字0-4095。从那时起,您将只计算没有设置第12位的数字。因此,计算数字的速度将会减慢。

然后,你将达到第16个LSB。现在,您只计算未设置第12和第16位的数字。因此,计算数字的速度会慢一些。

等等。

这些“暂停”的唯一原因是外部for循环天真地遍历所有数字,直到n:它不会简单地跳到条件所适用的下一个数字。