按位取代模数运算符

我们知道例如两个权的模可以这样表示:

x % 2 inpower n == x & (2 inpower n - 1). 

例子:

 x % 2 == x & 1 x % 4 == x & 3 x % 8 == x & 7 

两个数字的一​​般无力呢?

我们说:

x%7 ==?

首先,这样说实际上是不准确的

 x % 2 == x & 1 

简单的反例: x = -1 。 在很多语言中,包括Java, -1 % 2 == -1 。 也就是说, %不一定是模的传统math定义。 例如,Java将其称为“余数运算符”。

关于按位优化,只有两个模幂可以“轻松”地按位算术完成。 一般来说,只有基数b的模数能够“容易地”用数字的基数b表示来完成。

以10为底,例如,对于非负NN mod 10^k只是取最小的k数字。

参考

  • JLS 15.17.3剩余操作员%
  • Wikipedia / Modulo Operation

这只适用于两个幂(通常只是正数),因为它们具有在其二进制表示中只有一个位设置为'1'的唯一属性。 由于没有其他类别的数字共享此属性,因此不能为大多数模数expression式创build按位和expression式。

只有一个简单的方法来find2 ^我的数字模数按位。

根据n%3,n%7等链接 ,有一种巧妙的方法来解决Mersenne案件。对于n%5,n%255和复合案例如n%6有特殊情况。

对于情况2 ^ i,(2,4,8,16 …)

 n % 2^i = n & (2^i - 1) 

更复杂的是很难解释。 只有在你非常好奇的时候才能阅读。

这是一个特殊的情况,因为计算机代表基数为2的数字。这是可以概括的:

(数字) 基数 %base x

等于(数字) 的最后x个数字。

存在有效algorithm存在的2的幂以外的模。

例如,如果x是32位无符号整数,那么x%3 = popcnt(x&0x55555555) – popcnt(x&0xaaaaaaaa)

 for x % 7 = ? x % 7 == (x+x/7) & 7 

在java中完美工作。

 int a = x % 7 ; int a = (x+x/7)&7; 

两个陈述都是一样的。

在二进制中不使用按位和( & )运算符,没有。 示意图:

假设有一个值k ,使得x & k == x % (k + 1) ,但是k!= 2 ^ n – 1 。 那么如果x == k ,则expression式x & k似乎“正常运行”,结果是k 。 现在考虑x == ki :如果k中有任何“0”位,那么有一些i大于0,那么ki在这些位置上只能用1位表示。 (例如,当100(4)已经被减去时,1011(11)必须变成0111(7),在这种情况下,当i = 4时000位变为100)。如果来自k的expression式的位必须从零到一个来表示ki ,那么它不能正确地计算x%(k + 1) ,在这种情况下它应该是ki ,但是没有办法按位布尔值并且在给定掩码的情况下产生该值。

使用bitwise_and,bitwise_or和bitwise_not,可以将任何位configuration修改为另一位configuration(即这些操作符集“function完整”)。 但是,对于像模数这样的操作来说,通用公式必然是相当复杂的,我甚至不打算重新创build它。

在这个特定的情况下(mod 7),我们仍然可以用位运算符replace%7:

 // Return X%7 for X >= 0. int mod7(int x) { while (x > 7) x = (x&7) + (x>>3); return (x == 7)?0:x; } 

它的工作原理是8%7 = 1。显然,这个代码可能比简单的x%7效率低,而且可读性也更差。

只有一个简单的方法来find2 ^我的数字模数按位。

根据n%3,n%7等链接,有一种巧妙的方法来解决Mersenne案件。对于n%5,n%255和复合案例如n%6有特殊情况。

对于情况2 ^ i,(2,4,8,16 …)

n%2 ^ i = n&(2 ^ i – 1)

更复杂的是很难解释。 只有在你非常好奇的时候才能阅读。

@ Murali任何这样的方法n%[(2 ^ 16)+1] = 65537。 我的意思是n%(2 ^ k)+1这是一个素数。