在C中,最好的方法是查看一个数字是否可以被另一个数字整除?我用这个:
if (!(a % x)) {
// this will be executed if a is divisible by x
}
反正哪个更快?我知道这样做,即130%13将导致每10次做130/13。因此,只需要一个循环就有10个循环(我只想知道130是否可以被13整除)。
谢谢!
答案 0 :(得分:25)
我知道这样做,即130%13将导致每10次130/13
梦呓。 %
在我曾经使用的任何处理器上都没有这样的东西。它会130/13
一次,并返回余数。
使用%
。如果您的应用程序运行速度太慢,请对其进行分析并修复任何太慢的应用程序。
答案 1 :(得分:8)
对于两个任意数字,检查的最佳方法是检查是否a % b == 0
。模数运算符具有基于硬件的不同性能,但您的编译器可以比您更好地解决这个问题。模数运算符是通用的,您的编译器将为您正在运行的任何硬件找出最佳的指令序列。
如果其中一个数字是常数,你的编译器可能会通过进行一些位移和减法的组合来优化(主要是2的幂),因为硬件div / mod比加法或减法慢,但在现代处理器上延迟(已经只有几纳秒)被大量其他性能技巧所隐藏,因此您无需担心它。没有硬件通过重复划分来计算模数(一些旧的处理器通过重复的位移和减法进行划分,但它们仍然使用专用硬件,因此硬件执行它比使用软件模拟它更快)。大多数现代ISA实际上都在一条指令中计算除法和余数。
可能有用的唯一优化是除数是2的幂。然后,您可以使用&
来屏蔽低位(通过除数-1)并检查结果为零。例如,要检查a
是否可被8整除,a & 7 == 0
是等效的。一个好的编译器会为你做这个,所以坚持使用%
。
答案 2 :(得分:6)
在一般情况下,使用模运算符可能是最快的方法。有一些例外,特别是如果您对数字是否可以被2的幂整除感兴趣(在这种情况下,按位运算可用),但如果您只使用%
,编译器应自动为您选择它们。对于13
等任意值,您不太可能做得更好。
另外,“每10次做130/13”是什么意思?它只130 / 13
一次。这正是所需要的。
答案 3 :(得分:3)
如果x
是常数,那么是:
if (a * 0x4ec4ec4ec4ec4ec5 < 0x13b13b13b13b13b2) {
// this will be executed if a is divisible by 13
}
0x4ec4ec4ec4ec4ec5
是modular multiplicative inverse的13(模2 64 ),所以如果a
实际上是13的倍数,那么产品将小于(2 64 / 13)。 (因为a是整数n
的13倍,而n
必须符合64位字,这意味着它小于2 64 。)
这仅适用于x
的奇数值。对于偶数(即y> 0的倍数为2 y ),您可以将此测试与按位AND测试结合使用(y
的最后a
位应为零如果他们然后将a
除以2 y 并继续进行乘法测试。)
如果x
是常量,这是值得的,因为计算乘法逆是比整数除法更贵。
修改:我还假设a
和x
未签名。
答案 4 :(得分:0)
当机器执行%
时,它只执行除法指令,并自动生成余数。
然而,请注意,如果其中一个数字为负数,%
将给出负余数。
如果你只关心零的余数,这不是问题,
但是,如果你正在寻找另一个剩余部分,比如1,它真的会让你失望。