当前位置: 首页 > news >正文

3. 为什么 0.1 + 0.2 != 0.3

总结

  1. 底层是二进制实现

概述

在 JavaScript 中,0.1 + 0.2 的结果并不是精确的 0.3,而是 0.30000000000000004。这个现象并不是 JavaScript 的“bug”,而是由于浮点数在计算机底层的二进制表示方式导致的精度丢失问题。


一、计算机如何表示小数?

JavaScript 使用 IEEE 754 标准中的 64 位双精度浮点数(double) 来表示数字。这种格式将一个数字分为三部分:

  • 符号位(Sign bit):1 位,表示正负。
  • 指数位(Exponent):11 位,表示数值范围。
  • 尾数位(Mantissa / Fraction):52 位,表示精度。

由于计算机只能使用有限位数的二进制来表示小数,因此某些十进制小数无法被精确表示为二进制浮点数


二、为什么 0.10.2 无法精确相加?

1. 十进制转二进制的小数部分是无限循环

  • 0.1(十进制) → 0.00011001100110011...(二进制,无限循环)
  • 0.2(十进制) → 0.0011001100110011...(二进制,无限循环)

由于只能保留有限位(52 位尾数),因此只能近似存储这些值。

2. 计算时产生误差累积

当计算机将这两个近似值相加时,误差也随之累积,最终结果为:

0.1 + 0.2;
// 输出:0.30000000000000004

三、IEEE 754 表示举例

0.1 为例,其 IEEE 754 表示如下(简化):

部分
符号位0(正数)
指数位-4(即 2^-4)
尾数位1.10011001100110011001101…(截断后)

最终得到的值是:1.10011001100110011001101 × 2^-4,并不是精确的 0.1


四、其他语言也存在这个问题吗?

是的,所有使用 IEEE 754 浮点数标准的语言都存在这个问题,例如:

  • Python
  • Java
  • C++
  • Go
>>> 0.1 + 0.2
0.30000000000000004

五、如何解决精度问题?

1. 使用 toFixed() + parseFloat()

parseFloat((0.1 + 0.2).toFixed(1)) === 0.3;
// true

⚠️ 注意:toFixed() 返回字符串,需用 parseFloat() 转换回数字。

2. 使用 decimal.jsbig.js 等库

对于金融计算或高精度需求,推荐使用第三方库:

npm install decimal.js
import Decimal from "decimal.js";const result = new Decimal(0.1).plus(new Decimal(0.2));
result.equals(0.3); // true

3. 乘以 10^n 转换为整数运算

function add(a, b, precision = 10) {return (a * precision + b * precision) / precision;
}add(0.1, 0.2); // 0.3

http://www.dtcms.com/a/316084.html

相关文章:

  • Physics Simulation - UE中Projectile相关事项
  • Android 性能基准测试(Benchmark)完全指南:专业方法与最佳实践
  • VNC连接VirtualBox中的Ubuntu24.04 desktop图形化(GUI)界面
  • 【npm 解决】---- TypeError: crypto.hash is not a function
  • 相机拍摄的DNG格式照片日期如何修改?你可以用这款工具修改
  • Android --- Bug调查经验记录
  • linux 破解密码
  • LangGraph学习笔记 — LangGraph中State状态模式
  • 恶魔轮盘赌
  • 对 .NET线程 异常退出引发程序崩溃的反思
  • 基于vscode连接服务器实现远程开发
  • Redis之Set和SortedSet类型常用命令
  • Rust + WebAssembly 上线实战指南
  • LangChain入门:内存、记录聊天历史 ChatMessageHistory、模型、提示 ( Prompt )、模式 ( Schema )
  • Linux3
  • 在CentOS 7上搭建GitLab服务器的完整指南
  • 第二十五天(数据结构:树)
  • 智慧社区(七)——基于 ECharts 与 Spring Boot 实现小区住户数据统计可视化
  • Java面试宝典:对象的内存布局
  • 龙芯(loongson) ls2k1000 openwrt
  • 人工智能领域、图欧科技、IMYAI智能助手2025年3月更新月报
  • 网络巡查平台管理办法对政务管理有哪些作用
  • 进阶向:PDF合并/拆分工具
  • RabbitMQ削峰填谷详解:让系统在流量洪峰中“稳如泰山”
  • 在 MCP 中实现 “askhuman” 式交互:原理、实践与开源方案
  • Java: jwt 入门介绍(Introduction to JSON Web Tokens)
  • Spring 的依赖注入DI是什么?
  • ChatGPT以及ChatGPT强化学习步骤
  • 陪诊小程序开发:用科技重构就医陪伴的“温度经济”
  • K8S健康检查巡检清单