CashRegister函数while循环缺1次迭代 找零少1Penny问题排查
问题原因
你遇到的少1Penny的问题,核心是JavaScript浮点数运算精度误差:0.01这类小数无法被二进制浮点数精确表示,多次累加后会出现类似0.04变成0.03999999999999999的微小偏差,导致边界判断提前触发,少执行了一次循环。
修复方案
所有金额运算统一转成整数(单位为分,乘以100),避免浮点误差,同时调整边界判断的逻辑,修改后的完整代码如下:
let coinsValue = { "PENNY": 1, // 单位改为分,全部转为整数运算 "NICKEL": 5, "DIME": 10, "QUARTER": 25, "ONE": 100, "FIVE": 500, "TEN": 1000, "TWENTY": 2000, "ONE HUNDRED": 10000 } function checkCashRegister(price, cash, cid) { // 所有金额转成整数(分)运算,用round消除初始转换的微小误差 let troco = Math.round((cash - price) * 100); let dinheiroEmCaixa = 0; // 计算收银机总金额,同步转成分 for (let i = 0; i < cid.length; i++){ dinheiroEmCaixa += Math.round(cid[i][1] * 100); } if (dinheiroEmCaixa < troco) return { status: 'INSUFFICIENT_FUNDS', change: [] }; if (dinheiroEmCaixa == troco) return { status: "CLOSED", change: cid } if (dinheiroEmCaixa > troco) { let availableToGive = 0; let valorMaximo = 0; let counter = 0; // 提前把所有cid的金额转为整数,避免后续运算反复转换出误差 let cidInt = cid.map(item => [item[0], Math.round(item[1] * 100)]); for (let i = 0; i < cidInt.length; i++) { if (coinsValue[cidInt[i][0]] > troco) cidInt.splice(i,1) else if (coinsValue[cidInt[i][0]] < troco && cidInt[i][1] > 0) availableToGive += cidInt[i][1] } if (availableToGive < troco) return { status: "INSUFFICIENT_FUNDS", change: [] } for (let i = (cidInt.length - 1); i >= 0; i--) { while (counter <= troco) { // 修正边界判断:加当前面值后不超过该面额库存、不超过找零总额才继续 if (valorMaximo + coinsValue[cidInt[i][0]] > cidInt[i][1] || (counter + coinsValue[cidInt[i][0]]) > troco ) break; valorMaximo += coinsValue[cidInt[i][0]] counter += coinsValue[cidInt[i][0]] } cidInt[i][1] = valorMaximo / 100; // 最终输出时转回元单位 valorMaximo = 0; if (counter > troco || cidInt[i][1] == 0) cidInt.splice(i, 1) } return { status: "OPEN", change: cidInt } } } // 测试代码 console.log(checkCashRegister(3.26, 100, [ ["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100] ]))
输出结果
运行后即可得到预期结果:
{ status: 'OPEN', change: [ [ 'TWENTY', 60 ], [ 'TEN', 20 ], [ 'FIVE', 15 ], [ 'ONE', 1 ], [ 'QUARTER', 0.5 ], [ 'DIME', 0.2 ], [ 'PENNY', 0.04 ] ] }
内容的提问来源于stack exchange,提问作者izzypt
相关产品推荐
相关产品推荐

