n
表明位位数 = 2^n-1
| 1 |
是奇数,因此能够根据第一位| 1 |
的数值判断一个数值是奇数仍是偶数num % 2
运算本质就是取的| 1 |
的值,若是是1就是奇数,是0就是偶数const getBinary = num => num.toString(2)
~
~
的处理过程函数
实质上是对数字求负,而后减1-num - 1
code
&
和 OR |
和 XOR ^
&
每一个数字中的数位对齐,位对位进行与运算|
每一个数字中的数位对齐,位对位进行或运算^
每一个数字中的数位对齐,位对位进行异或运算<<< 、>>>
和无符号移动 <<、>>
<<
相等于乘于2,而右移>>
至关于除于2因为二进制的结构是| 16 | 8 | 4 | 2 | 1 |
这种结构,位数是从右边开始的,咱们遍历要从右边开始blog
function eachBit(num, callback) { while (num) { num >>= 1 } }
10 = (0,1,0,1,0)
,最靠近左边的1
在第四位2^4-1 = 8
,| 8 |
,因此遍历了4次遍历的次数
和当前的位数
以及被右移出去的值(0或1)
传递给callback
function eachBit(num, callback) { let i = 0 let bitNum = 0 while (num) { // 奇偶位或第一位的值,也即即将被右移出去的值 const value = num % 2 // 位数 = 2^i bitNum = Math.pow(2, i) callback && callback(value, i, bitNum) // 右移1位 num >>= 1 i++ } }
function repeat(str, n) { let res = '' eachBit(n, v => { if (v === 1) { res += str } if (n > 1) { str += str } }) return res }
eachBit
,好比n = 10
那么二进制'1010'
只需遍历四次| 8 |
,第二位1对应| 2 |
str += str
就是一直迭代,重复次数是2^n
(n是遍历的次数)v === 1
的时候也即| 2 |
,这时候是str + str
2个重复的str
,| 8 |
是8个重复的str
str
的重复次数是对应| 2 |
和| 8 |
的,恰好重复10次n > 1
是n等于1,没有必要再执行迭代了,只会遍历一次,且v必等于1,后面没有必要执行了