1、js中最大数字和最小数字:
Number.MAX_VALUE: 1.7976931348623157e+308
Number.MIN_VALUE: 5e-324
Number.MAX_SAFE_INTEGER: 9007199254740991
Number.MIN_SAFE_INTEGER: -9007199254740991
易推出 Javascript 能表示的最大数Number.MAX_VALUE:
1*(Math.pow(2, 53) - 1) * Math.pow(2, 971) = 1.7976931348623157e+308
同理可推得 Number.MIN_VALUE 的值:
1 * 1 * Math.pow(2, -1074) = 5e-324
需要注意的是,Number.MIN_VALUE 表示的是最小的比零大的数,而不是最小的数,最小的数很显然是 -Number.MAX_VALUE。
2、为什么 0.1+0.2 = 0.30000000000000004
十进制转二进制
- 整数部分 "除二取余,倒序排列"
- 小数部分 "乘二取整,顺序排列"
0.1*2=0.2 //0
0.2*2=0.4 //0
0.4*2=0.8 //0
0.8*2=1.6 //1
0.6*2=1.2 //1
0.2*2=0.4 //0
0.2*2=0.4 //0
0.4*2=0.8 //0
0.8*2=1.6 //1
0.6*2=1.2 //1
0.2*2=0.4 //0
0.1的二进制:0.000110011......0011......(0011无限循环)
0.2的二进制:0.00110011......0011...... (0011无限循环)
浮点数科学计数法
根据IEEE 754标准,任意一个浮点数的二进制都可以用如下公式进行表示:
说明:E是无符号整数,长度是11位,取值范围是为0~2047。因为科学计数法中的指数是可以为负数,所以约定减去一个中间数(偏移量)1023,[0,1022] 表示为负,[1024,2047] 表示为正。
e = -4; m =1.1001100110011001100110011001100110011001100110011010 (52位)
e = -3; m =1.1001100110011001100110011001100110011001100110011010 (52位)
0.1的小数点向右移动4位,让其小数点左边只有一个“1”。0.2的小数点向右移动4位,让其小数点左边只有一个“1”。根据IEEE 754标准,双精度浮点的尾数只能存储52位,最后的“1”是第53位,根据进1舍0的原则进行操作。
二进制存储格式
e = -4; m = 1.1001100110011001100110011001100110011001100110011010 (52位)
+ e = -3; m = 1.1001100110011001100110011001100110011001100110011010 (52位)
-----------------------------------------------------------------
相加时如果指数不一致,需要对齐,根据小阶向大阶看齐的原则,一般情况下是向右移,因为最右边的即使溢出了,损失的精度远远小于左边溢出。
e = -3; m = 0.1100110011001100110011001100110011001100110011001101
+ e = -3; m = 1.1001100110011001100110011001100110011001100110011010
-----------------------------------------------------------------
e = -3; m = 10.0110011001100110011001100110011001100110011001100111
规格化
-----------------------------------------------------------------
e = -2; m = 1.0011001100110011001100110011001100110011001100110100(52位)
-----------------------------------------------------------------
= 0.010011001100110011001100110011001100110011001100110100
= 0.3000000000000000444089209850062616169452667236328125
= 0.30000000000000004(十进制)
浮点数存储格式
上图是64位的双精度浮点数,
- 最高位是符号位S(sign),表示浮点数的正负(0代表正数,1代表负数)
- 中间的11位是指数E(exponent),该数都会加上一个常数(偏移量),用来表示次方数;
- 剩下的52位为尾数(有效数字)M(mantissa),表示有效位(尾数),超出的部分自动进1舍0
当结果大于 Math.pow(2, 53) 时,会出现精度丢失,导致最终结果存在偏差,而当结果大于 Number.MAX_VALUE,直接返回 Infinity。
3、位运算符
<<左移,符号位始终不变,空出位补0操作,超过32位自动丢弃。>>有符号右移,把32位数字中的所有有效位整体右移,空出位置使用符号位填补,超出32位被丢弃>>>无符号右移,把无符号的32位整数所有数位整体右移,使用0来填充所有的空位&按位与;|按位或;^按位异或;~按位反
0 (base 10) = 00000000000000000000000000000000 (base 2)
-1 (base 10) = 11111111111111111111111111111111 (base 2)
-2147483648 (base 10) = 10000000000000000000000000000000 (base 2)
2147483647 (base 10) = 01111111111111111111111111111111 (base 2)
32位有符号数字的最小负整数为-2147483648,最大整数为2147483647即(2^31-1)
314的二进制编码:
00000000000000000000000100111010
编码~314,即 314
11111111111111111111111011000101
314 的反码再加1,得到编码 -314,即
11111111111111111111111011000110
补码形式是指一个数的负对应值(如 5和-5)为数值的所有比特位反转后,再加1。补码保证了当一个数是正数时,其最左的比特位是0,当一个数是负数时,其最左的比特位是1。
1、js按位运算时,小数部分怎么处理呢?答案是直接丢弃
~~2.8 //2
~~-2.8 //2
2、js的非数值类型如何进行位运算的呢?
当 js 需要进行位运算的时候,对于非数值类型,会首先将操作数转成一个整型(就是0)然后在进行运算。这就解释了为什么 js 中可以允许非数值类型参与运算,其实这是个伪命题,因为实质上是对非数值操作数的整型表达式进行的位运算。
所以对一个非数值变量做取反操作,得到的一定是 -1,因为实际上等于对 0 做取反操作
~0 == -1
~NaN == -1
~null == -1
~'xx' == -1
~[] == -1
~{} == -1
~func == -1
function func(){}
3、js中的无符号右移(>>>)到底有什么特别之处?
那就是并没有真正发生移位的情况下,符号位会不会被替换成0,在js 中是会发生替换的。
//当操作数是负数时,移动位数大于0,也体现不出区别
1>>>0 //1
-1>>>1 //2147483647
//但是当操作数是负数,无符号右移 0 位时,区别就大了
-1 >>> 0 // 4294967295
-1 (base 10) = 11111111111111111111111111111111 (base 2)
-1的补码为
11111111111111111111111111111111
>>>0 实际上并没有发生数位变化,但是 js 却会把符号位替换成 0
01111111111111111111111111111111
js 中无符号右移时,不管正数、负数都会首先将符号位替换成 0,然后再进行移位。也就是说,该运算符永远返回正整数。
4、~~与Math.floor的区别 ~是按位取反,两次取反后变回原来的操作数。但是当操作数是小数的时候,会忽略其小数部分
~~43.2 == (~)~43.2 == ~(~43.2) == 43
~~-43.2 == ~(~-43.2) == -43
Math.floor(43.2) == 43
Math.floor(-43.2) == -44
5、按位运算的应用有哪些?
(1)奇偶判断
数字 & 1 = 1奇数
数字 & 1 = 0偶数
(2)取整
~~2.83 //2
2.83 >> 0 //2
2.83 << 0 //2
2.83 | 0 //2
(3)计算乘除
//左移一位相当于乘2,左移n位相当于乘以2的n次方
5 << 3 //5*(2^3)=40
//右移一位相当于除2,右移n位相当于除以2的n次方
5 >> 3 //5/(2^3)=0
-5 >> 3 //-1
(4)判断两个整数是否相等
//异或
3 ^ 5 != 0
5 ^ 5 = 0
(5)交互两个整数
function swap(num1, num2){
num1 = num1 ^ num2;
num2 = num1 ^ num2;
num1 = num1 ^ num2;
}
(6)rgb与16进制颜色直接的转换
function hexToRGB(hex){
hex = hex.replace('#', '0x');
const r = hex >> 16;
const g = hex >> 8 & 0xff;
const b = hex & 0xff;
console.log(`rgb(${r}, ${g}, ${b})`);
}
function RGBToHex(rgb){
const rgbArr = rgb.split(/[^\d]+/);
const color = rgbArr[1] << 16 | rgbArr[2] << 8 | rgbArr[3];
return '#' + color.toString(16);
}
4、二进制、十进制、八进制、十六进制之间的转换
其他进制转十进制:Number.parseInt(string , radix)
//字符串转数字
var str = '1100';
parseInt(str, 10); //1100
parseInt(str, 2); //12
parseInt(str, 8); //576
parseInt(str, 16); //4352
十进制转其他进制:Number.toString(radix)
//数字转字符串
var num = 12;
num.toString(10); //12
num.toString(2); //1100
num.toString(8); //14
num.toString(16); //c
(0.1).toString(2);
//"0.0001100110011001100110011001100110011001100110011001101"
二进制转八进制:parseInt(string, radix1).toString(radix1)
//使用十进制进行过度
parseInt('1100', 2).toString(8); //14