0.1+0.2 为什么不等于0.3

程序里为什么0.1+0.2不等于0.3? 为什么0.1+0.2不等于0.30.1+0.2新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 0.1+0.2 程序里面0.1+0.2=0.30000000000000004 你好! 这是你第一次使用 Markdown编辑器 阅读详情

目录

一、0.1+0.2的计算过程

1.十进制转成二进制

2.转成浮点数

3.浮点数相加

4.浮点数转成十进制

二、答案

三、拓展


一、0.1+0.2的计算过程

1.十进制转成二进制

在JS内部所有的计算都是以二进制方式计算的。 所以运算 0.1+ 0.2 时要先把 0.1和 0.2 从十进制转成二进制。

  • 0.1转化成二进制的算法:
    0.1*2=0.2======取出整数部分0
    0.2*2=0.4======取出整数部分0
    0.4*2=0.8======取出整数部分0
    0.8*2=1.6======取出整数部分1
    0.6*2=1.2======取出整数部分1
    接下来会无限循环
    0.2*2=0.4======取出整数部分0
    0.4*2=0.8======取出整数部分0
    0.8*2=1.6======取出整数部分1
    0.6*2=1.2======取出整数部分1
    所以0.1转化成二进制是:0.0001 1001 1001 1001......
  • 0.2转化成二进制的算法:
    0.2*2=0.4======取出整数部分0
    0.4*2=0.8======取出整数部分0
    0.8*2=1.6======取出整数部分1
    0.6*2=1.2======取出整数部分1
    接下来会无限循环
    0.2*2=0.4======取出整数部分0
    0.4*2=0.8======取出整数部分0
    0.8*2=1.6======取出整数部分1
    0.6*2=1.2======取出整数部分1
    所以0.2转化成二进制是:0.0011 0011 0011 0011......

这里要注意 0.1 和 0.2 转成的二进制是无穷的。另外在现代浏览器中是用浮点数形式的二进制来存储二进制,所以还要把上面所转化的二进制转成浮点数形式的二进制。

2.转成浮点数

浮点数分为单精度对应32位操作系统和双精度对应64位操作系统。目前的操作系统大多是64位操作系统,故这里只解释一下二进制如何转成双精度浮点数的二进制。

双精度浮点数用1位表示符号位,11位表示指数位,52位表示小数位,如下图所示:

  • 符号位:正数为0,负数为1;
  • 指数位:阶数+偏移量,阶数是:

,e为阶码的位数。偏移量是把小数点移动到整数位只有1时移动的位数,正数表示向左移,负数表示向右移;

  • 小数位:即二进制小数点后面的数。

接下来把0.1转成的二进制0.0001100110011001 ......转成浮点数形式的二进制。

  • 先要把小数点移动到整数位只有1,要向右移动4位,故偏移量为−4,通过指位数的计算公式

,把1019转成二进制为1111111011,不够11位要补零,最终得出指位数为01111111011;

  • 小数位为100110011001...... ,因为小数位只能保留52位,第53位为1故进1。

转换结果如下图所示:

同理,再把 0.2 转成的二进制0.0011 0011 0011 0011...... 转成浮点数形式的二进制,转换结果如下图所示:

3.浮点数相加

浮点数相加时,需要先比较指位数是否一致,如果一致则小数位直接相加,如果不一致,要先把指位数调成一致的,指位数小的向大的调整。

为了行文方便,把0.1转成的浮点数称为为0.1,把0.2转成的浮点数称为0.2。

0.1的指数位是1019 ,0.2的指数位是1020 。故要把0.1的指数位加1,即把0.1的小数点向左移动1位,另外浮点数的整数位固定为1,过程如下所示

1.1001100110011001100110011001100110011001100110011010   原先
0.11001100110011001100110011001100110011001100110011010  移动后  
0.1100110011001100110011001100110011001100110011001101   将小数的第53位舍去,因为为0故不需进1

导致0.1的小数位变成如下所示:

现在0.1和0.2的指数位相同了,把小数位直接相加。

    1100110011001100110011001100110011001100110011001101 0.1的小数位
+   1001100110011001100110011001100110011001100110011010 0.2的小数位
=  10110011001100110011001100110011001100110011001100111

