JavaScript浮点数相加异常及checkCashRegister函数forEach循环问题
Hey there! Let's work through your two technical issues step by step, using the code snippet you provided.
问题1:JavaScript浮点数相加的异常
原因分析
JavaScript 使用 IEEE 754 双精度浮点数 来存储数值,这种格式无法精确表示所有十进制小数(比如 0.1、0.2 这类)。当你对这类浮点数执行加法时,就会出现看似奇怪的精度误差,比如 0.1 + 0.2 = 0.30000000000000004。在你的代码里,累加 values["TOTAL"] += arr[1] 时,如果 arr[1] 是带小数的金额(比如 1.01 便士),多次累加后也会出现精度偏移。
解决方法
- 转换为整数计算:把金额转换成最小单位(比如分)进行整数运算,从根源避免浮点数误差。例如:
// 把美元转成分,计算后再转回美元 const totalCents = values["TOTAL"] * 100 + arr[1] * 100; values["TOTAL"] = totalCents / 100; - 使用
toFixed()控制精度:如果不需要极高精度,可以在累加后保留两位小数(对应美元的分):// toFixed返回字符串,需转成数字使用 values["TOTAL"] = Number((values["TOTAL"] + arr[1]).toFixed(2));
问题2:checkCashRegister函数中forEach循环的问题
原因分析
从你的代码来看,核心问题是 全局变量污染:
- 你把
values对象定义在函数外部,每次调用checkCashRegister时,不会重新初始化values。比如第一次调用后values["TOTAL"]已经有值,第二次调用forEach时会在这个旧值的基础上继续累加,导致计算结果完全错误。 - 另外,当前的
forEach只是把cid里的金额赋值给values并累加总金额,但还没实现实际的找零逻辑(不过这可能是你还没写完的部分)。
解决方法
- 将
values移到函数内部:每次调用函数时都创建一个新的values对象,彻底避免全局状态污染:function checkCashRegister(price, cash, cid) { // 把values放到函数内部,每次调用都重新初始化 let values = { "PENNY": 0, "NICKEL": 0, "DIME": 0, "QUARTER": 0, "ONE": 0, "FIVE": 0, "TEN": 0, "TWENTY": 0, "ONE HUNDRED": 0, "TOTAL": 0, }; cid.forEach((arr) => { values[arr[0]] = arr[1]; // 同时处理浮点数精度问题 values["TOTAL"] = Number((values["TOTAL"] + arr[1]).toFixed(2)); console.log(`${values["TOTAL"]} + ${arr[1]} = ${values["TOTAL"]}`); }); let change = cash - price; // 这里可以继续完善找零逻辑,比如判断是否能足额找零、返回对应状态等 console.log(values); return change; } - 完善找零逻辑(可选):如果你的目标是实现完整的收银找零功能,后续需要根据
change的金额,从大面额到小面额依次扣除values里的金额,最后返回找零数组或者对应的状态(比如"INSUFFICIENT_FUNDS"、"CLOSED"等)。
内容的提问来源于stack exchange,提问作者Henry S
相关产品推荐
相关产品推荐

