JavaScript 浮点数运算的精度问题及解决

JavaScript 浮点数运算的精度问题及解决

在 JavaScript 中整数和浮点数都属于 Number 数据类型,当浮点数做数学运算的时候,你经常会发现一些问题,举几个例子:

0.1 + 0.2 = 0.30000000000000004

console.log(0.1 + 0.2) = 0.30000000000000004

1.5 - 1.2 = 0.30000000000000004

19.9 * 100 = 1989.9999999999998

0.3 / 0.1 = 2.9999999999999996

参见下图:

怎么回事?JavaScript 算错了吗?

不是错误,原因在于浮点数(Floating-point Number)是对实数的一种近似表示。

这个问题并不只是在 Javascript 中才会出现,几乎所有的编程语言都采用了 IEEE-754 浮点数表示法,下面是Python语言的情况:

关于IEEE754浮点更多情况可见:IEEE754浮点表示小结 https://zhuanlan.zhihu.com/p/615232196

在此我们不展开介绍,而主要介绍JavaScript中如何应对这种情况,这里给出一些解决方案。

使用一些第三方库,如 Decimal.js 等,提供了更高精度的浮点数运算功能。这些库可以处理更复杂的运算,并提供更高的精度。

当你在浏览器环境中使用 Decimal.js 库时,你可以按照以下步骤进行操作:

下载 Decimal.js 库文件。你可以在 Decimal.js 的官方网站(文档:https://mikemcl.github.io/decimal.js/ 下载:https://github.com/MikeMcl/decimal.js )上找到下载链接。

将下载的 Decimal.js 文件保存到你的项目中的合适位置。

在你的 HTML 文件中添加以下代码来引入 Decimal.js 库:

<script src="path/to/decimal.js"></script>

确保将 path/to/decimal.js 替换为实际的文件路径。

使用 <script> 标签引入 Decimal.js 库文件的在线版本:

<script src="https://cdnjs.cloudflare.com/ajax/libs/decimal.js/10.2.1/decimal.min.js"></script>

使用在线版本方便一些,但不能断网

在你的 JavaScript 代码中,你可以使用 Decimal 对象来执行精确的数学运算。以下是一个简单的例子:

<!DOCTYPE html>
<html>
<head><script src="https://cdnjs.cloudflare.com/ajax/libs/decimal.js/10.2.1/decimal.min.js"></script>
</head>
<body><script>// 创建 Decimal 对象var num1 = new Decimal(0.1);var num2 = new Decimal(0.2);// 执行数学运算var sum = num1.plus(num2);var product = num1.times(num2);// 打印结果console.log(sum.toString()); // 输出: 0.3console.log(product.toString()); // 输出: 0.02</script>
</body>
</html>

在这个例子中,我们首先引入了 Decimal.js 库。然后,我们创建了两个 Decimal 对象 num1 和 num2,并使用 plus 方法计算它们的和,使用 times 方法计算它们的乘积。最后,我们使用 toString 方法将结果转换为字符串并打印出来。

这样在浏览器环境中使用Decimal.js等库进行精确的数学运算,有点麻烦,也可以使用一些技巧来处理浮点数运算。下面介绍这些技巧。

☆将浮点数转换为整数进行运算,然后再将结果转换回浮点数。例如,使用整数运算:将浮点数转换为整数进行运算,然后再将结果转换回浮点数。例如,可以将浮点数乘以一个较大的倍数,进行整数运算,然后再除以相同的倍数,得到最终结果。

(0.1 * 10 + 0.2 * 10) / 10;  //输出 0.3

☆使用 JavaScript 的内置函数 toFixed() 来控制浮点数的小数位数。这个函数会将浮点数四舍五入到指定的小数位数,并返回一个字符串表示的结果。

使用内置函数toFixed():toFixed() 函数可以将浮点数四舍五入到指定的小数位数,并返回一个字符串表示的结果。

    1. + 0.2).toFixed(1);  //输出'0.3'

最后,给出一个有点意思的例子

实现自动出题(加减乘除)四则运算的并能判断用户输入答案对错,效果图如下:

HTML网页文件源码:

<!DOCTYPE html>
<html>
<head><title>四则运算自动出题</title><script>//generateQuestion() 函数用于生成一个数学问题function generateQuestion() {var num1 = Math.floor(Math.random() * 10) + 1;var num2 = Math.floor(Math.random() * 10) + 1;var operator = Math.floor(Math.random() * 4); // 0: +, 1: -, 2: *, 3: /var question;var answer;switch (operator) {case 0:question = num1 + " + " + num2;answer = num1 + num2;break;case 1:question = num1 + " - " + num2;answer = num1 - num2;break;case 2:question = num1 + " * " + num2;answer = num1 * num2;break;case 3:question = num1 + " / " + num2;//answer = num1 / num2;answer = (num1 / num2).toFixed(2);  //保留两位小数break;}document.getElementById("question").innerHTML = question;document.getElementById("answer").value = "";  //用户回答用document.getElementById("result").innerHTML = "";document.getElementById("correctAnswer").value = answer; //正确答案存储在隐藏的输入框中}//checkAnswer() 函数用于检查用户输入的答案是否正确。function checkAnswer() {var userAnswer = parseFloat(document.getElementById("answer").value);var correctAnswer = parseFloat(document.getElementById("correctAnswer").value);var result;if (userAnswer === correctAnswer) {result = "回答正确!";} else {result = "回答错误!正确答案是 " + correctAnswer;}document.getElementById("result").innerHTML = result;}</script>
</head>
<body><h1>四则运算题目</h1><p>实现自动出题(加减乘除)四则运算的并能判断用户输入答案对错,除法结果保留两位小数</p><p>用户可以点击下一题按钮生成新的题目。每次点击下一题按钮时,JavaScript代码会生成新的题目</p><p id="question"></p><input type="number" id="answer" placeholder="请输入答案"><button onclick="checkAnswer()">提交</button><button onclick="generateQuestion()">下一题</button><p id="result"></p><input type="hidden" id="correctAnswer"><script>generateQuestion();</script>
</body>
</html>

