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() 函数可以将浮点数四舍五入到指定的小数位数,并返回一个字符串表示的结果。
-
- + 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!
相关文章:
JavaScript 浮点数运算的精度问题及解决
JavaScript 浮点数运算的精度问题及解决 在 JavaScript 中整数和浮点数都属于 Number 数据类型,当浮点数做数学运算的时候,你经常会发现一些问题,举几个例子: 0.1 0.2 0.30000000000000004 console.log(0.1 0.2) 0.3000000…...
基于STM32的无线传感器网络(WSN)通信方案设计与实现
无线传感器网络(Wireless Sensor Network,简称WSN)是由一组分布式的无线传感器节点组成的网络,用于监测和收集环境中的各类物理信息。本文将基于STM32微控制器,设计并实现一个简单的无线传感器网络通信方案,…...
Flink和Kafka连接时的精确一次保证
Flink写入Kafka两阶段提交 端到端的 exactly-once(精准一次) kafka -> Flink -> kafka 1)输入端 输入数据源端的 Kafka 可以对数据进行持久化保存,并可以重置偏移量(offset) 2)Flink内…...
UE4动作游戏实例RPG Action解析三:实现效果,三连击Combo,射线检测,显示血条,火球术
一、三连Combo 实现武器三连击,要求: 1.下一段Combo可以随机选择, 2.在一定的时机才能再次检测输入 3. 等当前片段播放完才播放下一片段 1.1、蒙太奇设置 通过右键-新建蒙太奇片段,在蒙太奇里创建三个片段,并且移除相关连接,这样默认只会播放第一个片段 不同片段播…...
Linux/麒麟系统上部署Vue+SpringBoot前后端分离项目
目录 1. 前端准备工作 1.1 在项目根目录创建两份环境配置文件 1.2 环境配置 2. 后端准备工作 2.1 在项目resources目录创建两份环境配置文件 2.2 环境配置 3. 前后端打包 3.1 前端打包 3.2 后端打包 4、服务器前后端配置及部署 4.1 下载、安装、启动Nginx 4.2 前端项目部署…...
STM32在FreeRTOS下的us延时
STM32在FreeRTOS下的us延时 前言 freeRTOS下跑SPI时需要微秒级别的延时,但是freeRTOS只提供了毫秒级的,记录一下实现us延时的方法。 前期分析 最简单的方式就是开个定时器或者干脆直接计算一下用nop做都可以实现us延时,但是显然还是使用滴…...
软件测试/人工智能丨深入人工智能软件测试:PyTorch引领新时代
在人工智能的浪潮中,软件测试的角色变得愈发关键。本文将介绍在人工智能软件测试中的一些关键技术,以及如何借助PyTorch深度学习框架来推动测试的创新与升级。 PyTorch:深度学习的引擎 PyTorch作为一种开源的深度学习框架,为软件…...
Android 当中的 Fragment 协作解耦方式
Android 当中的 Fragment 协作解耦方式 文章目录 Android 当中的 Fragment 协作解耦方式第一章 前言介绍第01节 遇到的问题第02节 绘图说明 第二章 核心代码第01节 代理人接口第02节 中间人 Activity第03节 开发者A第04节 开发者B第05节 测试类 第一章 前言介绍 第01节 遇到的…...
城市网吧视频智能监控方案,实现视频远程集中监控
网吧环境较为复杂,电脑设备众多且人员流动性大,极易发生人员或消防事故,亟需改变,TSINGSEE青犀AI智能网吧视频监管方案可以帮助实现对网吧环境和用户活动的实时监控和管理。 1、视频监控系统 在网吧内部布置高清摄像头࿰…...
C#WPF视频播放器实例
本文实例演示C#WPF视频播放器 实例如下: 修改mainwindow的代码 <Windowx:Class="PlayerDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xml…...
【uniapp】Google Maps
话不多说 直接上干货 提前申请谷歌地图账号一、新建地图 使用h5获取当前定位或者使用三方uniapp插件 var coords ""navigator.geolocation.getCurrentPosition(function(position) {coords {lat: position.coords.latitude,lng: position.coords.longitude};lats …...
C语言变量与常量
跟着肯哥(不是我)学C语言的变量和常量、跨文件访问、栈空间 栈空间还不清楚,期待明天的课程内容 C变量 变量(Variable)是用于存储和表示数据值的名称。 主要包括四个环节:定义、初始化、声明、使用 在我刚…...
AI创作系统ChatGPT网站源码/支持DALL-E3文生图/支持最新GPT-4-Turbo模型+Prompt应用
一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…...
二维码智慧门牌管理系统升级,异常门牌聚合解决方案助力高效管理
文章目录 前言一、异常门牌聚合解决方案 前言 在今天的数字化时代,智慧城市已成为发展趋势,其中二维码智慧门牌管理系统扮演着至关重要的角色。通过对门牌信息进行数字化管理,该系统极大提升了城市管理的效率和便捷性。然而,随着…...
【XTDrone Ubuntu20.04】XTDrone+ Ubuntu20.04 + PX4安装
XTDrone仿真平台配置 文章目录 XTDrone仿真平台配置依赖安装 ROS一键安装Marvos安装PX4 安装安装QTGroundControlXTDrone下载安装 环境: VMWare 16.0 Ubuntu 22.04 (因为没人配过)Ubuntu 20.04 参考文章: 仿真平台基础配置 (yuq…...
河北大学选择ZStack Cube超融合一体机打造实训云平台
河北大学通过云轴科技ZStack Cube超融合一体机构建校园实训云平台,部署测试仅耗时1天,该平台能够更快地为学生提供高性能、高可用的云主机、云存储和云网络服务;同时也能满足日常运维管理要求,为学生提供更好的实训环境。 河北省…...
IDEA远程一键部署SpringBoot到Docker
IDEA是Java开发利器,Spring Boot是Java生态中最流行的微服务框架,docker是时下最火的容器技术,那么它们结合在一起会产生什么化学反应呢? 一、开发前准备 1. Docker安装 可以参考:https://docs.docker.com/install/ 2…...
索引三星结构
三星索引的定义,可以先给我们对索引优化提供一个大概的思路: 满足第1颗星: 取出所有的等值谓词的列,作为索引最开头的列——以任意顺序都可以。 满足第2颗星: 将order by加入到索引列,不要改变这些列的顺…...
rust 笔记 高级错误处理
文章目录 错误处理组合器or() 和 and()or_else() 和 and_then()filtermap() 和 map_err()map_or() 和 map_or_else()ok_or() and ok_or_else() 自定义错误类型错误转换 From 特征 归一化不同的错误类型Box<dyn Error>自定义错误类型 简化错误处理thiserroranyhow 错误处理…...
python+Django 使用apscheduler实现定时任务 管理调度
apscheduler实现定时任务 管理调度 在Django 项目中经常会用到定时任务去处理一些业务处理 使用 APScheduler 可以轻松地实现定时任务的管理和调度。你可以通过以下步骤来创建、启动、停止和删除定时任务: 1.创建调度器对象: from apscheduler.schedu…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
