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

文章目录

在前端以及几乎所有现代编程语言中, 0.1 + 0.2 不等于 0.3 这是由于浮点数表示存在精度问题。要理解这个问题,我们需要了解浮点数的表示方式以及计算机内部的运算原理。

浮点数表示方式

大多数编程语言使用 IEEE 754 标准来表示浮点数,该标准使用二进制格式来存储浮点数。浮点数由三部分组成:

  1. 符号位:表示数值的正负。
  2. 指数:决定数值的幅度。
  3. 尾数(或称有效数字、尾数部分):表示具体的数字。

二进制表示的小数

在二进制中,并非所有的十进制小数都能被精确表示。例如:

  • 十进制 0.1 转换为二进制是一个无限循环小数:0.0001100110011001100110011...
  • 十进制 0.2 同样是一个无限循环小数:0.0011001100110011001100110...

由于存储空间限制和计算精度,计算机只能取这无限循环小数的有限位来近似表示。结果就是,0.10.2 的二进制表示都不是完全准确的,而是某个最接近的近似值。

加法问题

计算机在进行加法运算时,将这两个近似值相加,结果并不会是确切的 0.3,而是一个近似的值,可能是 0.30000000000000004 或类似的数值。因此,在进行相等性比较时,0.1 + 0.2 === 0.3 将是 false

例子

看一下代码:

javascript 复制代码
console.log(0.1 + 0.2); // 输出: 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // 输出: false

正如前面解释的,加法运算的结果并不是精确的0.3

如何处理精度问题

当需要处理货币计算或其他要求高精度的场景时,可以采取一些方法:

1. 使用数字比较的容差(epsilon)

当比较两个浮点数时,可以设置一个小的容差值来判断它们是否足够接近。

javascript 复制代码
const EPSILON = Number.EPSILON || 2.220446049250313e-16;
console.log(Math.abs(0.1 + 0.2 - 0.3) < EPSILON); // 输出: true
2. 使用整数

一种常见的实践方法是在处理货币时使用整数。例如,把金额转换成以分为单位的整数来进行计算。

javascript 复制代码
const a = 10; // 表示 $0.10
const b = 20; // 表示 $0.20
const sum = a + b; // 表示 $0.30

console.log(sum === 30); // 输出: true
console.log((sum / 100).toFixed(2)); // 输出: "0.30"
3. 使用专用库

为了解决 JavaScript 中的精度问题,有许多第三方库可以进行精确的十进制运算。例如,decimal.jsbignumber.js

使用 decimal.js 举例:

javascript 复制代码
const Decimal = require('decimal.js');

const a = new Decimal(0.1);
const b = new Decimal(0.2);
const sum = a.plus(b);

console.log(sum.toString()); // 输出: "0.3"
console.log(sum.equals(0.3)); // 输出: true

结论

0.1 + 0.2 不等于 0.3 是由浮点数表示和计算精度导致的。在实际开发中,需要格外注意浮点数的运算误差,可以使用适当的方法来规避这些问题。

相关推荐
每次的天空1 分钟前
Kotlin 作用域函数:apply、let、run、with、also
android·开发语言·kotlin
Mr.Liu63 分钟前
小程序30-wxml语法-声明和绑定数据
前端·微信小程序·小程序
7675604794 分钟前
useDateFormat源码解析
前端·源码
Mintopia4 分钟前
Three.js粒子系统开发实战:从基础到性能优化
前端·javascript·three.js
小林熬夜学编程4 分钟前
【高并发内存池】第八弹---脱离new的定长内存池与多线程malloc测试
c语言·开发语言·数据结构·c++·算法·哈希算法
Promise5204 分钟前
大屏"跑马灯" 长列表性能优化
前端·javascript
子玖5 分钟前
初始化项目前的准备
前端·javascript·vue.js
Mintopia5 分钟前
Three.js进阶实战:打造动态光影交互场景 ——结合环境光、聚光灯与相机控制的沉浸式体验
前端·javascript·three.js
贵州数擎科技有限公司6 分钟前
Threejs绘制小兩伞快拿去送给你的女神
前端
Carlos_sam7 分钟前
OpenLayers:封装Overlay的方法
前端·javascript