MST

星途 面试题库

面试题:JavaScript中浮点数精度问题在算术操作符中的体现

请解释为什么在JavaScript中 0.1 + 0.2 不等于 0.3 ?如何解决这个精度问题?
39.0万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

原因

在JavaScript中,数字以IEEE 754双精度64位格式存储。0.1和0.2在二进制中是无限循环小数,存储时会进行近似,导致相加后的结果与0.3的二进制表示存在细微差异,所以 0.1 + 0.2 不等于 0.3。具体来说:

  • 0.1的二进制表示为:0.0001100110011001100110011001100110011001100110011001101(无限循环,存储时会截断近似)
  • 0.2的二进制表示为:0.001100110011001100110011001100110011001100110011001101(无限循环,存储时会截断近似)
  • 二者相加后结果的二进制表示与0.3的二进制表示 0.01001100110011001100110011001100110011001100110011001101 存在差异。

解决方法

  1. 使用 toFixed() 方法: 可以对结果使用 toFixed() 方法进行四舍五入,设定保留的小数位数。
let result = (0.1 + 0.2).toFixed(1);
console.log(result === '0.3'); // true

toFixed() 返回的是字符串,如果需要数字类型,还需进一步转换。 2. 使用 Math.round() 方法: 先将数字乘以一个10的幂次方,使小数变为整数,进行运算后再除以相同的幂次方,并使用 Math.round() 进行四舍五入。

let num1 = 0.1;
let num2 = 0.2;
let result = Math.round((num1 + num2) * 10) / 10;
console.log(result === 0.3); // true
  1. 使用 BigInt(ES2020 引入)BigInt 类型可以表示任意精度的整数。先将小数转换为整数进行运算,再转换回小数。
let num1 = 0.1 * 10n;
let num2 = 0.2 * 10n;
let result = Number((num1 + num2) / 10n);
console.log(result === 0.3); // true
  1. 使用第三方库如 decimal.jsdecimal.js 提供了用于任意精度算术的Decimal类型。
const Decimal = require('decimal.js');
let num1 = new Decimal(0.1);
let num2 = new Decimal(0.2);
let result = num1.plus(num2).equals(new Decimal(0.3));
console.log(result); // true