位运算与余数

本文探讨了C风格语言中使用位运算代替取余运算的原理,特别是在除以2的幂时如何通过X & (2^N - 1)获取余数。通过实例解释了这种位运算背后的逻辑,并提出对于非2的N次幂的取余运算的疑问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:在C风格语言中(比如C,C++,C# (注:排名按出生日期 ^_^)),取余运算符定义为“%”。但在很久很久以前,CPU采用如下方法计算余数(注意,该方法只对2的N次方数系有效):

X & (2^N - 1)

 

看到这个算法,我感到比较好奇,为什么这么做呢?

 

首先从求余数谈起,我们知道,计算机中存储的方式是0和1序列:

1 0001 2^0

2 0010 2^1

3 0011 2^1 + 1

4 0100 2^2

当我们把这些数字序列左移一位的时候... 是的,你答对了,相当与数字扩大为原来的2倍,同理可知右移一位就是缩小为原来的1/2。

 

那么余数在哪里?被移掉的哪些位便是余数,这是无数前人的证明结果~可以自己拿笔和纸画一画就明白了。

 

那么,说了这么多,为什么一个求余的%被替换为:X & (2^N - 1)?

举例:

9 的二进制就是1001

8 的二进制就是1000

显然余数是1,按照公式这么做:

把8的二进制1000换为8-1也就是7,7的二进制表示为:0111

1001&0111 = 0001

答案为1与我们想的结果一致。

是巧合么?我们把9换成13,过程你亲自来一遍,结果在你没算错的情况下必然和我的一样:0101

 

但是注意,这种方法只是适合与求一个数除以二的N次冥才正确。

先说原理再说疑问:

原理:

由于除数是2^N (N为0起始递增的整数),所以隐藏条件就是,除数的2进制真身只能是如下的方式展现:

0001,0010,0100,1000.。。。。。

没看出来?那我们继续:

10000,100000,1000000.。。。。

明白了吧,当

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值