二进制妙用之循环计数
二进制妙用之循环计数
1. 什么是循环计数
从0到n之间循环依次取数,假设 n=3,那么我需要的如下数据 0,1,2,3,0,1,2…;现象就这样,我也不知道循环计数这个名词是否合适.姑且,就认为合适吧.
2. 常规实现
这点需求,相信对于所有的coder都小菜一碟.我们愉快的写下如下代码
// author: herbert 464884492
// 公众号: 小院不小
for(let i=0;i<=3;i++){
console.log(i);
if(i==3){
i=-1;// 一次for循环后,先执行++,在判断条件
}
// do something
// jump for
}
3. 二进制实现
相信很多朋友,对于这么简单的需求.应该可以一口气实现好多个.姑且就一打吧.当然,我们今天的重点并不是讨论总共有多啊少种实现方式,这里的重点是二进制.好吧,那用二进制改怎么实现呢?
// author: herbert 464884492
// 公众号: 小院不小
let i=0;
while(true){
console.log(i++&0x3); // ++运算符优先级 17 逻辑与 16
// do something
// jump while
}
以上代码中,++先执行,再执行逻辑与.不清楚优先级的朋友,括号最好还是加上.运算符优先级链接,我这里将其复制过来,所有优先级顺序如下
优先级 | 运算类型 | 关联性 | 运算符 |
---|---|---|---|
20 | 圆括号 | n/a(不相关) | (…) |
19 | 成员访问 | 从左到右 | … . … |
19 | 需要计算的成员访问 | 从左到右 | … [ … ] |
19 | new(带参数列表) | n/a | new …( … ) |
19 | 函数调用 | 从左到右 | … ( … ) |
19 | 可选链(Optional chanining) | 从左到右 | ?. |
18 | new(无参数列表) | 从右到左 | new … |
17 | 后置递增 | n/a | …++ |
17 | 后置递减 | n/a | …– |
16 | 逻辑非 | 从右到左 | ! … |
16 | 按位非 | 从右到左 | ~ … |
16 | 一元加法 | 从右到左 | + … |
16 | 一元减法 | 从右到左 | – … |
16 | 前置递增 | 从右到左 | ++ … |
16 | 前置递减 | 从右到左 | — … |
16 | typeof | 从右到左 | typeof … |
16 | void | 从右到左 | void … |
16 | delete | 从右到左 | delete … |
16 | await | 从右到左 | await … |
15 | 幂 | 从右到左 | … ** … |
14 | 乘法 | 从左到右 | … * … |
14 | 除法 | 从左到右 | … / … |
14 | 取模 | 从左到右 | … % … |
13 | 加法 | 从左到右 | … + … |
13 | 减法 | 从左到右 | … – … |
12 | 按位左移 | 从左到右 | …<<… |
12 | 按位右移 | 从左到右 | …>>… |
12 | 无符号右移 | 从左到右 | …>>>… |
11 | 小于 | 从左到右 | …<… |
11 | 小于等于 | 从左到右 | …<=… |
11 | 大于 | 从左到右 | …>… |
11 | 大于等于 | 从左到右 | …>=… |
11 | in | 从左到右 | … in … |
11 | instanceof | 从左到右 | … instanceof … |
10 | 等号 | 从左到右 | …==… |
10 | 非等号 | 从左到右 | …!=… |
10 | 全等号 | 从左到右 | …===… |
10 | 非全等号 | 从左到右 | …!==… |
9 | 按位与 | 从左到右 | …&… |
8 | 按位异或 | 从左到右 | …^… |
7 | 按位或 | 从左到右 | … | … |
6 | 逻辑与 | 从左到右 | … && … |
5 | 逻辑或 | 从左到右 | … || … |
4 | 条件运算符 | 从右到左 | … ? … : … |
3 | 赋值 | 从右到左 | …=… …+=… …-=… …*=… …/=… …%=… …<<=… …>>=… …>>>=… …&=… …^=… …|=… |
2 | yield | 从右到左 | yield … |
2 | yield* | 从右到左 | yield* … |
1 | 展开运算符 | n/a | …… |
0 | 逗号 | 从左到右 | …,.. |
4. 实现原理
聪明的你,一定能发现.二进制实现好像有漏洞,假如我要0到4呢,通过上边的算法,得到结果全是0或4.所以这个和上篇一样一样有一个确权操作.这个权值必须满足二进制位全为1,所以能实现循环计数,有如下规律
2^0^=1
2^1^+2^0^=3
2^2^+2^1^+2^0^=7
2^3^+2^2^+2^1^+2^0^=15
….
这样计数的原理,主要利用二进制与运算特性以及位运算溢出实现置0操作.所有这个不仅有权值的局限性,还和操作系统位数有关系.所以,要使用这种方法,还是根据当前业务具体考虑是否可行.
5. 总结
知识虽小,重在积累.2020注定是不平凡的一年.加油!!
欢迎感兴趣的朋友关注我的订阅号“小院不小”,或点击下方二维码关注。我将多年开发中遇到的难点,以及一些有意思的功能,体会都会一一发布到我的订阅号中