了解 java 代码 - 检查整数是否为 2 的幂

Understanding java code - Check if an integer is power of 2

我在 Leetcode.com

看到了这个高效编写的代码
public static boolean isPowerOfTwo(int n) {
            return n>0 && ((n&(n-1))==0);
        }

这工作得非常好,但我无法弄清楚代码中单个“&”的工作原理。 有人可以努力解释代码的工作原理吗?

根据相同的逻辑,确定整数是否为 3 的幂的代码是什么?

Java中的&是位与运算符。它采用两个整数并对每个位执行与操作,生成一个 int,其中当且仅当该位在两个操作数中都为“1”时,每个位都设置为“1”。该代码使用这样的理解,即二进制中任何 2 的幂都是一个“1”,后跟一些“0”。这意味着减一将改变数字的所有位。对于任何非 2 的幂,在第一个之后至少会有一个非零数字,因此第一个数字将保持不变。由于对两个不同的值执行 AND 总是会产生“0”,因此当且仅当该数字是 2 的幂时,将原始数字与其本身减一进行 AND 运算才会产生 0。因为这是专门针对二进制数的技巧,所以它不适用于查找其他基数的幂。

要了解此函数的工作原理,您需要了解二进制数的表示方式。如果您不这样做,我建议您阅读教程,例如 Learn Binary (the easy way).

假设我们有一个数字 8,我们想知道它是否是 2 的幂。我们先把它转换成二进制:1000。现在让我们看看8-1 = 7的二进制形式:0111& 运算符用于二进制 AND。当我们将 AND 运算符应用于 87 时,我们得到:

 1000
 0111
&----
=0000

每个 2 的幂整数都是 1 后跟非负数的零。当您从该数字中减去 1 时,您将始终得到一个 0 后跟一系列 1。由于对这两个数字应用 AND 运算将始终得到 0,因此您始终可以验证它是否是 2 的幂。如果数字不是 2 的幂,当您从中减去 1 时,它不会反转其所有数字,并且 AND 测试将产生正数(失败)。

单个 & 是按位 'and' 运算符(与作用于布尔值的 && 相反)。

因此,当您对两个整数使用 & 时,结果是它们二进制表示的逻辑 'and'。

此代码有效,因为 2 的任何次方都是 1 后跟二进制中的一些 0(例如,4 是 100,8 是 1000,等等)。任何 2 的次方,减去 1,都只会是全 1(例如 3 是 11,7 是 111)。 所以,如果你取 2 的幂,然后按位取它本身负 1,你应该只有 0。但是,除了 2 的幂以外的任何东西都会给出非零答案。

示例:
1000 = 8
0111 = 7 (8-1),'&'ing 这些给出
0000 = 0

但是,如果你有类似 6(不是 2 的幂)的东西:
110 = 6
101 = 5 (6-1),'&'ing 这些给出
100 = 4(不等于 0,因此代码会 return 错误)。

我希望说清楚!

它是一个按位运算符:

如果我们取 2 的指数 3 等于 8, 例如 2³ = 2×2×2 = 8

现在要计算 8 是否是 2 的幂,它是这样工作的:

n&(n-1) --> 8 和 (8-1) --> 1000 和 0111 = 0000 因此它满足条件 --> (n&(n-1))==0

单个“&”执行按位与运算,这意味着在 A & B 的结果中,A 和 B 是整数,只有那些位将设置为 1,其中 A 和 B 都为 1。

例如,让我们看一个数字 16:

16 & (16 - 1) =

00010000 &
00001111 =
00000000

这适用于 2 的幂,因为任何 2 的幂减 1 都会设置所有低位,或者换句话说,n 位可以表示 n 个不同的值,包括零,因此 (2^n)-1 是最高的全部设置后可以用n位表示的值。

希望对您有所帮助。

三的幂有点问题,因为我们的计算机不使用三进制数。基本上,三的幂是任何三元数,只有一个数字不同于零,并且该数字是“1”,就像在任何其他数字系统中一样。 从我的脑海里,我想不出比重复做模 3 直到你得到一个作为除法结果(在这种情况下你有 3 的幂)或非零模结果(这将意味着它不是三的幂)。 也许这也有帮助:http://www.tutorialspoint.com/computer_logical_organization/number_system_conversion.htm