如何有效地找出数字是7的倍数?

时间:2015-08-07 04:28:28

标签: algorithm numbers

有多种方法可以找到相同的方法,我尝试使用按位操作 -

if(((n<<3) - n)%7 == 0 ) {
    print "divide by 7";
}

还有其他更有效的方法吗?

我们可以使用以下算法找到数字是3的倍数 -

如果奇数设置位数(奇数位置的位数)和偶数设置位数之间的差值是3的倍数,则数字也是如此。

我们可以将上述算法推广到其他数字吗?

2 个答案:

答案 0 :(得分:5)

因此,如果您的数字可由硬件支持的整数表示,并且硬件具有除法或模运算,那么您应该只使用它们。它比你写的任何东西都简单,而且可能更快。为了与硬件竞争,你必须使用汇编程序并使用比硬件制造商更好的其他更快的指令,并且没有他们可以使用的无证技巧的优势,但你不能。

这个问题变得有趣的地方是涉及任意大整数的地方。 Modulo有一些技巧。例如,我可以告诉你100000000010000010000可以被3整除,即使我的大脑是一个非常慢的数学处理器而不是计算机,因为%模运算符的这些属性:

  • (a+b+c) % d = ( (a%d) + (b%d) + (c%d) ) %d
  • (n*a) % d = ( (a%d) + (a%d) + (a%d) +... (n times) ) %d = (n*(a%d)) %d

现在请注意:

  • 10%3 = 1
  • 100%3 =(10 *(10%3))%3 = 10%3 = 1
  • 1000%3 =(10 *(100%3))%3 = 1 等...

因此,为了判断一个基数为10的数字是否可以被3整除,我们只需对数字求和,看看总和是否可被3整除

现在使用相同的技巧,使用以八进制或基数8表示的大二进制数(在评论中也由@hropyatr指出),并使用7的可除性,我们有特殊情况:

8 % 7 = 1

从中我们可以推断出:

(8**N) % 7 = (8 * (8 * ( ... *( 8 * (8%7) % 7 ) % 7 ) ... %7 = 1

为了“快速”测试7的任意大八进制数的可除性,我们需要做的就是将它的八进制数加起来并尝试将其除以7.

最后,坏消息。

发布的代码:

if ( (n<<3 - n) % 7 ==0 ) ...不是7的可分性测试。

因为任何true总是产生n(正如@Johnathan Leffler所指出的)

n&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&gt;

因此,例如6不能被7整除,

8n6<<3 = 48,可被48 - 6 = 42整除。

如果你的意思是右移7也不起作用。使用49进行测试,if ( (n>>3 - n ) % 7 == 0 )49//866-49,尽管49可被7整除,但-43不是。-43

最简单的测试,if (n % 7 ) == 0是你最好的镜头,直到n溢出硬件,此时你可以找到一个以八进制表示n的例程,并将八进制数字加模7。

答案 1 :(得分:2)

我认为if(n%7 == 0)是通过7检查可分性的更有效方法。
但是如果你处理的是大数字并且无法直接进行modulus操作,那么这可能有所帮助:

  1. 当且仅当10x + y可被7整除时,x − 2y形式的部分内容才能被7整除。换句话说,从剩余数字形成的数字中减去最后一位数的两倍。继续这样做,直到获得可被7整除的数字。当且仅当使用此过程获得的数字可被7整除时,原始数字才能被7整除。
    例如,数字371: 37 − (2×1) = 37 − 2 = 35; 3 − (2 × 5) = 3 − 10 = −7;因此−7可以被7整除,371可以被7整除。
  2. 另一种方法是乘以3。当10x + y除以7时,3x + y形式的余数具有相同的余数。必须将原始数字的最左边数字乘以3,添加下一个数字,除以7时的余数,然后从头开始:乘以3,添加下一个数字等。
    例如,数字371: 3×3 + 7 = 16余数22×3 + 1 = 7 该方法可用于找出除以7的余数 P.S:reference