You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 21:30:01