目录
在js中是不区分浮点型和整数型,只要是数字即为number类型。
在计算机中,所有的数据都是以二进制
的形式进行存储。
(小数)十进制转化为二进制
小数十进制转化为二进制采用乘2取整法至值为0或无限循环
为止。
举例说明-> 0.1
将0.1转化为二进制进行存储
0.1*2=0.2 --------0
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
0.4*2=0.8 --------0
0.8*2=1.6 --------1
0.6*2=1.2 --------1
因此0.1转化为二进制为 0.00011 0011 0011 0011 …
举例说明 ->0.2
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
0.4*2=0.8 --------0
0.8*2=1.6 --------1
0.6*2=1.2 --------1
因此0.2转化为二进制为 0.0011 0011 0011 0011 …
小数存储
js中的数字类型相当于其他强类型语言中的double类型,也就是双精度浮点类型。采用64位
二进制数表示一个number类型数据。这64位的二进制数作用如下:
- 符号位:用来表示数字的正负,0为正数,1为负数
- 指数位:一般都用科学计数法表示数值大小,但是这里一般都是2进制的科学计数法,表示2的多少次方
- 小数位:存储小数
举例说明小数存储过程 --> 0.1存储
-
[1] 将0.1转化为2进制
0.1转化为二进制为 0.00011 0011 0011 0011 …
-
[2] 存储小数采用 科学计数法IEEE745标准, 默认所有的该数值都转为
1.xxxxx
这种格式tips:最终所有数据都是1.xxxx ,数据格式统一,因此存储时省略1,这样做可以多存储一位小数!
0.1存储为这种格式为 1.1001 1001 1001 1… * 2 的-4次方
-
[3] 存储过程
-
(1)符号位
正数: 0
-
(2)指数位
指数共占11位, 取值分别为00000000000~11111111111
将中间值 11111111111/2 01111111111作为0
正值++
-1 01111111110
-2 01111111101
…
负值–
1 10000000000
2 10000000001
…0.1的指数位为-4 转化为二进制为01111111011
-
(3)小数位存储:只能存储52位小数位, 因此将小数位保留为52位
注意: 存储过程中类似十进制的四舍五入:
若是末尾为1,则前一位加1,若是末尾为0,则不变
0.1 的小数位为
1001100110011001100110011001100110011001100110011001…
末位进位
1001100110011001100110011001100110011001100110011010
-
最终存储结果为:0011111110111001100110011001100110011001100110011001100110011010
因此小数在存储的时候精度存在丢失的可能
-
小数计算
小数在计算时是将数据转化为对应的
二进制再进行计算
在计算浮点数相加时,需要先进行 “对位”,将较小
的指数化为较大
的指数,并将小数部分相应右移。==> 省略后不要忘记进位哦~
举例说明小数计算 0.1+0.2
0.1转化为二进制为 1.1001 1001 1001 … * 2 的-4次方
0.2转化为二进制为 1.1001 1001 1001 … * 2的-3次方
两者次方不一样先进行对位
0.11001100110011001100110011001100110011001100110011010
1.1001100110011001100110011001100110011001100110011010
结果
10.0110011001100110011001100110011001100110011001100111 0
转化为标准形式
1.0011001100110011001100110011001100110011001100110011 10
保留52位小数
1.0011001100110011001100110011001100110011001100110100
存储
0 01111111011 0011001100110011001100110011001100110011001100110100
小数存储总结
也就是说小数在存储的过程中失去一次精度,在计算的时候又失去一次精度,因此在计算过程中造成结果不准确同时小数位超多;
那么如何解决小数计算时失精的问题呢?
- 可以将小数转化为整数进行计算
- 使用Number的toFixed方法保留固定小数位 (没有小数也会补0)
- 使用插件mathjs解决
mathjs插件
-
下载
npm install mathjs
-
配置
import { create, all } from 'mathjs' const config = { number: 'BigNumber', // 可选值:number BigNumber } const math = create(all, config)
注意若是 number配置项为
BigNumber
可以解决小数失去精度问题,若是值为number
则小数计算仍然失精! -
使用
evaluate
方法解决失精问题math.evaluate(0.1+0.2) // 0.30