会发现现在的小数位多出了一位,超出了52位,故要把小数位最后一位截掉,小数位最后一位是1,故要进1,如下所示:

10110011001100110011001100110011001100110011001100111
1011001100110011001100110011001100110011001100110100

截掉小数位的最后一位相当把小数点向左移了一位,故指数位要加1,此时的指数是0.2的指数1021 ,加1后变成1021 ,转成二进制为01111111101 ,那么相加后的浮点数如下所示:

4.浮点数转成十进制

二进制浮点数计算结束后,把结果(二进制的浮点数)转成十进制,其转换公式为

,s是符号位为0或1,e为浮点数指数位转成十进制的值,i表示小数位从左到右的位数,第一位 i=1 ,

表示每一位的值为0或1。

那么按着公式把二进制的浮点数转成十进制:

结果如下所示:

0.3000000000000000444089209850062616169452667236328125

由于精度问题,只取到0.30000000000000004。

二、答案

0.1+0.2 不等于 0.3 ,因为在 0.1+0.2 的计算过程中发生了两次精度丢失。第一次是在 0.1 和 0.2 转成双精度二进制浮点数时,由于二进制浮点数的小数位只能存储52位,导致小数点后第53位的数要进行为1则进1为0则舍去的操作,从而造成一次精度丢失。第二次在 0.1 和 0.2 转成二进制浮点数后,二进制浮点数相加的过程中,小数位相加导致小数位多出了一位,又要让第53位的数进行为1则进1为0则舍去的操作,又造成一次精度丢失。最终导致 0.1+0.2 不等于0.3 。

三、拓展

0.1+0.2 不等于 0.3 会引起那些BUG ?

会引起统计页面展示错乱的BUG,还有 300.01 优惠300 元后,支付金额不足0.01 元等类似的BUG。

怎么解决 0.1+0.2 不等于 0.3 ?

可以用Math.js数学计算库来解决,或者用toFixed()给计算结果四舍五入,但是toFixed()在chrome或者火狐浏览器下四舍五入也有精度误差。可以用Math.round来解决精度误差,比如要把 2.55 四舍五入保留 1 位小数,先把 2.55∗10 得到 25.5 ,再用Math.round取整25.5 ,会得到25,再把 25÷10 得到 2.5 ,就这样间接实现了四舍五入。可以用Math.pow来做个简单的封装Math.round(Math.pow(10, m) * number) / Math.pow(10, m),其中number是要四舍五入的数,m是保留几位小数。

13-为什么在JavaScript中0.1 + 0.2不等于0.3? 理解这一点,并采用适当的方法来处理浮点数计算,可以帮助我们避免相关的精度问题。首先,我们需要了解计算机是如何表示小数的。而在二进制中,并不是所有的十进制小数都能精确地表示。将这些十进制小数转换为二进制浮点数时,它们只能近似表示。但是,在二进制系统中,0.1表示为一个无限循环的小数,类似于在十进制中1/3表示为0.3333…对于需要高精度计算的场景,可以使用BigDecimal库进行处理,这些库能够精确处理十进制数。这并不是精确的0.3,而是一个非常接近0.3的数值,但在计算机的精度限制下,它们并不相等。 阅读详情

相关推荐

JavaScript浮点数精度问题解析:0.1 + 0.2为什么不等于0.3

IEEE 754标准是由国际电气和电子工程师协会(IEEE)制定的一套关于浮点数运算的标准。该标准解决了不同计算机和处理器在进行浮点数计算时可能产生的不一致问题。由于早期计算机系统在浮点运算方面缺乏统一规范,导致同一个计算任务在不同的硬件或软件环境下得到的结果不尽相同,这对科学计算、工程、金融等领域造成了极大的困扰。IEEE 754标准的制定,使得浮点数的表示和运算在全世界范围内实现了标准化,极大地提高了计算结果的可移植性与可信度。Math对象包含了一系列用于执行基本数学运算和复杂数学计算的函数。

weixin_29363791的博客 631

为什么 0.1+0.2 不等于 0.3

