0.3-0.2 = 0.09999999999999998 问题解析(精度缺失问题)

写在前面

这个问题其实一直存在,我也看了很多博主写的文章,但是没有一篇文章真的说明白了这个问题,所以今天我尽量将这个问题讲明白,废话不多说,开整

问题表象

研究一下0.3 - 0.2 不等于0.1的问题,做前端时间久的人都避不开精度缺失的问题,今天我们就研究透他,关于0.3 - 0.2 = 0.09999999999999998 这个问题

其实这个问题不是javascript独有的,很多语言都有这个问题,下面是我用不同语言打印出来的0.3 - 0.2 的问题

  • Java
public class HelloWorld {public static void main(String []args) {System.out.println(0.3- 0.2);// 0.09999999999999998}
}
  • Python
#!/usr/bin/python
# Write Python 3 code in this online editor and run it.
print(0.3 - 0.2);
# 0.09999999999999998
  • Swift
/* Write swift code in this online editor and run it. */
var myString = 0.3-0.2
print(myString)
/* 0.09999999999999998*/
  • TS
const hello : number = 0.3 - 0.2
console.log(hello)
// 0.09999999999999998
  • Rust
fn main() {println!("{}",0.3-0.2);  0.09999999999999998
}
问题分析

要解释这个问题其实也不复杂,就是解释一下计算机和不同的语言之间是怎么交流的,我们要明白一件事就是不管语言本身有多高级,表象都是按照语言本身的语法规则进行开发我们认为计算机可以看得懂的逻辑,但是其实本质是这门语言按照他之前定好的规则进行进制的转换,最终转为计算机看得懂的二进制,也就是说计算机本身只认识0和1,这就是为什么说计算机是由0和1组成的,知道了这个本质上面的事情就好解释了,下面我们拿javascript进行展示,

当我们输入0.3给计算机的时候,他会转成二进制,转换结果为:

0.3.toString(2) // 0.010011001100110011001100110011001100110011001100110011

这个时候我们发现他是一个无限循环小数,我们计算机数据交互式先存储,再读取,既然是存储,那么就意味着存储的空间是有限的,那么一个无限循环的小数是不可能一直被存储的,所以计算机只能做一个切断的处理,具体切断多少位呢?这里可以参考IEEE754(国际规定的舍入规则,说人话就是avaScript 中进行浮点数运算时,只有前 15 到 17 位是精确的,超出这个范围的数字可能会出现精度损失), 那么切断之后我们保留小数位数多一点,将他的精度扩大之后可以发现(我们保留17位)

0.2.toPrecision(17) //0.20000000000000001
0.3.toPrecision(17) //0.29999999999999999

看到上面的两个数据,我们所谓的0.3 - 0.2 在计算机里面是 0.29999999999999999 - 0.20000000000000001 = 0.09999999999999998

这就是为什么这个结果值是0.09999999999999998的原因。

为什么不是所有的小数都这样呢?其实这个也很好解释,只要转为二进制之后不是无限循环或者无限不循环的小数都不会有问题,比如0.5 转为二进制之后就是0.1 ,所以他的计算不会出问题

解决办法

js 可以使用第三方库进行处理,比如decimaljs或者BigNumberjs,当然不想引入的话,也可以直接将原始数据放大之后缩小即可,其实本质就是转为整数进行处理,因为整数没有这个问题,比如

(0.3 * 1000 - 0.2 * 1000)/1000 // 0.1

他的运行我们也可以验证

(0.3 * 1000).toPrecision(17) // 300.00000000000000
(0.2 * 1000).toPrecision(17) // 200.00000000000000
(300.00000000000000 - 200.00000000000000) / 1000 // 0.1
问题影响

这个问题其实是一个比较严重的问题,特别是银行行业,我们平常写业务代码的时候不注意这个没关系,因为最后最多就是几分钱的差异,但是任何小事都经不过放大,银行的金额一般都是数量比较大的,所以当一个小的差异就很可能被无限放大,最后就会差别很离谱,所以这个还是需要注意的,上面说了decimaljs是可以处理的,那么看了他的readme文件,大概可以推测出来他其实就是将我们的小数转为了string类型的字符串进行处理,这样可以最大程度保持原始值。所以这个问题还是需要注意的。

decimal.js用法
// 引入CDN https://cdnjs.cloudflare.com/ajax/libs/decimal.js/10.4.3/decimal.min.js
let a =  new Decimal(0.3) 
let b = new Decimal(0.2) 
console.log(a.minus(b).toString()) // 0.1 // 包括加法(plus)、减法(minus)、乘法(times)、除法(div)、乘方(pow)、开方(sqrt)

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

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

相关文章

<软考高项备考>《论文专题 - 45 范围管理(4) 》

5 过程4-创建WBS 5.1 问题 4W1H过程做什么把项目可交付成果和项目工作分解成较小、更易于管理的组件的过程作用:为所要交付的内容提供0架构为什么做WBS代表着项目范围说明书所规定的工作,可以针对WBS 的工作包安排进度,估算成本和实施监控谁…

java SSM体育器材租借管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM体育器材租借管理系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要…

海外服务器2核2G/4G/8G和4核8G配置16M公网带宽优惠价格表

腾讯云海外服务器租用优惠价格表,2核2G10M带宽、2核4G12M、2核8G14M、4核8G16M配置可选,可以选择Linux操作系统或Linux系统,相比较Linux服务器价格要更优惠一些,腾讯云服务器网txyfwq.com分享腾讯云国外服务器租用配置报价&#x…

php-7.1.13的配置文件一览

[PHP] ;;;;;;;;;;;;;;;;;;; ; About php.ini ; ;;;;;;;;;;;;;;;;;;; ; PHP’s initialization file, generally called php.ini, is responsible for ; configuring many of the aspects of PHP’s behavior. ; PHP attempts to find and load this configuration from a num…

GZ075 云计算应用赛题第5套

2023年全国职业院校技能大赛(高职组) “云计算应用”赛项赛卷5 某企业根据自身业务需求,实施数字化转型,规划和建设数字化平台,平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”,拟采用开源OpenSt…

17|回调函数:在AI应用中引入异步通信机制

17|回调函数:在AI应用中引入异步通信机制 回调函数和异步编程 回调函数,你可能并不陌生。它是函数 A 作为参数传给另一个函数 B,然后在函数 B 内部执行函数 A。当函数 B 完成某些操作后,会调用(即“回调”…

如何对APP进行安全加固

引言 如今,移动应用市场蓬勃发展,APP数量呈现爆炸性增长。随着5G技术的广泛应用,APP的增长趋势持续增强。然而,由于APP的泛滥,网络攻击者的目标也在逐渐转移,数亿的移动互联网用户面临着病毒攻击的威胁&am…

计算机毕业设计——SpringBoot 房屋销售租赁平台 房屋购物网站(附源码)

1,绪论 1.1 背景调研 在房地产行业持续火热的当今环境下,房地产行业和互联网行业协同发展,互相促进融合已经成为一种趋势和潮流。本项目实现了在线房产平台的功能,多种技术的灵活运用使得项目具备很好的用户体验感。 这个项目的…

杨中科 ASP.NET MVC

ASP.NET Core 入门 什么是ASP.NET CORE 1、ASP.NET Core是.NET中做Web开发的框架 2、ASP.NET Core MVC 传统MVC项目,前后端都做在一起 3、ASP.NET Core Web API: 前后端分离、多端开发。(是属于MVC中的一部分) 4、ASPNET Core MVC其实包含Web API,不过…

Python入学测试题 江苏某线下培训机构出题

入学测试题 温馨提示:为检测自身的情况,请认真作答,不要进行上网搜答案 1. 实现冒泡排序 for i in range(len(nums)):for j in range(0, len(nums) - i - 1):if nums[j] > nums[j 1]:nums[j], nums[j 1] nums[j 1], nums[j] 2. 二维…

未来十年不变的AI是什么?吴恩达等专家关于2024年AI发展趋势的预测

随着2024年的到来,人工智能领域正迎来前所未有的变革和发展。从深度学习到自然语言处理,AI技术的每一个分支都在经历着快速的进步。在这个关键的时刻,业界专家们提出了对未来趋势的深刻洞察,预测了将形成AI发展主流的关键方向。智…

雍禾医疗以患者为中心 雍禾植发医生文志清专注做精每一台手术

随着生活方式的改变,晚睡、长期使用电子产品等原因让脱发成为消费者不可忽视的问题。有相关数据显示,76%消费者关注自己的头皮健康状况,53%的人群受到脱发困扰,已经有20%消费者认识到专业毛发医疗机构的重要性,选择到专…

V8R6小版本升级步骤(单机环境)

在KingbaseES V8R6版本提供了sys_upgrade的升级工具。 sys_upgade介绍 sys_upgrade实现KingbaseES服务器实例版本升级。 sys_upgrade 允许将存储在KingbaseES数据文件中的数据升级到一个更高的KingbaseES主版本,而无需进行主版本升级(例如从 V8R6C4 到 V8R6C5)通常…

STL——vector详解

目录 💡基本概念 💡存放内置数据类型 💡存放自定义数据类型 💡存放自定义数据类型指针 💡vector容器嵌套容器 💡vector构造函数 💡vector赋值操作 💡vector容量和大小 &…

大数据技术原理与应用期末考试题

大数据技术原理与应用期末考试题 一、单选题 1.下面哪个选项属于大数据技术的“数据存储和管理”技术层面的功能? A、利用分布式文件系统、数据仓库、关系数据库等实现对结构化、半结构化和非结构化海量数据的存储和管理 B、利用分布式并行编程模型和计算框架,结合机器学习…

YOLOv8改进 | 主干篇 | ConvNeXtV2全卷积掩码自编码器网络

一、本文介绍 本文给大家带来的改进机制是ConvNeXtV2网络,ConvNeXt V2是一种新型的卷积神经网络架构,它融合了自监督学习技术和架构改进,特别是加入了全卷积掩码自编码器框架和全局响应归一化(GRN)层。我将其替换YOLOv8的特征提取网络,用于提取更有用的特征。经过我的实…

西电期末1018.logistic方程

一.题目 二.分析与思路 根据题目递归即可&#xff0c;用while函数判断是否到达1000项&#xff0c;内部用abs函数&#xff08;绝对值函数&#xff09;判断是否收敛&#xff0c;最后按照结果输出即可。 三.代码实现 #include<bits/stdc.h>//万能头 int main() {double …

【SI PI 学习路线图】

一、【题干】 SI/PI基本理论 SI/PI经典书籍 软件操作 Hyperlynx Sigrity SIWAVE HFSS Q3D ADS 相关软件Help文档 二、行动路线图 01 1.信号完整性基本概念介绍 2.时域和频域的关系 3.S参数的介绍 4.仿真实例&#xff1a;S参数仿真 平板项目低速信号仿真 02 1.TDR基本概念…

Flink 任务指标监控

目录 状态监控指标 JobManager 指标 TaskManager 指标 Job 指标 资源监控指标 数据流监控指标 任务监控指标 网络监控指标 容错监控指标 数据源监控指标 数据存储监控指标 JobManager 指标 TaskManager 指标 Job 指标 当使用 Apache Flink 进行流处理任务时&…

NLP基础——中文分词

简介 分词是自然语言处理&#xff08;NLP&#xff09;中的一个基本任务&#xff0c;它涉及将连续的文本序列切分成多个有意义的单元&#xff0c;这些单元通常被称为“词”或“tokens”。在英语等使用空格作为自然分隔符的语言中&#xff0c;分词相对简单&#xff0c;因为大部分…