js速记--数值精度问题

133 阅读2分钟

在使用js进行数值计算是,有时候会有精度丢失问题,比如计算小数时:

image.png

整数计算精度丢失,一般是由于数值太大了,转二进制后超出了整数的最大位数; 小数计算精度丢失,一般是由于小数转二进制,长度超出了最大存储长度;

一、小数精度丢失原因

出现精度丢失,简单说就是因为计算机是二进制,而计算的是十进制的数字,而计算机存储二进制的容量又有限,有时候不能表示一个精准的十进制数。

1、十进制转二进制

整数部分:

整数部分除2取余,直到被除数为0,将余数倒过来

例子:将十进制4转为二进制

image.png

得到的余数是 0、0、1,倒过来就是 '100',就是二进制的4

小数部分: 小数部分乘2取整,知道小数部分为0

例子:将十进制0.25转为二进制

image.png

所以转为二进制后的小数部分就是 '01'

2、二进制转十进制

依次取每位的值,乘以权重,然后求和

例子:求二进制数 100.01的十进制数

image.png

3、精度问题分析

还是用 0.1 + 0.2这个问题看,0.1转为二进制,会得出0.0001100011...,是一个无限循环的,那么问题来了,电脑该怎么保存呢?答案就是取一个近似值,所以0.1在电脑中存储的是一个近似值,那么计算的结果必然会出现精度丢失了

二、整数精度丢失原因

js中存储数字采用的是双进度存储,总共64位:

  • 1个符号位
  • 11个指数位
  • 52个尾数位

所以理论上来说,能保存最大整数应该为: 2^52 + 2^51 + 2^50 + ... + 2^0

js中存在一个常量,保存这个值:Number.MAX_SAFE_INTEGER,值为9007199254740991

当存储的整数大于这个值时,就会出问题了,我在最大值后面加了个1

image.png

如果超过最大值后,进行计算,也会出问题

  • 其实上面的小数精度问题,也是一样的,超出了最大位数了

二、解决方案

  • 将数字转为字符串,然后进行操作
  • 小数计算精度问题,可以将小数转为整数后再计算,计算完成后再转回小数
  • 整数问题,可以使用bigint类型
  • 使用第三方库:bigNumber、number-precision