JS中数值常量的含义,数值的运算

JS采用双精度浮点数(Double-precision floating-point format, Binary64)表示数值(Number),关于计算机中浮点数的表示,可参考这里

1 数值常量的含义

  • Number.MAX_VALUE

The largest number thar can be represented in JavaScript. Equal to approximately 1.79E+308.
二进制表示:0111 1111 1110 52个1
计算公式: ( 2 − 2 − 52 ) × 2 1023 ≈ 1.8 × 1 0 308 (2 - 2^{-52}) \times 2^{1023} \approx 1.8\times10^{308} (2252)×210231.8×10308

// true, 约等于1.79E+308
Number.MAX_VALUE === (2 - Math.pow(2, -52)) * Math.pow(2, 1023)
  • Number.MIN_VALUE

The closest number to zero that can be represented in JavaScript. Equal to approximately to 5.00E-304.
二进制表示:0000 0000 0000 48个0 0001
计算公式(指数位全0)是: 2 − 1074 ≈ 5 − 324 2^{-1074} \approx 5^{-324} 210745324

// true, 约等于5E-304
Number.MIN_VALUE === Math.pow(2, -52) * Math.pow(2, -1022)
  • Number.MAX_SAFE_INTEGER Number.MIN_SAFE_INTEGER

The value of the largest(smallest) integer n such that n and n+1 are both exactly representable as a Number value. Equal to 9007199254740991(-9007199254740991).
二进制表示:0100 0011 0011 52个1
计算公式: 2 − 53 − 1 = 9007199254740991 2^{-53} - 1 = 9007199254740991 2531=9007199254740991

// Number.MIN_SAFE_INTEGER is the opposite of Number.MAX_SAFE_INTEGER
// true, 9007199254740991
Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1
  • Number.EPSILON

The difference of 1 and the smallest value of number greater than 1 that is representable as Number value. Equal to approximately 2.22E-16.
二进制表示:0100 0011 0011 48个0 0001
计算公式: 2 − 52 ≈ 2.22 × 1 0 − 16 2^{-52} \approx 2.22 \times 10^{-16} 2522.22×1016

// true, 约等于2.22E-16
Number.EPSILON === Math.pow(2, -52)
  • Number.NaN

A value that is not a number. In equality comparations, NaN dose not equal to any value, including itself. To test whether a value is equalvalant to NaN, use isNaN function.
二进制表示:0111 1111 1111 52个不全为0

// isNaN先将参数toNumber, Number.isNaN要求参数必须是Number
isNaN === Number.isNaN()	// false

isNaN('a')		// true
isNaN('NaN')	// true
Number.isNaN('a')		// false
Number.isNaN('NaN')		// false
  • Number.POSITIVE_INFINITY Number.NEGETIVE_INFINITY

A value greater than the largest number that can be represented in JavaScript. JavaScript displays it as infinity.
二进制表示:0111 1111 1111 52个不全为0

// isFinite先将参数toNumber, Number.isFinite要求参数必须是Number
isFinite === Number.isFinite	// false

isFinite('2')			// true
Number.isFinite('2')	// false

2 数值运算

  • 0.1和0.2的二进制表示
// 0.0001100110011001100110011001100110011001100110011001101
// JS采用Binary64,已有精度损失,是最接近0.1的number
0.1.toString(2)

// 十进制:7205759403792794, 实际的53有效数字
let a = 0b11001100110011001100110011001100110011001100110011010
// 十进制:7205759403792793
let b = 0b11001100110011001100110011001100110011001100110011001

// JS:0.1, 计算器:0.10000000000000000555111512312578
let x = a * Math.pow(2, -56)
// JS:0.09999999999999999, 计算器:0.09999999999999999167332731531133
let y = b * Math.pow(2, -56)
// x比y更接近于0.1

// 0.001100110011001100110011001100110011001100110011001101
// 已有精度损失,是最接近0.2的number, 0.2 = 0.1 * 2
0.2.toString(2)

// 52位有效数字和0.1相同, Binary64中的52位有效数字也和0.1相同
// JS:0.2, 计算器:0.20000000000000001110223024625157
let x = a * Math.pow(2, -55)
// JS:0.19999999999999998, 计算器:0.19999999999999998334665463062265
let y = b * Math.pow(2, -55)
// x比y更接近于0.2
  • 0.1 + 0.2 = ?
// 0.30000000000000004
0.1 + 0.2

// JS: 0.30000000000000004
// 计算器:0.30000000000000001665334536937735
0.10000000000000000555111512312578 + 0.20000000000000001110223024625157

// 0.0100110011001100110011001100110011001100110011001101
0.30000000000000004.toString(2)

// 十进制:5404319552844596, a = b + 1
let a = 10011001100110011001100110011001100110011001100110100
// 十进制:5404319552844595
let b = 10011001100110011001100110011001100110011001100110011

// JS:0.2, 计算器:0.30000000000000004440892098500626
let x = a * Math.pow(2, -55)
// JS:0.19999999999999998, 计算器:0.29999999999999998889776975374843
let y = b * Math.pow(2, -55)

let z = 0.30000000000000001665334536937735
x === z		// true
y === z		// false

// x比y更接近于z
x - z = 0.00000000000000002775557561562891 = 2.775557561562891E-17
z - y = 0.00000000000000002775557561562892 = 2.775557561562892E-17

3 数值的Binary64表示

  • 整数的Binary64表示,MAX_SAFE_INTEGER的由来

0 ~ MAX_SAFE_INTEGER间的整数,正数的符号位是0
关键是确定指数位E和有效数字S,指数位有1023的偏移,011 1111 1111

例子1:S = 0b1.001,E = 0b1000 = 2 3 2^3 23,value = 9

例子2:S = 1.11…还有50个1,E = 100…还有50个0 = 2 52 2^{52} 252
v a l u e = ( 2 − 2 − 52 ) × 2 52 = 2 53 − 1 value = (2 - 2^{-52}) \times 2^{52} = 2^{53} - 1 value=(2252)×252=2531
小数点后的有效数字最多有52位,而E的范围足够大,能够使小数变成整数。

最后1位有效数字的权重最小,为 2 E − 52 2^{E - 52} 2E52,E从小变大,权重也在增大,能表达的数值间隔也在增大。

  • 0.1的Binary64表示
// 0.0001100110011001100110011001100110011001100110011001101
0.1.toString(2)

小数点后55位,有效数字52位,有效数字前面去掉1,后面补上0
Binary64中52位有效数字是:1001100110011001100110011001100110011001100110011010
符号位和指数位: 0011 1111 1011 52位有效数字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值