OK! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/189357.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云服务器4核8G配置有哪些?多少钱一年?

腾讯云服务器4核8G配置优惠价格表&#xff0c;轻量应用服务器和CVM云服务器均有活动&#xff0c;云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元&#xff0c;5年6490.44元&#xff0c;轻量应用服务器4核8G12M带宽一年446元、529元15个月&#xff0c;腾讯云百科txybk.com分…

mac苹果笔记本应用程序在哪?有什么快捷方式吗?

苹果笔记本电脑一直以来都被广泛使用&#xff0c;而苹果的操作系统 macOS 也非常受欢迎。一台好的笔记本电脑不仅仅依赖于硬件配置&#xff0c;还需要丰富多样的应用程序来满足用户的需求。苹果笔记本应用程序在哪&#xff0c;不少mac新手用户会有这个疑问。在这篇文章中&#…

033、微调

之——高级炼丹术 目录 之——高级炼丹术 杂谈 正文 1.标注数据集是很贵的 2.微调的思想 3.尝试 小结 杂谈 微调&#xff08;Fine-tuning&#xff09;是深度学习中的一种常见策略&#xff0c;它通常用于预训练模型在特定任务上的性能提升。微调的过程涉及在一个已经在大…

二维码智慧门牌管理系统升级,异常门牌聚合解决方案助力高效管理

文章目录 前言一、异常门牌聚合解决方案 前言 在今天的数字化时代&#xff0c;智慧城市已成为发展趋势&#xff0c;其中二维码智慧门牌管理系统扮演着至关重要的角色。通过对门牌信息进行数字化管理&#xff0c;该系统极大提升了城市管理的效率和便捷性。然而&#xff0c;随着…

11月最新版付费进群源码自动定位+开源

感觉这个和前几天发布的付费进群差不多。 但有部分地方不一样&#xff0c;也是有什么分销分站后台&#xff0c;看见就头大。 没测试具体功能&#xff0c;可以搭建出来&#xff0c;D盾也未检测到加密文件 更多源码请到www.baicxx.com

html-网站菜单-点击显示导航栏

一、效果图 1.点击显示菜单栏&#xff0c;点击x号关闭&#xff1b; 2.点击一级菜单&#xff0c;展开显示二级&#xff0c;并且加号变为减号&#xff1b; 3.点击其他一级导航&#xff0c;自动收起展开的导航。 二、代码实现 <!DOCTYPE html> <html><head>&…

商业化三年,OceanBase在忙什么?

文&#xff5c;刘雨琦 2020年&#xff0c;国产数据库厂商OceanBase&#xff08;以下简称OB&#xff09;商业化的第一年&#xff0c;只有18个客户。 如何打开局面&#xff0c;让这个从蚂蚁场景中走出来的数据库活下去&#xff0c;并进入到更多的场景里&#xff0c;发挥更大的价…

【算法】距离(最近公共祖先节点)

题目 给出 n 个点的一棵树&#xff0c;多次询问两点之间的最短距离。 注意&#xff1a; 边是无向的。所有节点的编号是 1,2,…,n。 输入格式 第一行为两个整数 n 和 m。n 表示点数&#xff0c;m 表示询问次数&#xff1b; 下来 n−1 行&#xff0c;每行三个整数 x,y,k&am…

农户建档管理系统的设计与实现-计算机毕业设计源码20835

摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xff0c;采用Java技术建设农户建档管理系统。 本…

Apache Airflow (十) :SSHOperator及调度远程Shell脚本

&#x1f3e1; 个人主页&#xff1a;IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 &#x1f6a9; 私聊博主&#xff1a;加入大数据技术讨论群聊&#xff0c;获取更多大数据资料。 &#x1f514; 博主个人B栈地址&#xff1a;豹哥教你大数据的个人空间-豹…

【计算机网络笔记】ICMP(互联网控制报文协议)

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

Vmware虚拟机创建快照、克隆和备份 创建文件夹共享方法

Vmware虚拟机备份 方法一&#xff1a;虚拟机快照备份 虚拟机 快照备份 像是Windows系统里的系统 还原点 功能&#xff0c;它能拍摄一张您虚拟机当前的状态&#xff0c;并将其保存起来&#xff0c;您可以随时通过恢复到快照功能将虚拟机还原到拍摄快照时的状态。 步骤1. 打开…