js数值类型

文章目录

  • js数值类型--number
    • 更详细的参考资料
    • js数值类型的存储形式
    • js数值的范围与精度(有效数位数)
    • js中十进制小数的存储与运算不准确的问题
    • 数值的表示方法
    • 关于js中的NaN
    • 与数值有关的全局方法

js数值类型–number

更详细的参考资料

中文wiki-IEEE754
中文wiki-IEEE754(免版)

js数值类型的存储形式

JavaScript 内部,所有数字都是以64位浮点数形式储存,即使整数也是如此.

  • 什么是浮点数?
    利用科学计数法来表达实数(Number),即用一个尾数/小数部分(Fraction),一个基数(Base,通常为2),一个指数(Exponent)以及一个表示正负的符号(Sign)来表达实数。尾数有时也称为有效数字(Significand)
    浮点数表示公式:在这里插入图片描述
    其存储结构为:js数值类型_第1张图片
    各部分说明:
  • 符号域Sign:决定数值的正负
  • 指数域Exponent:决定数值的小数点位置
  • 指数偏移值(修正值)Bias:为了使指数域区分正负(小数点既可右移,也可左移),而在存储时默认减掉的一个值,64位浮点数该值为1023=(1/2)*2指数域位数-1=210-1(因为初始值从0开始,所以减去1)
  • 小数域/有效数字域Fraction:小数点之后的有效数字(未与指数域相乘之前)

但是,同一个数值,由于指数域的取值不同会有不同的表示方法,例:12.34=1.234×101=0.1234×102.为了提高数据的表示精度同时保证数据表示的唯一性,需要对浮点数做规格化处理。
在计算机内,对非0值的浮点数,要求尾数的绝对值必须大于基数的倒数,即|F|≥1/B.对于二进制来说,就是:要求尾数域的最高有效位应为1,把不满足这一表示要求的尾数,变成满足这一要求的尾数的操作过程,叫作浮点数的规格化处理,通过尾数移位和修改阶码实现规格化要求。


js数值的范围与精度(有效数位数)

一般情况下(normalized,0< E< 2047)
js数值类型表示整数的范围

  • js数值中,整数都可以被精确存储;而很多小数的存储会有误差(见后续章节)
  • 由以上js数值的存储结构:有效数字有53位(一个隐含位),也就是说,绝对值小于2的53次方的整数,即-2^53 到 2^53的整数,都可以精确表示.
  • 注:js能精确表示的最大数值是253 ,但可以表示的最大数值不是 253.

