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…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