位),而在这种格式下无法精确表示某些小数,因此在进行计算时会出现精度误差。中,这些小数会被转换成最接近它们的可表示值,然后再进行计算。被转换成的值可能会存在精度误差,导致它们的和不等于。都是无限循环小数,无法用二进制精确地表示。中采用的是双精度浮点数格式(

weixin_42560424的博客 3029

避坑指南:HslCommunication连接西门子PLC时常见的5个错误及解决方法(S7-1200/S1500适用)

本文详细解析了使用HslCommunication连接西门子S7-1200/S1500 PLC时常见的5个错误及解决方法,包括基础连接配置、数据块读写异常、连接闪断、防火墙与权限问题以及高级调试技巧。通过实战案例和代码示例,帮助开发者快速定位和解决连接问题,提升工业自动化项目的开发效率。

weixin_30752699的博客 396

0.1 + 0.2 为什么不等于 0.3之小数精度问题

浮点数计算类,取二者中小数位数最长者(记为 N),同时乘以 10 的 N 次幂,转换为整数进行计算,再除以 N 次幂转回小数需要用 toFixed 取近似值的地方,可以先加上 1e-14 或 umber.EPSILON,再取。判定两个数字相等,可以使用 Math.abs(left - right) < Number.EPSILON实在不会,就直接用别人写好的成熟库吧。

yyh1994的博客 2103

想学嵌入式但没开发板?试试这个免费的STM32虚拟仿真平台(含LVGL界面教程)

本文介绍如何利用免费的STM32虚拟仿真平台学习嵌入式开发,特别适合预算有限或零硬件基础的学习者。通过详细的LVGL界面开发教程,展示虚拟仿真在嵌入式学习中的高效性和实用性,涵盖环境搭建、代码实现到实机迁移的全流程,助力快速掌握嵌入式开发核心技能。

weixin_29266647的博客 306

Stm32L0 STM32CUBE中UART和使用LPUART1以及串口不进中断问题解决

/* 开启串口1中断 */ LL_USART_EnableIT_RXNE(LPUART1); /* 开启串口2中断 */ LL_USART_EnableIT_RXNE(USART2);

シ❤゛甜虾的个人博客 7686

17、为什么0.1 + 0.2 不等于 0.3

再用2去除商,又会得到一个商和余数,如此进行,直到商为小于1时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。具体做法是:用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,此时0或1为二进制的最后一位。浮点数相加时,需要先比较指位数是否一致,如果一致则小数位直接相加,如果不一致,要先把指位数调成一致的,指位数小的向大的调整。转成浮点数形式的二进制。

天界程序员的博客 2287

基于APDL语言的结构优化设计

同理,二次微分值称为二阶值。通俗地讲优化分析,指的找到一种方案可以满足所有的设计要求,而且所需的支出(如重量,面积,体积,应力,费用等)最小。设计方案的任何方面都是可以优化的,比如说:尺寸(如厚度),形状(如过渡圆角的大小),支撑位置,制造费用,自然频率,材料特性等。完成分析文件的建立后,就可以进行优化分析了,如果在交互方式下进行优化的话,最好先在ANSYS数据库中用分析文件建立参数,其优点有:初始参数可以作为一阶分析方法的起点,且对于优化过程参数在数据库中可以在GUI下进行操作,便于定义优化变量。

m0_73816777的博客 1174

为什么 0.1 + 0.2 不等于0.3?如何解决这个问题?

一、开头 我们都知道0.1 + 0.2 !== 0.3,而是0.30000000000000004,那么是为什么?我们都知道计算机在内部实现中使用的是二进制,0.1也是不例外的,此时我们将0.1转换为二进制数据表示可以表示为:0.0001100110011001100...(1100无限循环),0.2转换为二进制数据可以表示为0.00110011001100...(1100循环),此时这两个数均为无限循环小数,那么该如何去存储呢? 二、如何存储二进制小数 不同的语言可能会有不同的存储标准,javascrip

weixin_47450807的博客 9108

顶刊论文引言用AI怎么写?借助Gemini 3 Pro结合四段式写出逻辑清晰的Introduction

写研究目标时,先明确研究问题,直接回应前文提到的研究缺口,如 “This study aims to investigate whether X modulates Y via the Z pathway in human cells.”然后再提出你的研究假设,当理论依据清晰时,可以用如 “We hypothesized that inhibiting X would rescue Y deficiency in this model.”的句子点出研究目标。要求:1)明确陈述本研究拟解决的核心科学问题;

