我发现一些示例源代码,其中作者似乎使用按位运算符&
而不是%
运算符。但是,当我尝试x & 4
时,它不会产生与x % 5
相同的值。为什么(x&3)与(x mod 4)相同?
4
A
回答
16
这仅适用于2.
权力一般:
x MOD 2^n
等同于:
x AND (2^n - 1)
另请注意,这可能仅适用于x >= 0
是真实的,这取决于您的MOD
的定义为x < 0
。
要了解为什么这个工作的,考虑什么MOD真的是 - 它只是执行整数除法后余。在除以2^n的情况下,我们实际上只是将二进制值右移n位并丢弃任何移出的低位,例如,对于一个8位的二进制数
a b c d e f g h
如果我们通过除以4 = 2^2,则我们用2位右移:
0 0 a b c d e f
其余(g h
)已被扔掉作为结果整数除法。
如果我们想知道余那么我们可以只通过应用0 0 0 0 0 0 1 1
面具提取位g h
:
a b c d e f g h
AND 0 0 0 0 0 0 1 1
= 0 0 0 0 0 0 g h
注意,已经有值3,这在一般情况下只有2^n - 1.
让我们用一些实数来试试这个。假设我们要计算四分之四十二并同时获得商和余数:
42 = 0 0 1 0 1 0 1 0
要得到我们正确的2位移商:
42/4 (decimal)
= 0 0 1 0 1 0 1 0 >> 2
= 0 0 0 0 1 0 1 0
= 10 (decimal)
42 MOD 4 (decimal)
= 0 0 1 0 1 0 1 0 AND 0 0 0 0 0 0 1 1
= 0 0 0 0 0 0 1 0
= 2 (decimal)
所以42/4 = 10余2
4
答案很简单,试着用二进制来思考。
0000 = 0 AND 11 = 0000 = 0
0001 = 1 AND 11 = 0001 = 1
0010 = 2 AND 11 = 0010 = 2
0011 = 3 AND 11 = 0011 = 3
0100 = 4 AND 11 = 0000 = 0
0101 = 5 AND 11 = 0001 = 1
0110 = 6 AND 11 = 0010 = 2
0111 = 7 AND 11 = 0011 = 3
...等等。
这与提醒的结果相同(%为余数,形式上不是模数)。 它只适用于2的幂,只适用于零和正数。
相关问题
- 1. 为什么x ** 3比x * x * x慢?
- 2. C++:2 + x + 1与3 + x相同吗?
- 3. (a mod 2 * x) - (a mod x)
- 4. Convert.ToInt32(x)与(int)相同x
- 5. 为什么IsNaN(x)与x = NaN不同x = NaN
- 6. 为什么x - = x + 4返回-4而不是4
- 7. x ++与++ x有什么不同?
- 8. away3d 3.x vs away3d 4.x
- 9. 为什么x <= x false?
- 10. 从RichFaces 3.x迁移到RichFaces 4.x:什么取代SimpleSelection?
- 11. 为什么x^0 = x?
- 12. 为什么.html与$(x)协同工作,但不与x协同工作?
- 13. 为什么(让x = x + 3在fst(snd(x + 1,(5,x-2))))等于5
- 14. Numpy,为什么`x + = y`产生与`x = x + y`不同的结果?
- 15. HttpClient迁移3.x到4.x
- 16. 从HttpClient 3.x迁移到4.x
- 17. Apache Camel 2.x和Servicemix 3.x/4
- 18. 从Spring Security 3.x升级到4.x
- 19. 将TinyMce 3.x升级到TinyMce 4.x
- 20. Eclipse 4.x中的Eclipse 3.x trimbar
- 21. Hibernate 3.x和4.x性能视角
- 22. ctime(x)= ctime(x-600)为什么?
- 23. Ext.state.Manager.setProvider()行为6.2与4.x
- 24. 循环(1 + x + x ** 2 + x ** 3 + x ** 4 .... n)不起作用
- 25. x mod -3给出返回正数
- 26. 为什么graphicsDevice.viewport(x,y,z,w)使用x作为x和y?
- 27. 计算4 ^在x mod2π为大的x
- 28. 生成表3 x 4与数组php
- 29. 为什么kibana 3.x不适用于弹性搜索2.x?
- 30. Express.js为什么要从2.x升级到3.x
在过去,按位进行比模数快很多,所以对于两个幂来说这是一个很酷的“微优化”:) – TacticalCoder
@ user988052仍然是。在.NET(刚刚测试过)中速度提高了10%,代码在这里是http://ideone.com/BLqZP(但是请注意,在ideone上,差异要小得多)。发布+无调试器运行。 – xanatos
@ user988052:按位,并且比任何必须处理*全部*数字的通用'mod'实现仍然更快。但是这种优化是如此众所周知且很简单,以至于许多编译器都实现它,所以是的。 @xanatos:在进行基准测试时,一定要让JIT先热身。 – delnan