为什么num % 64 等于 num & 63

大家好,我是小白学编程。

最近在工作中一个同事问我“位图是怎么回事?”,我说:“是 Java 中可以使用少量内存存储大量数字的那个位图吗?”他说是,我说:“你先等等,我明天再告诉你。”因为我之前也没用过位图,也只是了解,但是具体怎么回事我也说不上来,于是我就借这个机会去研究了一下。但是,当然,这篇文章不是说位图的。

一、位图 

        被同事问道“位图是怎么回事”后,我特意去了解了一下位图,我在网上搜索了很多相关的文章,其中有一位大佬写的我觉得挺好的,我也是借着这篇文章了解的位图,文章是这个

位图的简单实现和使用

在这里感谢这位大佬!这里我不多说了,感兴趣的可以看一下上面这篇文章。

位图我的个人理解就是一个数字数组,然后数组中的每一个元素都有一定的占位,每个占位上都可以表示一个数的状态,bit 位上是 1 表示目标数存在,bit 位上是 0 表示目标数不存在。如下图 :

在上面 int 数组中,每一个 int 值中的每一个 bit 位上都可以表示一个数的存在状态。

二、num % 64 等于 num & 63 ?

        当我看到位图那篇文章之后,对位图是理解了,但是有一点我没太理解,就是文章中说的在定位所在 bit 位时使用的 num % 64,其实就是 num & 63。为什么说 num % 64 就是 num & 63 呢?一开始我不太理解,后来想一下,其实就是通过二进制方式的按位与运算的形式来求余数。所以 num % 64 确实是等于 num & 63

三、为什么相等

        由于本人二进制学的不是很好,接下来的是我的个人理解,如果有不对的地方,还希望可以得到大家的斧正。

        num % 64 相当于 num % (2 * 2 * 2 * 2 * 2 * 2) ,64正好是 2 的正数次方,所以就相当于是 num & 63 ,那为什么呢,怎么理解?为了理解这个,首先根据十进制进行一次推演

此处根据十进制的数进行推演,如果 num % 1000 相当于 num % (10 * 10 * 10) ,1000正好是 10 的正数次方,那么,对于 num 这个数,我们就不用考虑大于等 1000 的部分了,只要考虑小于 1000 的部分。因为如果 num 是个大于 1000 的数,那么 num 可以拆分为 k * 1000 + v ,也就是 k 个 1000 加上 v,那么 num 对 1000 进行取余时,得到的就是 v 。举个例子,如果 num = 123456 ,那么 num = 123 * 1000 + 456,所以 num 对 1000 进行取余时,结果就是 456。

        那么 num % 64 就是 num & 63 是怎么来的呢?首先说明一下,这个转换仅使用于取余的对象是 2 的整数次方的数有效。想要解释这个,首先需要把 num 和 64 、63 转换成 2 进制的形式来看,这里假设 num = 123 。那么转换成 2 进制之后是这样的

123 的 2 进制格式是  1111011
64 的 2 进制格式是   1000000
63 的 2 进制格式是    111111
59 的 2 进制格式是    111011

         十进制的数是逢十进一,二进制的数是逢二进一。通过根据十进制的数进行推演,一个数对 64 进行取余,那么也说不用考虑 num 大于等于 64 的部分,只要考虑小于 64 的部分即可。

        num % 64 ,num 可以拆分成 k * 64 + v,那么 num 对 64 进行取余得到的结果就是 v 。

        把上面的数全部替换成二进制的形式就一目了然了

        num % 1000000 ,num 可以查分成 k * 1000000 + v,那么 num 对 1000000 进行取余得到的结果就是 v。

        我们接着上面的假设继续说,假设 num = 123,那么也就是变成了

num % 64 
123 % 64
转换成二进制就是
1111011 % 1000000

也就是变成了二进制中 1111011 对 1000000 进行取余,同理,我们不用考虑大于等于 1000000 的部分,只要考虑到小于 1000000 的部分即可,所以所以 1111011 可以看作是

1111011 = 1 * 1000000 + 111011

那么余数就是二进制的 111011,转换成十进制的数就是 59

        那么怎么能快速的取到这个二进制的 v 呢?那就是通过二进制的按位与 & 运算。简单的说一下按位与运算就是只有当上下位都是 1 的时候结果才落 1 ,否则落 0。那么和哪个数做按位与运算呢?因为 64 的二进制是 1000000,num 对 64 进行取余,仅考虑 num 中小于 64 的部分,那么也就是只考虑 num 二进制的后六位,那么就可以知道我们只要与二进制的 111111 这个数做按位与运算即可得到,111111 转换位十进制的数是 63 。所以,到这里,我能就知道了为什么 num % 64 就是 num & 63 了。

四、按位与 &

        按位与运算就就像做小学加减法那样进行,计算法则就是连个数中同位的数都是 1 时结果落 1,否则结果落 0 。如下图

对 num1 和 num2 做按位与运算,num1 和 num2 右对齐方式上下排列,相同位位值,就是图中相同颜色的位置。如果 num1 和 num2 中相同位位置的数(相同颜色)都是1 ,则结果在相同位位置的值就落1,否则在结果相同位位置就落 0 ,如下示例

所以,对于 123 % 64 就是 123 & 63 的二进制按位与应该是这样的

        123 的二进制是 1111011

        63 的 2 进制格式是 111111

        59 的 2 进制格式是 111011

 

 

人生没有固定的路线,每一个选择都是一次转折

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值