MST

星途 面试题库

面试题:JavaScript算术操作符边界条件下的类型转换与精度

考虑以下代码:`let num1 = 0.1; let num2 = 0.2; let result = num1 + num2;` 为什么 `result` 不是预期的 `0.3` ?如何解决这个精度问题?同时,在对`Number.MIN_VALUE`进行连续多次乘法操作时,又会出现什么边界情况?
41.9万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

1. 为什么 result 不是预期的 0.3

在JavaScript中,数字以IEEE 754双精度64位格式存储。这意味着,像 0.10.2 这样的小数在二进制中无法精确表示。

0.1 的二进制表示是一个无限循环小数 0.0001100110011...,同样,0.2 的二进制表示也是无限循环的 0.001100110011...。当它们相加时,由于二进制的不精确表示,结果在转换回十进制时就不是精确的 0.3,而是 0.30000000000000004

2. 如何解决这个精度问题

  • 使用 toFixed 方法: 可以使用 toFixed 方法将结果四舍五入到指定的小数位数。例如:
let num1 = 0.1; 
let num2 = 0.2; 
let result = (num1 + num2).toFixed(1); 
console.log(result); 

这样 result 就会是字符串 '0.3'。如果需要数字类型,可以使用 parseFloat 转换回来。

  • 使用 BigInt(如果可行)BigInt 类型可以表示任意精度的整数。如果你的应用场景允许将小数转换为整数进行运算,然后再转换回来,可以使用 BigInt。例如:
let num1 = 0.1 * 10; 
let num2 = 0.2 * 10; 
let result = (BigInt(num1) + BigInt(num2)) / BigInt(10); 
console.log(result); 
  • 使用 math.js: 这是一个功能强大的数学库,提供了高精度运算。例如:
const math = require('math.js'); 
let num1 = 0.1; 
let num2 = 0.2; 
let result = math.add(num1, num2); 
console.log(result); 

3. Number.MIN_VALUE 连续多次乘法操作的边界情况

Number.MIN_VALUE 是JavaScript中最小的正值,约为 5e-324。当对 Number.MIN_VALUE 进行连续多次乘法操作时,由于数字的下溢问题,最终结果会趋近于 0。一旦结果小于 Number.MIN_VALUE,JavaScript会将其视为 0。例如:

let minValue = Number.MIN_VALUE; 
let product = minValue; 
for (let i = 0; i < 100; i++) { 
    product *= 0.1; 
} 
console.log(product); 
// 最终结果将是0

这是因为 Number.MIN_VALUE 已经非常接近0,每次乘以一个小于1的数,结果会越来越小,最终低于JavaScript能表示的最小正值。