ECMAScriptt中所有的数值都以IEEE-754 64位格式储存,但是位操作符并不直接操作64位的值。而是先将64位的值转换成32位的整数,然后再执行操作,最后再将结果转换回64位。对于开发人员来说,由于64位储存格式是透明的,所以整个过程就像是只存在32位的整数一样。
数值的表示
对于所有有符号的整数,32位中前31位表示整数的值。第32位表示数值的符号,0表示正数,1表示负数,符号位的值决定了其他位数值的格式。
正数
正数以存二进制格式存储
比如18的二进制表示是
0000 0000 0000 0000 0000 0000 0001 0010
//其中有效为为前5位、没有用到的位以0填充
10010
负数
负数使用的格式是二进制补码,计算一个数值的二进制补码,需要下面几个步骤(以-18为例)
1.求这个数值的绝对值的二进制码
//18的二进制码
0000 0000 0000 0000 0000 0000 0001 0010
2.二进制反码,将0替换成1,将1替换成0
//18的二进制反码
1111 1111 1111 1111 1111 1111 1110 1101
3.二进制反码加1
//18的二进制反码加1
1111 1111 1111 1111 1111 1111 1110 1110
操作符
按位非(~)
按位非返回的是数值的反码
//一个数的负数=一个数的二进制反码+1
//一个数的二进制反码=一个数的负数-1
let a=18
let b=~a//-19
常用方法
取整,类似于parseInt
~~2.2222 //2
按位与(&)
将两个数的每一位对齐,只有在对应位置上都是1的时候才返回1
//18的二进制码
0000 0000 0000 0000 0000 0000 0001 0010
//3的二进制码
0000 0000 0000 0000 0000 0000 0000 0011
//18&3
0000 0000 0000 0000 0000 0000 0000 0010
let a=18
let b=3
let c=a&b //2
常用方法
判断奇偶数
num&1
//如果结果是1那么是奇数
//如果是0那么是偶数
按位或(|)
将两个数的每一位对齐,在对应位置上只要有一个1的情况下就返回1
//18的二进制码
0000 0000 0000 0000 0000 0000 0001 0010
//3的二进制码
0000 0000 0000 0000 0000 0000 0000 0011
//18|3
0000 0000 0000 0000 0000 0000 0001 0011
let a=18
let b=3
let c=a|b //19
按位异或(^)
将两个数的每一位对齐,在对应位置上只有一个1的情况下才返回1
//18的二进制码
0000 0000 0000 0000 0000 0000 0001 0010
//3的二进制码
0000 0000 0000 0000 0000 0000 0000 0011
//18^3
0000 0000 0000 0000 0000 0000 0001 0001
let a=18
let b=3
let c=a^b //17
常用方法
完成数值交换
let a=1
let b=2
a ^= b
b ^= a
a ^= b
console.log(a) // 2
console.log(b) // 1
左移(<<)
将一个数值的所有位向左移动指定的位数
//18的二进制码
0000 0000 0000 0000 0000 0000 0001 0010
//18<<5
0000 0000 0000 0000 0000 0010 0100 0000
let a=18
18<<5//576
//但是有可能会出现改变符号位的情况,以及超出位数的情况
//1的二进制
0000 0000 0000 0000 0000 0000 0000 0001
1<<31
1000 0000 0000 0000 0000 0000 0000 0000
1<<32
0000 0000 0000 0000 0000 0000 0000 0001
有符号右移(>>)
保留符号位,从第31位开始向右移指定位数
//576的二进制码
0000 0000 0000 0000 0000 0010 0100 0000
//576>>5
0000 0000 0000 0000 0000 0000 0001 0010
let a=576
576>>5//18
无符号右移(>>>)
不保留符号位,从第32位开始向右移指定位数
正数与有符号右移相同,但是负数会出现改变符号位的情况
综合应用
rgb与16进制互相转换
16进制转rgb
-
rgb的通常表示为rgb(r,g,b)
-
rgb的值得范围是0-255(这是十进制),那么转成二进制就是8位
-
那么我们要取r的值只需要向右偏移16位(去掉g和b的值)
-
取g的值先向右偏移8位(去掉b的值)然后匹配后8位(oxff的值是11111111)
-
取b的值就是直接匹配后8位
function hexToRGB(hex){ var hex = hex.replace("#","0x"), r = hex >> 16, g = hex >> 8 & 0xff, b = hex & 0xff; return
rgb(${r},${g},${b})
; }
rgb转16进制
就是跟上面差不多,反向理解下就行
function RGBToHex(rgb){
var rgbArr = rgb.split(/[^\d]+/),
color = rgbArr[1]<<16 | rgbArr[2]<<8 | rgbArr[3];
return "#"+color.toString(16);
}
参考:《JavaScript高级程序设计》
感谢阅读