特殊情况下

  • 情况1:denormalized(非规约形式的浮点数: 有效数字隐含位,也就是浮点数整数部分=0,E=0,0 N = ( − 1 ) s × ( 0 + F ) × 2 0 − ( B i a s − 1 ) N=(-1)^s\times({\color{Red} 0}+F)\times2^{{\color{Red} 0}-(Bias-1)} N=(1)s×(0+F)×20(Bias1)
    此种情况下,有效数字的隐含位(小数点之前)由1变为0且计算公式变为:±0.F×2(-1022)
    [注意:denormalized下,E取0,但指数域不是-1023而是-1022.]
  • 情况2:零值(E=0,F=0)
    由于符号位S是独立存储的,所以由+0和-0之分.
  • 情况3:infinity无穷大(E=2047,F=0)
    同零值,也有+∞和-∞之分.
  • 情况4:NaN(not a number)(E=2047,F>0)

注:

  • 正向溢出(overflow):一个数>=2^1024,返回infinity
  • 反向溢出(underflow):一个数小于2^(-1075)(指数部分最小的-1023加上52位小数部分),返回0.

js中能表示的最大值与最小值(绝对值)
js数值类型_第2张图片

  • 最大值Number.MAX_VALUE

    如上图,最大值应该是仅次于infinity的值,也就是E=2046,F为全1时的值,因此:
    Number.MAX_VALUE=1×(21023)×1.1…1=1×2(1023-52)×11…1B=2^(1023-52)×9007199254740991≈1.7976931348623157e+308

  • 最小值Number.MIN_VALUE

    最小值应该是指数域E=0,而小数域F仅有最低位为1时的值.属于denormalized,因此根据其公式:
    Number.MIN_VALUE=1×2(-1022)×2(-52)≈5e-324


js中十进制小数的存储与运算不准确的问题

知识回顾:十进制转二进制

  • 正整数部分:除二取余,倒序排列
    js数值类型_第3张图片

  • 小数部分:乘二取整,正序排列
    js数值类型_第4张图片

十进制小数转二进制小数的问题
一些小数,例如0.1,0.2,0.3,0.4等,在转换为二进制时,其位数是无穷的,而我们用于存储的空间只有52位,所以要进行舍入,那么就会产生误差.

举例 0.1+0.2===0.3为false

  • 首先,我们用在线任意进制转换器对0.1,0.2进行十进制到二进制转换:
    0.1D=0.00011001100110011001100110011001100110011001100110011010B
    0.2D=0.00110011001100110011001100110011001100110011001100110100B
    0.3D=0.010011001100110011001100110011B
    (注意:上述三个十进制小数对应的二进制数位数本身是无穷,我们对此作了第52位的舍入,即截取前52位,并在第52位上加1)

  • 接着我们对上述0.1和0.2两行二进制数进行二进制加法运算,得到如下结果:
    0.01001100110011001100110011001100110011001100110011001110

  • 再借由在线任意进制转换器将结果转换回十进制,得到结果为:
    0.3000000000000000444089209850062616169452667236328125.

同时,我们运行js代码:
alert((0.1+0.2));
得到结果为:
js数值类型_第5张图片
总结:
我们在键盘输入一个十进制数值后,js会将之进行十进制到二进制的转换并存储,在此过程中产生了误差,等到我们再次使用这个值的时候,它已经不是原来正确的值了.

解决办法(简单但不严谨):
将要计算的小数转换为整数进行计算,计算完毕后再转换回小数(只适用于四则运算).


数值的表示方法

  • 字面量直接表示:

    • 十进制:35
    • 二进制:10010B或者前缀0b(数字0,字母b)
    • 八进制:前缀0(数字0).如果有前缀0,其后又有8,9视为十进制
    • 十六进制:前缀0x(数字0,字母x/X)
  • 科学计数法:(以下两种情况,js自动转换为科学计数法)

    • 小数点前数字多于21位
    • 小数点后的零多于5个

关于js中的NaN

  • NaN不是数据类型,只是基本类型number里的特殊值
  • NaN不等于任何值,包括它本身
  • NaN转换为布尔值为false
  • 用isNaN(x)方法判断一个值是否是NaN(注意:isNaN只针对数值,传入非数值参数可能会出现问题)

与数值有关的全局方法

  • parseInt(str):将字符串转换为整数
    转换说明:

  • 自动过滤前导的空格

  • 如果参数不是字符串,会先将其转换为字符串,再进行操作

  • 转换过程是一个一个字符逐个进行,遇到不能转换为数字的字符,返回已经转换的部分;如果第一个字符都不能转换,返回NaN

  • 字符串以0开头,按十进制转换;以0x或0X开头,按16进制转换

  • 遇到自动转换为科学计数法的数字字符串,parseInt()会将其科学计数法表示的形式作为字符串进行转换,从而产生古怪的结果.

    第二参数:

  • parseInt(str)还可以接受第二个参数(2-36),指明被解析值的进制,返回该值对应的十进制数;

  • 若第二个数值超出2-36范围,返回NaN

  • 第二个数值为0,null,undefined,直接忽略

  • 如果第二个参数为非数值,先将之转换为数值,再按前两个情况判断和操作

  • 如果第一个参数包含对于指定进制无意义的字符,只返回可转换的部分(若最高位无法转换,返回NaN)

  • parseFloat(str):将字符串转换为浮点数
    转换说明:

  • 自动过滤字符串前导空格

  • 如果参数不是字符串或者字符串第一个字符不能转换,返回NaN(此处与parseInt不同)

  • 转换过程是一个一个字符逐个进行,遇到不能转换为浮点数的字符,返回已经转换的部分

  • 会将空字符转换为NaN

  • isNaN(x):判断一个值是否为NaN
    转换说明:

  • isNaN()只对数值精准有效,如果传入非数值,会先将其转为数值,再进行判断:isNaN(‘123’)==false;isNaN(‘abc’)==true;isNaN(Array)/isNaN(Object)==true

  • 但是,对于空数组和只有一个数值成员的数组,null,isNaN()返回false;不过,对于空对象{},返回true

  • 因此,判断NaN应该利用它是唯一一个"不等于自身的值"的特性来实现

  • isFinite():判断某个值是否为正常的数值

  • isFinite()只对数值精准有效,如果传入非数值,会先将其转为数值,再进行判断.

  • 但是,对于空数组和只有一个数值成员的数组,null,isNaN()返回true;不过,对于空对象{},返回false

  • 对于Infinite,-Infinite,NaN,undefined返回false

你可能感兴趣的:(javascript,CSS,数据类型)