智能AI让学术科研更容易 180

第三天:Python基础语法详解

Python代码规范与注释最佳实践 摘要: 本文深度解析Python缩进规则与代码结构的技术规范,包括缩进的底层原理、语法规则和错误处理。详细阐述Python注释系统,涵盖行内注释、文档字符串和类型注释等多种形式,并提供工业级代码组织方案。研究显示,良好的缩进可提升40%的代码识别速度,降低50%的认知负荷。文章还对比了Sphinx、pdoc等主流文档生成工具,给出企业级项目中的注释编写原则和模板建议,帮助开发者构建更可维护的Python代码。

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 1011

0.1+0.2为什么不等于0.3

大家好,我是哪吒。最近碰到一个问题,很有趣,我就不贴代码了,要不你们会以为我在无中生有。我现在的心情很复杂,我想静静。我只知道浮点数相加是丢失精度的,但是为什么会丢精度,我就不知道了。浮点数在计算机内部是以二进制的形式存储的,而有些十进制的小数在二进制下无法精确表示,因此在进行浮点数运算时可能会存在精度误差。浮点数分为单精度对应32位操作系统和双精度对应64位操作系统。目前的操作系统大多是64位操作系统,故这里只解释一下二进制如何转成双精度浮点数的二进制。双精度浮点数用1位表示符号位,11位表示指数位,52

学Java,找哪吒 1569

13、Java 中 MQTT 异步通知与回调的使用及传感器命令处理

本文详细介绍了在 Java 中使用 MQTT 的异步通知与回调机制,并展示了如何通过 Paho Java 客户端处理与传感器交互的命令。文章包含代码示例,讲解了 MQTT 客户端的连接、订阅、消息处理以及模拟传感器数据发布的过程,适用于希望在 Java 应用中实现 MQTT 通信与设备控制的开发者。

eee77的博客 159

python0.1+0.2不等于0.3_为什么0.1+0.2不等于0.3

先看两个简单但诡异的代码:0.1 + 0.2 > 0.3 // true0.1 * 0.1 = 0.0100000000000000020.1加0.2为什么就不等于0.3昵?要回答这个问题,得先了解计算机内部是如何表示数的。计算机内部如何表示数我们都知道,计算机用位来储存及处理数据。每一个二进制数(二进制串)都一一对应一个十进制数。1. 计算机内部如何表示整数这里以十进制数13来展示“按位计...

weixin_33617691的博客 5141

【华为OD机试真题】459、小扇和小船的数字游戏、数字游戏 | 机试真题+思路参考+代码解析(CD卷)(C++、Java、Py)

### 🎃题目描述 >小扇和小船今天又玩起来了数字游戏,小船给小扇一个正整数 n(1  现在求 m 的最小值

KJ.JK 1718

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

前端面试题——0.1+0.2为什么不等于0.3?

0.1+0.2=0.3在我们的日常生活中是简单到不用动脑子就能得出的等式。但是在计算机的世界中恐怕并非如此,你或许在编写代码时见过0.1+0.2=0.30000000000000004,是计算机算错了吗?让我们来探究其背后的原理。

omroji的博客 2039

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

python0.1+0.2不等于0.3_为什么0.1 + 0.2不等于0.3?

原标题:为什么0.1 + 0.2不等于0.3?0.1 + 0.2不等于0.3这是一个普遍的问题,例如在JS控制台输入将得到0.30000000000000004 在python的控制台也是输出这个数: 在C里面运行以下代码,指定输出小数位为57位:printf("%.57f", 0.1 + 0.2);将得到:0.3000000000000000444089209850062616169452667...

weixin_30800249的博客 1722

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

为什么0.1+0.2不等于0.3

