如何查找出或判断某个数的倍数

最直观的方法

其实最直观的方法,就是如果x对i取余得0,表示x能由i整除,所以x就是i的倍数

if(x%i==0)
	printf("%d是i的倍数\n",x)

但是我们这里肯定要讲别的方法

欧几里得

假如某个数是x的倍数,那么x就是两数之间的最大公约数,那么我们很容易想到欧几里得递归求最大公因数的方法

那我们根据这条性质求出x的倍数

int func(int a,int b)
{
	return b==0?a:func(b,a%b);
}

int main(){
	int N=1024;
	int x=2;
	for(int i=0;i<=N;i++)
		//假如i是x的倍数
		if(func(i,x)==x)
			printf("%d\n",i);
}

位运算

没写好,随便看看吧

通过位运算也可以解决这类问题
先看几组运算

	1111 1111
&	0000 0000
=	0000 0000

	1111 1110
&	0000 0001
=	0000 0000

	1111 1100
&	0000 0011
=	0000 0000

直观上来看,任何数&0都会得0,最低位为0的数&1都会得0,依次类推都成立
我们再延伸探讨一下,
第一组数据中,左值可以取任意的数
第二组数据中,左值同样可以取得任意的数,只要它的最低位是0
第三组数组中,…,只要最低两位都是0

再翻译成十进制
任意数都是1的倍数,成立
只要不是奇数的数都是2的倍数。仔细想想,在2进制中,如果最低位永远是0,没有1的存在,该数一定是奇数,就是说该数x可以表示成 C 1 ∗ 2 n + C 2 ∗ 2 n − 1 + . . . + C n ∗ 2 1 C_1*2^{n}+C_2*2^{n- 1}+...+C_n*2^{1} C12n+C22n1+...+Cn21的形式,可以发现该数一定能由2表示,这也是成立的 (通过这条性质我们还可以判断一个数的奇偶性)
第三组数据,0000 0011的值是3,那么某个数&3==0是什么意思呢?我们不妨列出这些数

0000 0100	--- 4
0000 1000	--- 8
0000 1100	--- 12
.... ..00	---	..

发现只要是最低两位都不是1的数,它们都有一个性质,那就是它们一定是4的倍数。。。
那我们这下是不是可以做个推论,只要任意一个数&x为0,那么它一定是x的倍数
先验证一下把,我们查找6的倍数

	0001 1000
&	0000 0110
=	0000 0000
正确,246的倍数

	0000 1001
&	0000 0110
=	0000 0000
错了,9&6==0,但是9并不是6的倍数,找到一个反例,说明上面的结论是不正确的

这时候我们发现任意一个数&x为0,是这个数是x的倍数的必要条件,而不是充分条件。
再整理一下数据发现,右值的1必须是连续的,这时候我们才能说
对于某个特殊的x,如果某个数&x==0,那么该数一定是(x+1)的倍数。x的bit从低位开始必须是连续的1
继续验证一下,发现这条性质是成立的。但是对于这个特殊的x,如下面这种形式

0000 0001	--- 1	用于判断某个数是不是2的倍数
0000 0011	--- 3	用于判断某个数是不是4的倍数
0000 0111   --- 7	用于判断某个数是不是8的倍数...
.... ....

等于说现在又绕回来了 😂…这个方法其实只能判断某个数是不是X的倍数,${ X | 2^c,(c=1,2…n) } $
写了一大堆。。也算是个扩展思路的方法把😂😂

int main(){
	//查找2的倍数
	int N=1024;
	for(int i=0;i<=N;i++)
		if((i&0x01)==0)
			printf("%d\n",i);
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值