位运算在算法中很有用,速度可以比四则运算快很多。To2orTo10JS中十进制转二进制: (val).toString(2)JS中二进制转十进制: parseInt(val, 2)JS中规定安全整数的范围是-2^532^53,所以大于9007199254740991的数进制转换会存在精度问题读取的十进制是根据原码来读取,而在内存中,数值都是以二进制补码形式保存的十进制-5的二进制表示为:1000,0101(原码)原码除符号位外,全部取反再+1:11111011(补码,内存存储形式)-5的结果:正数的补码和原码一样负数原码补码转换规则:符号位不动,从低位往高位数,遇到第一个1之前,包括第一个1不作任何取反,之后,每位都取反。避免了原码转反码再转补码的繁琐。{原码符号位不变} + {数值位按位取反后+1}{原码符号位不变} + {数值位从右边数第一个1及其右边的0保持不变,左边安位取反}// 700000111 // 原码00000111 // 补码// -610000110 // 原码11111010 // 补码 // {原码符号位不变} + {数值位从右边数第一个1及其右边的0保持不变,左边安位取反}// -610000110 // 原码11111001 // 反码11111010 // 补码 // {原码符号位不变} + {数值位按位取反后+1}进行按位操作,都是针对补码去操作。十进制转二进制1 12 103 114 1005 1016 1107 1118 10006464 / 2 = 32 -> 032 / 2 = 16 -> 016 / 2 = 8 -> 1000// 转为二进制为:100000// 十进制 33 可以看成是 32 + 1 ,并且 33 应该是六位二进制的(因为 33 近似 32,而 32 是 2 的五次方,所以是六位),那么 十进制 33 就是 100001 ,只要是 2 的次方,那么就是 1否则都为 0二进制转十进制二进制100001同理,首位是2^5(1) ,末位是2^0(0),相加得出33(只要是 2 的次方,那么就是 1否则都为 0)按位非(~) 取反将1(原码)转二进制: 00000001按位取反: 11111110将符号位之外的其它数字取反[符号位(即最高位)为1(表示负数)]: 10000001末位加1取其补码: 10000010转换会十进制: -200000001 // 原码11111110 // 按位取反10000001 // 除符号位取反10000010 // +1对任一数值 x 进行按位非操作的结果为 -(x + 1), 例如:2 -> -3JS中的作用是配合indexOf():indexOf找到一个给定元素的第一个索引,如果不存在,则返回-1, -1取反操作等于0,其它取反操作不等于0if (~arr.indexOf(v)) if (arr.includes(v))if (~str.indexOf(v)) if (str.indexOf(v) !== -1) 按位或(|)规则:其中一位为 1,结果就是 18 | 70000100000000111———-00001111 // 15任一数值 x 与 0 进行按位或操作,其结果都是 x:6 | 00000011000000000———00000110 // 6任一数值 x 与 -1 进行按位或操作,其结果都为 -1:6 | -10000011010000001———10000111将任一数值 x 与 0 进行按位或操作,其结果都是 x。将任一数值 x 与 -1 进行按位或操作,其结果都为 -1JS中向下取整Math.floor, 返回小于或等于一个给定数字的最大整数num | 0 or Math.floor(num)Math.floor(45.95); // 45.95 | 0// 45Math.floor(45.05); // 45.05 | 0// 45 Math.floor(4); // 4 | 0// 4 Math.floor(-45.05); // -45.05 | 0// -46 Math.floor(-45.95); // -45.95 | 0// -461 | 0 ; // 11.1 | 0 ; // 1’asfdasfda’ | 0 ; // 00 | 0 ; // 0(-1) | 0 ; // -1(-1.5646) | 0 ; // -1[] | 0 ; // 0({}) | 0 ; // 0"123456" | 0 ; // 1234561.23E2 | 0; // 1231.23E12 | 0; // 1639353344-1.23E2 | 0; // -123-1.23E12 | 0; // -1639353344按位与(&)规则:每一位都为 1,结果才为 18 & 7 // 0000010000000011100000000 // 0将任一数值 x 与 0 执行按位与操作,其结果都为 0。将任一数值 x 与 -1 执行按位与操作,其结果都为 x。JS中应用:判断奇偶性10 & 1 // 0 偶数11 & 1 // 1 奇数按位异或 (^)规则:每一位都不同,结果才为 18 ^ 7 // 15100001111111 // 158 ^ 8 // 0100010000000 // 0将任一数值 x 与 0 进行异或操作,其结果为 x。将任一数值 x 与 -1 进行异或操作,其结果为-x不进位加法:根据按位异或的特性就是不进位加法: 8 ^ 8 = 0 如果进位了,就是 16 了,所以只需要将两个数进行异或操作,然后进位。那么也就是说两个二进制都是1的位置,左边应该有一个进位1JS中应用:交换二个数值let a = 3let b = 4a ^= bb ^= aa ^= b有符号右移 (>>)将第一个操作数向右移动指定的位数,向右被移出的位被丢弃,正数则在高位补零,负数则补19 >> 200001001 // 移动二位, 以0填充00000010 // 2-9 >> 210001001 // 原码11110111 // 补码11111101 // 补码右移10000011 // 原码 // -3公式:int v = a / (2 ^ b)JS中的应用:任何小数 把它>> 0可以取整9.99 >> 0 // 99 >> 0 // 99.19 >> 0 // 9除法运算:9 >> 1 // 48 >> 1 // 4二分算法中取中间值:13 >> 1 // 612 >> 1 // 6topic两个数不使用四则运算得出和a + b = (a ^ b) + ((a & b) << 1)