浮点数

Javascript使用64位浮点数存储值类型,即1.0===1,javascript语言底层不存在整数。
64位浮点数分为3个部分:

  1. 第1位是符号位,表示字的正负
  2. 2~12位是指数部分,共11位,用来表示数字的大小
  3. 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);
}

总结

  1. Javascript使用64位浮点数存储数值类型的数据,在进行小数计算的时候会失去精度,大安全数范围是-2^53 ~ 253,最大数值范围是21023 ~ 2^1024。通过Number.MAX_VALUE/Number.MIN_VALUE访问最大值和最小值,通过Number.SAFE_MAX_INTEGER/Number.SAFE_MIN_INTEGER获取最大/最小安全范围
  2. Javascript中数值超过一定程度后会使用科学计数法表示:123e+3
  3. NaN是数字类型中的一个特殊值;0有正负之分但大多数场景下没有区别只有作为分母的时候有所区分;Infinity有正负之分
  4. Javascript中其它进制的表示方法: 0b11;二进制 0011;//八进制、0x11;//十六进制 这些进制数在运算的时候会首先转换成十进制
  5. parseInt(string,base)方法将字符串转换为整数类型,第一个参数是被解析的字符串,第二个参数表示被解析数值的进制。如果接收到的第一个参数不是字符串会自动转换成字符串,第二个参数接收一个2~36的整数类型,超出整个范围parseInt会返回NaN,如果是小数会自动去掉小数部分,第二个参数不传默认被解析的数值是十进制,如果第二个参数是0,false这些仍然按照十进制进行解析。parseInt可以部分解析,不能解析的时候返回NaN
  6. parseFloat用于将字符串解析为浮点数,与parseInt类似,parseFloat可以解析其它进制表示的字符串
  7. 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({});