Js中toFixed(2)精度问题的原因及解决办法

2024-02-14 07:20

本文主要是介绍Js中toFixed(2)精度问题的原因及解决办法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    toFixed() 方法可把 Number 四舍五入为指定小数位数的数字。例如将数据Num保留2位小数,则表示为:toFixed(Num);但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规则,银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。具体规则如下:简单来说就是:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。

经测试发现,在chorme下面,并没有完全遵守这个规则,尤其是5的后面没有数字的时候,不是这么判断的,如下:

var b = 1.335b.toFixed(2)"1.33"var b = 1.345b.toFixed(2)"1.34"var b = 1.355b.toFixed(2)"1.35"var b = 1.365b.toFixed(2)"1.36"var b = 1.375b.toFixed(2)"1.38"var b = 1.385b.toFixed(2)"1.39"

可以发现在chorme下没有完全去遵循这个规律,或许它有自己的算法,但是毕竟它没有遵循通用的银行家算法,所以tofixed这个方法在涉及到金钱计算的业务中还是少用.

总而言之:不论引入toFixed解决浮点数计算精度缺失的问题也好,它有没有使用银行家舍入法也罢,都是为了解决精度的问题,但是又离不开二进制浮点数的环境,但至少他帮助我们找到了问题所在,从而让我们有解决方法。

一开始的办法是把要四舍五入的后一位单独拎出来单独判断。

解决方法:

通过重写toFixed方法:

Number.prototype.toFixed = function (n) {let result = number.toString();const arr = result.split('.');const integer = arr[0];const decimal = arr[1];result = integer + '.' + decimal.substr(0, n);const last = decimal.substr(n, 1);

// 四舍五入,转换为整数再处理,避免浮点数精度的损失

if (parseInt(last, 10) >= 5) {const x = Math.pow(10, n);result = ((parseFloat(result) * x) + 1) / x;result = result.toFixed(n);}return result;}

然后又发现计算机二进制编码导致的精度问题,详见上一篇博客。

自己debugger,发现页面中的js进了死循环。很明显问题出在toFixed中回调了toFixed,结果没有走出来,继续debugger,又有了惊人的发现。以下是控制台测试:

console.log(2.115 * 100) // 211.50000000000003console.log(2.0115 * 1000) // 2011.4999999999998

既然你一直进入循环,我就手动把你拉出来。

result = (Math.round((parseFloat(result)) * x) + 1) / x;

最终完整的重写toFixed的方法

// toFixed兼容方法Number.prototype.toFixed = function (n) {if (n > 20 || n < 0) {throw new RangeError('toFixed() digits argument must be between 0 and 20');}const number = this;if (isNaN(number) || number >= Math.pow(10, 21)) {return number.toString();}if (typeof (n) == 'undefined' || n == 0) {return (Math.round(number)).toString();}let result = number.toString();const arr = result.split('.');// 整数的情况if (arr.length < 2) {result += '.';for (let i = 0; i < n; i += 1) {result += '0';}return result;}const integer = arr[0];const decimal = arr[1];if (decimal.length == n) {return result;}if (decimal.length < n) {for (let i = 0; i < n - decimal.length; i += 1) {result += '0';}return result;}result = integer + '.' + decimal.substr(0, n);const last = decimal.substr(n, 1);// 四舍五入,转换为整数再处理,避免浮点数精度的损失if (parseInt(last, 10) >= 5) {const x = Math.pow(10, n);result = (Math.round((parseFloat(result) * x)) + 1) / x;result = result.toFixed(n);}return result;}

这篇关于Js中toFixed(2)精度问题的原因及解决办法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/707864

相关文章

IDEA和GIT关于文件中LF和CRLF问题及解决

《IDEA和GIT关于文件中LF和CRLF问题及解决》文章总结:因IDEA默认使用CRLF换行符导致Shell脚本在Linux运行报错,需在编辑器和Git中统一为LF,通过调整Git的core.aut... 目录问题描述问题思考解决过程总结问题描述项目软件安装shell脚本上git仓库管理,但拉取后,上l

idea npm install很慢问题及解决(nodejs)

《ideanpminstall很慢问题及解决(nodejs)》npm安装速度慢可通过配置国内镜像源(如淘宝)、清理缓存及切换工具解决,建议设置全局镜像(npmconfigsetregistryht... 目录idea npm install很慢(nodejs)配置国内镜像源清理缓存总结idea npm in

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

idea突然报错Malformed \uxxxx encoding问题及解决

《idea突然报错Malformeduxxxxencoding问题及解决》Maven项目在切换Git分支时报错,提示project元素为描述符根元素,解决方法:删除Maven仓库中的resolv... 目www.chinasem.cn录问题解决方式总结问题idea 上的 maven China编程项目突然报错,是

Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题

《Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题》在爬虫工程里,“HTTPS”是绕不开的话题,HTTPS为传输加密提供保护,同时也给爬虫带来证书校验、... 目录一、核心问题与优先级检查(先问三件事)二、基础示例:requests 与证书处理三、高并发选型:

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

在Node.js中使用.env文件管理环境变量的全过程

《在Node.js中使用.env文件管理环境变量的全过程》Node.js应用程序通常依赖于环境变量来管理敏感信息或配置设置,.env文件已经成为一种流行的本地管理这些变量的方法,本文将探讨.env文件... 目录引言为什么使php用 .env 文件 ?如何在 Node.js 中使用 .env 文件最佳实践引

前端导出Excel文件出现乱码或文件损坏问题的解决办法

《前端导出Excel文件出现乱码或文件损坏问题的解决办法》在现代网页应用程序中,前端有时需要与后端进行数据交互,包括下载文件,:本文主要介绍前端导出Excel文件出现乱码或文件损坏问题的解决办法,... 目录1. 检查后端返回的数据格式2. 前端正确处理二进制数据方案 1:直接下载(推荐)方案 2:手动构造

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

Python绘制TSP、VRP问题求解结果图全过程

《Python绘制TSP、VRP问题求解结果图全过程》本文介绍用Python绘制TSP和VRP问题的静态与动态结果图,静态图展示路径,动态图通过matplotlib.animation模块实现动画效果... 目录一、静态图二、动态图总结【代码】python绘制TSP、VRP问题求解结果图(包含静态图与动态图