js使用toFixed遇到的问题以及由此引发的小数精度问题

摘要:
原文链接:https://www.cnblogs.com/yalong/p/15762637.html项目中使用toFixed出现的问题:一.js报错UncaughtSyntaxError:Invalidorunexpectedtoken如下图所示:就是说对整数和字符串使用toFixed()会报错二.四舍五入不正确1.335.toFixed(2)//输出1.33四舍五入的问题在谷歌、火狐浏览器下都

原文链接: https://www.cnblogs.com/yalong/p/15762637.html

项目中使用 toFixed 出现的问题:

一. js报错 Uncaught SyntaxError: Invalid or unexpected token

如下图所示:

js使用toFixed遇到的问题以及由此引发的小数精度问题第1张

就是说对 整数 和 字符串 使用toFixed() 会报错

二. 四舍五入不正确

1.335.toFixed(2) // 输出 1.33

四舍五入的问题在谷歌、火狐浏览器下都存在,ie浏览器下正常

三. 偶尔数字出现特别长的情况,如下图所示:

js使用toFixed遇到的问题以及由此引发的小数精度问题第2张

问题分析

问题一其实是toFixed的使用问题

x.toFixed(n) 方法可把 Number类型的数字x 四舍五入为指定小数位数的数字, n为保留的小数位数,并且返回的结果是字符串类型

注意这里x 必须为数字Number类型,如果用字符串的话报错

3.toFixed(2) 也会报错,原因是js引擎在运行的时候,默认将3后面的那个点认为是小数点,所以3.toFixed()也就相当于3.0toFixed(), 所以报错

解决方法如下:
  1. 多加一个点: 3..toFixed(2) // 输出 3.00
  2. 把数字存一个变量上
let num = 3
num.toFixed(2) // 输出 3.00
  1. 用括号: (3).toFixed(2) // 输出 3.00

问题二是浏览器本身toFixed() 的计算有问题

解决办法可以重写浏览器的toFixed()函数,写法网上很多就不多介绍了

问题三的本质是js小数的精度问题

看下面的示例:

// 加法 =====================
0.1 + 0.2 = 0.30000000000000004
0.7 + 0.1 = 0.7999999999999999
0.2 + 0.4 = 0.6000000000000001

// 减法 =====================
1.5 - 1.2 = 0.30000000000000004
0.3 - 0.2 = 0.09999999999999998
 
// 乘法 =====================
19.9 * 100 = 1989.9999999999998
0.8 * 3 = 2.4000000000000004

// 除法 =====================
0.3 / 0.1 = 2.9999999999999996
0.69 / 10 = 0.06899999999999999

这个问题的原因简单来说就是计算机计算的时候,会先把10进制的小数转为2进制的机器编码,然后使用二进制的编码进行计算,最后再把二进制的结果转为10进制。

10进制小数转2进制小数的过程如下:

十进制的小数转换为二进制小数,主要是利用小数部分乘2,取整数部分,直至小数点后为0

以0.625为例, 如下图所示:

js使用toFixed遇到的问题以及由此引发的小数精度问题第3张

js使用toFixed遇到的问题以及由此引发的小数精度问题第4张

十进制的 0.625 转为二进制 就是 0.101

但是有些小数转为二进制的时候,最后一位永远不会是0,然后就变成"无限长度"的了
看下面例子:

0.1 + 0.2 = 0.30000000000000004

把0.1 和 0.2 转成二进制如下:

0.1 -> 0.0001100110011001...(无限)
0.2 -> 0.0011001100110011...(无限)

IEEE 754 标准的 64 位双精度浮点数的小数部分最多支持 53 位二进制位,所以两者相加之后得到二进制为:

0.0100110011001100110011001100110011001100110011001100 

因浮点数小数位的限制而截断的二进制数字,再转换为十进制,就成了 0.30000000000000004。
误差就是这么出现了

总结

浏览器的toFixed() 存在的问题如下:

  1. 四舍五入不准确,并且在不同浏览器下也存在差异
  2. 有时会出现小数的精度特别长的情况,当然这个的本质其实是小数的精度问题

对于以上的问题,可以把toFixed() 方法重写了, 也可以使用别人的轮子,比如: bignumber

参考链接:
https://www.cnblogs.com/chyshy/p/14745284.html

https://www.cnblogs.com/bettermu/p/8532460.html

https://juejin.cn/post/6844903572979597319

https://jingyan.baidu.com/article/eb9f7b6dc692e9c79264e878.html

免责声明:文章转载自《js使用toFixed遇到的问题以及由此引发的小数精度问题》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇将 DNSCrypt 部署到 Openwrt 路由器上+ DNSmasq 解析国内域名用本地 DNS[ZT+实践]微信小程序自定义组件笔记-组件模板和样式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

js/jquery如何获取获取父窗口的父窗口的元素

取父窗口的元素方法:$(selector, window.parent.document);那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent.parent.document);类似的,取其它窗口的方法大同小异 1 $(selector, window.top.document); 2 $(selector, wind...

JS解析XML文件和XML字符串

详细内容请点击 JS解析XML文件 复制代码<script type='text/javascript'>loadXML = function(xmlFile){var xmlDoc=null;//判断浏览器的类型//支持IE浏览器if(!window.DOMParser && window.ActiveXObject){var...

SonarQube部署及代码质量扫描入门教程

一、前言 1、本文主要内容 CentOS7下SonarQube部署 Maven扫描Java项目并将扫描结果提交到SonarQube Server SonarQube扫描报表介绍 2、环境信息 工具/环境 版本 CentOS CentOS 7.6(IP:192.168.88.45) SonarQube 7.5 JDK 1.8.0 M...

【转】二维码生成原理

原文链接:QR码生成原理-QR Code(ISO 18004)编码方式 一、什么是QR码 QR码属于矩阵式二维码中的一个种类,由DENSO(日本电装)公司开发,由JIS和ISO将其标准化。QR码的样子其实在很多场合已经能够被看到了,我这还是贴个图展示一下: 这个图如果被正确解码,应该看到我的名字和邮箱。 二、QR码的特点 说到QR码的特点: 一是高速读取...

iframe用js设定自定义高度

JS代码 functionSetWinHeight(obj){ var win=obj; if(document.getElementById){ if (win && !window.opera){ if (win.contentDocument &&win....

好消息,又有400多个组件支持鸿蒙了!

众所周知,HarmonyOS目前提供16000多个API。然而在API之外,我们还提供一系列组件库供开发者使用。组件库有助于降低应用开发者的开发难度,提升开发效率,让应用开发更简单高效。 目前,HarmonyOS组件库在Git上可以直接获取,组件不断扩增中,期待大家持续关注支持。 那么HarmonyOS组件库到底是什么,下面就让我们从五个方面来介绍吧~ H...