首先来看一段诡异的代码: package org.sang.test; /** * @Author: chuxia0811 * @Date: 2021/2/9 22:55 * @Description : */ public class _01_02 { public static void main(String[] args) { float a = 0.1f; float b = 0.2f; System.out.println(a +

初夏0811的博客 2万+

0.1+0.2为什么不等于0.3,以及怎么等于0.3

在开发过程中遇到类似这样的问题: let n1 = 0.1, n2 = 0.2 console.log(n1 + n2) // 0.30000000000000004 这里得到的不是想要的结果,要想等于0.3,就要把它进行转化: (n1 + n2).toFixed(2) // 注意,toFixed为四舍五入 toFixed(num)方法可把 Number 四舍五入为指定小数位数的数字。那为什么会出现这样的结果呢?    计算机是通过二进制的方式存储数据的,所以计算机计算0.1+0.2的时候,实.

Front end development engineer 3万+

为什么 JavaScript 中 0.1 0.2 不等于 0.3 ?

本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/2kea7-jACCJmSYBQAwXyIg 作者:刘洋 在 js 中进行数学的运算时,会出现0.1+0.2=0.300000000000000004的结果,一开始认为是浮点数的二进制存储导致的精度问题,但这似乎不能很好的解释为什么在同样的存储方式下0.3+0.4=0.7可以得到正确的结...

vivo互联网技术 817

python中0.1+0.2为啥不等于0.3_为什么0.1+0.2不等于0.3?原来编程语言是这么算的……...

打开你的 Python,输入「0.1+0.2=」,结果是多少?0.30000000000000004 对不对?为什么结果不是 0.3?本文作者给出了详细的解释。从小我们就知道 0.1 + 0.2=0.3。但是,在光怪陆离的计算世界中,运算方式却大相径庭。我最近开始用 JavaScript 进行编码,在阅读数据类型时,我注意到 0.1 + 0.2 不等于 0.3 的奇怪行为。我向 Stack Ove...

weixin_34170028的博客 3912

JS中为什么0.1+0.2 不等于0.3

科学计数法 假设有两个数字 220000000000 和 22000000000 一眼看过去好像很难比较出大小 但是使用科学计数法就非常容易进行比较 2.2∗10112.2∗1010 2.2*10^{11}\\ 2.2*10^{10} 2.2∗10112.2∗1010 IEEE 754浮点数表示 Javascript是使用双精度浮点数表示的。 sign:符号位 1表示数字为负数,0表示为正数 (1位) exponent:阶码 (11位) mantissa: 尾数 (52位) 总共64位 看不懂

ZHgogogoha的博客 806

在js里为什么0.1+0.2不等于0.3

在js里为什么0.1+0.2不等于0.31.产生原因2.内部原理扩展 1.产生原因 JS 采用的是双精度版本, 即IEEE 754 双精度版本(64位),这个版本就存在精度问题,就导致了上边这种情况。 在计算机中,数字无论是定点数还是浮点数都是以多位二进制的方式进行存储的。 2.内部原理 我们计算机的信息全部转化为二进制进行存储的,那么0.1的二进制表示的是一个无限循环小数,该版本的 JS 采用的是浮点数标准需要对这种无限循环的二进制进行截取,从而导致了精度丢失,造成了0.1不再是0.1,截取之后0.

cppp1111的博客 4034

70、在js中为什么0.1+0.2不等于0.3

并不是所有小数都可以用「完整」的二进制来表示的,比如十进制 0.1 在转换成二进制小数的时候,是一串无限循环的二进制数,计算机是无法表达无限循环的二进制数的,毕竟计算机的资源是有限。 因此,计算机只能用「近似值」来表示该二进制,那么意味着计算机存放的小数可能不是一个真实值,现在基本都是用 IEEE 754 规范的单精度浮点类型或双精度浮点类型来存储小数的,根据精度的不同,近似值也会不同。 ———————————————— 版权声明:本文为优快云博主「小林coding」的原创文章,遵循CC 4.0 BY-

sunnnnh的博客 1746

为什么 Python 中0.1 + 0.2 不等于 0.3?

print(is_close(0.1 + 0.2, 0.3)) # 输出:True。

pythondh1的博客 2489
上一篇: ABAP 表控制TAKE CONTROL设计
荒芜酥
博客等级 码龄9年 19粉丝 9原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值