浮点数
Javascript使用64位浮点数存储值类型,即1.0===1,javascript语言底层不存在整数。
64位浮点数分为3个部分:
- 第1位是符号位,表示字的正负
- 2~12位是指数部分,共11位,用来表示数字的大小
- 13~64位是小数部分,共52位表示数字的精度
(-1)^符号位 * 1.xx(小数位) * 2^指数位
Js使用64位浮点数存储数值,而有些运算只有整数能完成,这时会将64位浮点数转为32位整数再进行计算,而转换的过程往往会失去精度,所以在进行小数的计算时要格外小心:
0.1 + 0.2 == 0.3; //false
0.3 - 0.2 ==0.1 // false
1. 数字精度
由于小数位有限,只有53位二进制,只能表示-2^53 ~ 2^53范围内的值次方的数值,超出这个范围会失去精度。通过Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER获取最大/最小安全值
Number.MAX_SAFE_INTEGER //9007199254740991
Number.MIN_SAFE_INTEGER //-9007199254740991
2. 数值范围
Js的数值存储中指数部分有11位,最大为2047(2的11次方-1),分出一半表示负数,因此JavaScript能表示的最大数值范围是-21023~21024(开区间),超出这个范围这个范围(加上小数部分)会溢出,正向溢出返回Infinity,负向溢出返回0。
Math.pow(2,1024); //Infinity
Math.pow(2,-1075); //0
通过Number.MAX_VALUE和Number.MIN_VALUE获取最大值和最小值
Number.MAX_VALUE //1.7976931348623157e+308
Number.MIN_VALUE //5e-324
3. 科学计数法
javascript的数值在超过一定范围后会使用科学计数法表示:
1e+3 //1000
5e-1 /0.5
4. 进制
Js的数值默认都是10进制,同样也提供了其它进制的表示方法,这些进制的数会自动转换为十进制的数:
0b11 //二进制以0b开头
0028 //八进制以00开头
0xa1 //十六进制
5. 数字类型中的特殊值
5.1 Infinity
Infinit用来表示超出最大范围的数值,Infinity有正负之分
1/0 //Infinity
1/-0 //-Infinity
Infinity大于一切数值,-Infinity小于一切数值,NaN除外,NaN和任何数值类型比较大小总是返回false
Infinity >NaN // false
Infinity <= NaN //false
Infinity的计算符合数学运算规则:
Infinity + 5; //Infinity
Infinity -5; //Infinity
Infinity * 5; //Infinity
Infinity / 5; //0
Infinity * 0; //NaN
Infinity / 0; //Infinity
0 / Infinity; //0
Infinity + Infinity; //Infinity
Infinity * Infinity; //Infinity
Infinity - Infinity; //NaN
Infinity / Infinity; //NaN
5.2 +0和-0
0有正负之分,通常情况下+0和-0是没有区别的,只有当0作为分母的时候有所区别:
+ 0 ===-0; //true
1 / 0; //Infinity
1 / -0; //-Infinity
5.3 NaN
NaN(Not a Number)表示非数字,主要用于字符串解析数字出错的场合,一些数学元算也会返回NaN。
Number('1asd55');
0/0;
Infinity / Infinity;
- NaN不是数据类型,它是数值类型中的一个特殊值
- NaN与任何数字计算都得到NaN
- NaN与任何值都不相等包括它自己
- 无法通过indexOf判断数组包含NaN
typeof NaN; //number
NaN + 5; //NaN
NaN -0; //NaN
NaN === NaN; //false
[NaN].indexOf(NaN); //false
6. 与数值相关的全局方法
6.1 parseInt
parseInt方法接受一个字符串,返回对应的数值类型,如果只有部分能被解析那么返回部分数值,如果没有能被解析的部分则返回NaN。
parseInt('12'); //12
parseInt('12ab34c');//12
parseInt('a112'); //NaN
如果parseInt接收的参数不是字符串类型,会先自动转换成对应的字符串。
parseInt(true); //parseInt(String(true)); => NaN
parseInt(5); //parseInt(String(5)); => 5
parseInt(undefined); //parseInt(String(undefined)); //NaN
parseInt(null); //parseInt(String(null)); //NaN
parseInt只能解析十进制字符串,如果输入的不是字符串会产生令人意外的结果:
parseInt('0b11'); //0
parseInt(0b11); // => parseInt(String(0b11)) //3
parseInt还有第二个参数用来表示被解析的数的进制,范围是2~36的闭区间,如果第二个参数不在这个范围则praseInt返回NaN,如果被解析的值和进制数不匹配也返回NaN。
parseInt('11',2); //3
parseInt('11',8); //9
parseInt('2',37); //NaN
parseInt('1',1); //NaN
parseInt('8',2); //NaN 2进制不包含8
6.2 parseFloat
parseFloat用于将字符串转换为浮点数,语法parseFloat(‘123’),parseFloat可以部分解析,如果整个字符串都无法转为浮点数则返回NaN
parseFloat('123'); //123
parseFloat('11b4123'); //11
parseFloat('s123'); //NaN
如果传入的字符串符合科学计数法会自动进行转换
parseFloat('1.23e+3'); //1230
与parseInt类型,当接收的参数不是字符串的时候会自动转换为字符串
parseFloat('0x15'); //0
parseFloat(0x15); //21
parseFloat会自动过滤字符串两端的空格换
parseFloat(' 515 \n'); //515
parseFloat可以解析Infinity
parseFloat(Infinity); //Infinity
6.3 parseFloat和parseInt的异同?
相同点:
- parseInt和parseFloat都接收一个字符串参数,如果传入的参数非字符串会自动转换成字符串
- parseInt和parseFloat都支持部分转换,无法转换时返回NaN
- parseInt和parseFloat都会自动过滤字符串两端的空白符
不同点
- parseInt可以接收两个参数,第二个参数用来设置被解析数值的进制
- parseFloat可以解析使用科学计数法
- parseFloat可以解析Infinity
6.4 parseInt和Number的区别?
- parseInt的解析规则相对宽松可以只解析部分,Number的解析规则比较严格
- parseInt不能解析空字符串,Number可以解析空字符串。一般来说Number的第二个参数为’',false, 或省略的时候会返回0
parseInt('1b23'); //1
Number('1b23'); //NaN
parseInt(''); //NaN
Number(''); //0
6.5 isNaN
isNaN用来判断一个值是不是NaN,返回布尔值,需要注注意的是isNaN只对数值有效,如果传入的是非数值类型会自动转换成数值类型,这一点要特别小心,例如当传入[]和{}的时候也会返回true
isNaN(NaN); //true
isNaN({}); //true
隐式转换使得isNaN并不能准确的判断,为了使结果正确在使用isNaN之前必须先判断输入是数值类型:
function IsNaN(n){
return typeof n === 'number' && isNaN(n);
}
总结
- Javascript使用64位浮点数存储数值类型的数据,在进行小数计算的时候会失去精度,大安全数范围是-2^53 ~ 253,最大数值范围是21023 ~ 2^1024。通过Number.MAX_VALUE/Number.MIN_VALUE访问最大值和最小值,通过Number.SAFE_MAX_INTEGER/Number.SAFE_MIN_INTEGER获取最大/最小安全范围
- Javascript中数值超过一定程度后会使用科学计数法表示:123e+3
- NaN是数字类型中的一个特殊值;0有正负之分但大多数场景下没有区别只有作为分母的时候有所区分;Infinity有正负之分
- Javascript中其它进制的表示方法: 0b11;二进制 0011;//八进制、0x11;//十六进制 这些进制数在运算的时候会首先转换成十进制
- parseInt(string,base)方法将字符串转换为整数类型,第一个参数是被解析的字符串,第二个参数表示被解析数值的进制。如果接收到的第一个参数不是字符串会自动转换成字符串,第二个参数接收一个2~36的整数类型,超出整个范围parseInt会返回NaN,如果是小数会自动去掉小数部分,第二个参数不传默认被解析的数值是十进制,如果第二个参数是0,false这些仍然按照十进制进行解析。parseInt可以部分解析,不能解析的时候返回NaN
- parseFloat用于将字符串解析为浮点数,与parseInt类似,parseFloat可以解析其它进制表示的字符串
- isNaN用于判断某个值是不是NaN,如果接收的参数为非数值类型会先转换成数值类型,因此使用的时候要先判断数值类型
练习题
学废了吗?快来做过练习题吧
+0 === -0;
0/0;
1/0;
1/-0;
1/0;
Infinity / 1;
5 - Infinity;
Infinity - Infinity;
Infinty / Infinty;
Infinity > NaN;
Infinty <= NaN;
parseInt('123');
parseInt('b215');
parseInt('\n1b3 ');
parseInt('');
parseInt(true);
parseInt(false);
parseInt(['xyz']);
parseInt([]);
parseInt({});
parseInt('0x13');
parseInt(0x13);
parseInt(123,2);
parseInt(121,37);
parseInt(11,36.5);
parseFloat('2e+3');
Number('0');
Number([]);
Number([1,2]);
Number([111]);
Number({});