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.3
    console.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! 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

“可信区块链运行监测服务平台TBM发展研讨会”将于11月23日在北京召开

为推动区块链治理与创新&#xff0c;积极推进信任科技生态体系建设&#xff0c;中国信息通信研究院、中国移动设计院联合区块链服务网络&#xff08;BSN&#xff09;发展联盟共同发起建立了可信区块链运行监测服务平台&#xff08;TBM&#xff09;。 TBM平台通过对区块链系统的…

requests爬虫IP连接初始化问题及解决方案

问题背景 在使用HTTPS爬虫IP连接时&#xff0c;如果第一次请求是chunked方式&#xff0c;那么HTTPS爬虫IP连接将不会被初始化。这个问题可能会导致403错误&#xff0c;或者在使用HTTPS爬虫IP时出现SSL错误。 解决方案 为了解决这个问题&#xff0c;我们可以在requests库的ada…

vue项目本地开发完成后部署到服务器后报404

vue项目本地开发完成后部署到服务器后报404是什么原因呢&#xff1f; 一、如何部署 前后端分离开发模式下&#xff0c;前后端是独立布署的&#xff0c;前端只需要将最后的构建物上传至目标服务器的web容器指定的静态目录下即可 我们知道vue项目在构建后&#xff0c;是生成一系…

仿真2.0 - 引入生成式AI

仿真模型是物理对象、系统或过程的虚拟表示&#xff0c;可预测其在不同场景中的行为和性能。 如今&#xff0c;仿真模型广泛应用于各行各业&#xff0c;以优化流程、为决策提供信息并创建数字孪生。 几十年来&#xff0c;仿真模型一直被用来对复杂的系统和过程进行建模。 这些…

interview review

M: gamma correction 人眼和相机对强度的变化敏感程序不一样, 人对暗部更敏感. 上面一条人眼觉得是均匀, 下面一条是相机真实的均匀. 人眼觉得的中间值 在相机中是21.8%, 为了让灰度的分布更符合人眼, 我们需要对图片进行gamma校正, 使得各用128个数字来表示相机真实世界中…

CentOS Linux release 7.9.2009 (Core)中安装配置Tomcat

一、安装JDK 部分内容可以参考我这篇文章&#xff1a;Windows11与CentOS7下配置与检测JDK与Maven环境变量 中的 2.2 安装jdk-8u371-linux-x64.tar.gz和配置环境变量/etc/profile //1、安装redhat-lsb yum install -y redhat-lsb//2、查看系统版本信息 lsb_release -a //3、查…

.NET 8.0 中有哪些新的变化?

1性能提升 .NET 8在整个堆栈中带来了数千项性能改进 。默认情况下会启用一种名为动态配置文件引导优化 (PGO) 的新代码生成器&#xff0c;它可以根据实际使用情况优化代码&#xff0c;并且可以将应用程序的性能提高高达 20%。现在支持的 AVX-512 指令集能够对 512 位数据向量执…

java:springboot单元测试spring-boot-starter-test

背景 Java的单元测试可以使用多个框架&#xff0c;其中比较流行的包括&#xff1a; JUnit&#xff1a;JUnit是Java单元测试最常用的框架&#xff0c;它提供了一套丰富的API&#xff0c;可以方便地编写测试用例和测试套件。JUnit 5是JUnit的最新版本&#xff0c;引入了许多新功…

汽车ECU的虚拟化技术初探(三)--U2A虚拟化辅助功能分析1

目录 1.基本概述 1.1 U2A虚拟化辅助功能 1.2 U2A虚拟化使能和资源分配 2. U2A架构概述 3. CPU运行模式 3.1 虚拟化模式 3.2 限制运行模式 3.3 权限运行模式 3.4 CPU运行模式小结 4.小结 1.基本概述 1.1 U2A虚拟化辅助功能 在汽车ECU的虚拟化技术初探(二)-CSDN博客中…

Boolean源码解剖学

原创/朱季谦 有天突发其想&#xff0c;想看一下Boolean底层都做了些什么&#xff0c;故而去看了一番Boolean的源码&#xff0c;基于一些思考的基础上&#xff0c;输出了这篇文章。 一.类继承 Boolean的源码类定义部分如下&#xff1a; 1 public final class Boolean implemen…

初学Redis(Redis的启动以及字符串String)

首先使用在Windows PowerShell中输入指令来启动Redis&#xff1a; redis-server.exe 然后通过指令连接Redis&#xff1a; redis-cli 上图的127.0.0.1是计算机的回送地址 &#xff0c;6379是默认端口 上述代码中创建了两个键&#xff0c;注意Redis中严格区分大小写&#xff0…

策略模式在数据接收和发送场景的应用(升级版)

1.背景 在数据接收和发送场景打算使用了 if else 进行判断&#xff1a; if("A".equals(system)){ASystem.sync("向A同步数据"); } if("B".equals(system)){BSystem.sync("向B同步数据"); } ... 非常麻烦&#xff0c;需求多了很臃肿&…

phpStorm Xdebug调试 加FireFox浏览器

步骤1&#xff1a; [Xdebug] zend_extension“D:\phpstudy_pro\Extensions\php\php5.4.45nts\ext\php_xdebug.dll” xdebug.collect_params1 xdebug.collect_return1 xdebug.remote_enableOn xdebug.remote_hostlocalhost xdebug.remote_port9001 xdebug.remote_handlerdbgp ;…

什么是Sectigo SSL证书

Sectigo SSL证书是由全球领先的网络安全公司Comodo和Symantec合并后成立的Sectigo公司所提供的一种数字证书。它能够为您的网站提供一个强大的安全套接字层&#xff08;SSL&#xff09;加密&#xff0c;确保您的网站与用户的数据传输过程中的安全性。 为什么选择Sectigo SSL证…

Django学习日志07

多表查询&#xff08;跨表查询&#xff09; 子查询&#xff1a;分步查询 链表查询&#xff1a;把多个有关系的表拼接成一个大表(虚拟表) inner join left join 展示左表所有数据数据&#xff0c;右表展示符合查询条件的数据&#xff0c;查询不到的用null填充 …

Flume学习笔记(2)—— Flume进阶

Flume进阶 Flume 事务 事务处理流程如下&#xff1a; Put doPut&#xff1a;将批数据先写入临时缓冲区putListdoCommit&#xff1a;检查channel内存队列是否足够合并。doRollback&#xff1a;channel内存队列空间不足&#xff0c;回滚数据 Take doTake&#xff1a;将数据取…

笔记54:门控循环单元 GRU

本地笔记地址&#xff1a;D:\work_file\DeepLearning_Learning\03_个人笔记\3.循环神经网络\第9章&#xff1a;动手学深度学习~现代循环神经网络 a a a a a a a

802.1Qbb

[TOC] 802.1Qbb 802.1Qbb是什么&#xff1f; 802.1Qbb&#xff08;基于优先级的流控制&#xff0c;PFC&#xff09;是以太网数据中心中一项重要的标准&#xff0c;用于提供无丢包的网络环境。这项标准是IEEE 802.1Q标准的一部分&#xff0c;旨在解决以太网数据中心网络中的拥…

基于共生生物算法优化概率神经网络PNN的分类预测 - 附代码

基于共生生物算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于共生生物算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于共生生物优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

C++语言的由来与发展历程

C语言的由来与发展历程可以追溯到1978年&#xff0c;当时美国电话电报公司&#xff08;AT&T&#xff09;的贝尔实验室发明了C语言&#xff0c;以满足UNIX操作系统的开发需求。在C语言的基础上&#xff0c;Bjarne Stroustrup于1983年创立了C编程语言&#xff0c;作为C语言的…