首先,先来回答几个问题,大多数开发者,对于这几个问题回答都模糊不清
目录
1.在JS中,小数运算是精确的吗?
2.在JS中,整数运算是精确的吗?
3.在JS中,整数的表示是连续的吗?
4.在JS中,能表示的最大数字是多少?
5.在JS中,能表示的数字最大位数是多少?
1.在JS中,小数运算是精确的吗?
答案是不一定的,例如以下情况
console.log(2.2 + 2.1) //输出4.300000000000001
但有时候又是准确的,以下情况
console.log(2.2 + 2.2) //输出4.4
2.在JS中,整数运算是精确的吗?
答案也是不一定的,例如以下情况
console.log(56464613546554564646 + 1) //输出56464613546554565000
通过以上两个问题,给大家一个提醒,在对精度要求很高的系统中,或者要小数的运算结果进行比较时,需要特别谨慎,必要时需要进行四舍五入,保留位数
3.在JS中,整数的表示是连续的吗?
答案也是不一定的,对于大多数开发者在生活中,用到的数字可能是连续的,但要是精确的很高的数字,例如某个数是一千亿,有可能下个数字就是一千亿零一或者一千亿零二,是有可能不连续的
4.在JS中,能表示的最大数字是多少?
最大连续整数:表示从1开始数,能数到的最大连续整数,它所在的前一个数是连续的,下一个数也是连续的,就表示最大连续整数。
在浏览器环境中,表示的最大连续整数可以这样来查看,通过查看全局变量window来获取最大连续整数,在浏览器的调试窗口直接输入以下代码,然后会返回最大连续整数
window.Number.MAX_SAFE_INTEGER //返回9007199254740991
那么在JS中能表示的最大数字是多少呢?
同样是在浏览器的环境下,通过window.Number.MAX_VALUE来查看得知
5.在JS中,能表示的数字最大位数是多少?
在JS中数字能表示的最大位数是不固定的,一般为16~17位,因为表示整数的时候最大为16位,但有可能表示小数的时候为17位,所以是不固定的。
以上问题,你是否认知清楚,如果没有请往下看
在回答以上问题之前,先带大家了解了解二进制
在现实世界中: 十进制,10个数字,逢十进一
在计算机世界中:二进制,2个数字,逢二进一
那么二进制是如何计算的:
二进制转换为十进制,举两个例子 1101和11.01转换为十进制
十进制转换为二进制,同样举个例子 13转换为二进制
13 / 2 商 6 余 1
6 / 2 商 3 余 0
3 / 2 商 1 余 1
1 / 2 商 0 余 1
余数从下往上看
十进制13转换为二进制为-->1101
那么小数转换为二进制呢?请往下看
举个例子3.25 -->
0.25 * 2 0.5 整数部分 : 0
0.5 * 2 1.0 整数部分 : 1
整数部分从上往下看
十进制3.25转换为二进制为-->11.01
小数转换为二进制方法:整数部分同上,小数部分乘2,取小数部分
那么了解二进制后,就可以来回答以上五个问题
为什么JS中小数运算不精确
因为在JS中,十进制的小数,转换成二进制后,可能是无限小数
就比如说十进制的小数0.3转换为二进制为 ------0.0100110011001100....后面是无限位数
0.3*2 0.6 整数部分 : 0
0.6*2 1.2 整数部分 : 1
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
…………
整数部分从上往下看
如何来验证是否是这样的呢,当然可以通过JS中的函数来解决
调用数字中的toString函数,可以转换为二进制,返回结果就是对应的二进制数值
let a = 0.3;
cosnole.log(a.toString(2)); //输出'0.010011001100110011001100110011001100110011001100110011'
后面为啥不写了,因为后面是无限小数,但是计算机的存储能力有限,因此会丢失精度,相当于抛弃一些数据,所以在JS中,小数的存储都是不精确的,才导致小数的相关运算不准确
了解到这些以后,那么又要思考一个问题 JS是怎么存储数字的呢
在JS中,如何存储数字
在计算机标准中,数字存储一般是整数法或者浮点法,但是在神奇的JS中,存储数字的方式都按照浮点法来存储,所以有时候数字运算也是不精确的,因为都是按照小数的方式来存储
那么浮点数是什么 ---浮点数就是使用浮点法存储的数字,可以分为双精度和单精度,在JS中,使用的是双精度来存放浮点数,编号是IEEE 754
JS在计算机中是如何存放数字的
JS在计算机中,给每个数字固定一块内存空间,尺寸固定位64位,例如1,就需要在前面补齐63个0
在计算机中,位(bit)是最小的存储单位,简称位bit
1 byte = 8 bit
1 KB = 1024 byte
1 GB = 1024 MB
那么在计算机中,怎么表示这64位,主要分为三段。类似于
[第一段][第二段][第三段]
第一段 : 1位,表示位号位,如果为1,是负数,如果为0,是正数
第二段 : 11位,表示指数位,这里的指数是值2位底的指数而不是10
第三段 : 52位,表示有效数字
11位的二进制可以表示多个数字
1位 2 2^1
2位 4 2^2
3位 8 2^3
…………
11位 2048 2^11
大多数数字,在JS中都是这样存储的
特殊情况
1.指数为0,尾数为0,表示数字 0
2.指数为2047 ,尾数为0,表示为Infinity
0 1111111111 00000000000....... //-->表示infinity,正无穷
3.符号为1,指数为2047,尾数为0,表示负无穷
0 1111111111 0000000000........ //-->表示-infinity,负无穷
4.指数为2047,尾数不为0,表示NaN
1 11111111111 0100010100….... //-->表示NaN
对于一个正常的数字,指数部分最多为2046
在JS中,能表示的最大数字
那么通过上面方法,那就能得出在JS中的最大数字
0 111111111111110 111111111111..... //1.7976931348623157e+308
在JS中,能表示的最大安全整数
什么是安全整数:从1开始到该数字,均是连续的整数,并且该数字的下一个整数是存在的.
0 xxxxx 11111111111…… //安全整数
那从上面可以得出最大的安全整数为2的52次方 - 1为9007199254740991
从上面的文章中可以得出,在JS中,凡是涉及小数运算,就需要警惕精度丢失,第一次写博客,希望有啥写得不好的,大家能提醒我,共勉