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

JavaScript中for循环返回值莫名翻倍问题排查

收银机找零逻辑数值异常排查求助

代码背景

为避免小数运算问题,所有金额均乘以100处理,相关初始化代码如下:

let dif100 = {
  rem : function(n){return n%10000},
  num: 10000,
  name : "ONE HUNDRED"} // 0
let dif20 = {
  rem : function(n){return n%2000},
  num: 2000,
  name : "TWENTY"}  // 1
let dif10 = {
  rem : function(n){return n%1000},
  num: 1000,
  name : "TEN"}   // 2
let dif5 = {
  rem : function(n){return n%500},
  num: 500,
  name: "FIVE"}     // 3
let dif1 = {
  rem : function(n){return n%100},
  num: 100,
  name: "ONE"}     // 4
let difqu = {
  rem : function(n){return n%25},
  num: 25,
  name: "QUARTER"} // 5
let difdime ={
  rem : function(n){return n%10},
  num: 10,
  name: "DIME"}//6
let difnic = {
  rem : function(n){return n%5},
  num: 5,
  name: "NICKEL"} //7
let difpen = {
  rem : function(n){return n%1},
  num: 1,
  name: "PENNY"} //8

let difArr = [dif100,dif20,dif10,dif5,dif1,difqu,difdime,difnic,difpen]

cid = [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1],
 ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20],
  ["TWENTY", 60], ["ONE HUNDRED", 100]]

let cashBox = cid.reverse()

for(let i = 0; i < cashBox.length; i++){
  cashBox[i][1] = Math.round(cashBox[i][1] *100)
}

测试情况

手动赋值dif(现金与价格差值乘以100)测试:

  • 当dif=18000(对应180美元)时,运行以下代码返回正确找零数组:
dif = 18000
answerArr = []
for(let i = 0; i < difArr.length; i++){
  if(dif < difArr[i].num){
    dif = dif
  } else if(difArr[i].rem(dif) == 0){ 
    if(cashBox[i][1] >= dif){
      answerArr.push([difArr[i].name, dif/100])
      dif = 0 
    } else if (cashBox[i][1] < dif){
      answerArr.push([difArr[i].name, cashBox[i][1]/100])
      dif = dif - cashBox[i][1]
    }
  }else {
    if(cashBox[i][1] >= dif - difArr[i].rem(dif)){
      answerArr.push([difArr[i].name, (dif - difArr[i].rem(dif))/100])
      dif = difArr[i].rem(dif)
    } else if (cashBox[i][1] < dif - difArr[i].rem(dif)){
      answerArr.push([difArr[i].name, cashBox[i][1]/100])
      dif = dif - cashBox[i][1] + difArr[i].rem(dif)
    }
  }
}
answerArr //返回 [["ONE HUNDRED",100],["TWENTY",60],["TEN",20]]
  • 当dif=18100(对应181美元)时,返回数组为[["ONE HUNDRED",100],["TWENTY",60],["TEN",20],["ONE",2]],最后1美元金额莫名翻倍;dif=18050时也存在类似异常。

排查方向

  • 核对cashBox与difArr的索引对应关系:
    cashBox由cid.reverse()生成,需逐一确认每个索引位置的币种是否与difArr完全匹配。比如反转后的cashBox第一项是["ONE HUNDRED",10000],对应difArr[0]是正确的,但后续的ONE美元、QUARTER等币种的索引是否一一对应?索引不匹配会导致取错现金盒中的金额,引发计算错误。

  • 跟踪循环每一步的关键变量值:
    在循环内部添加console.log,打印每一轮的i、difArr[i].name、当前dif值、cashBox[i][1]、dif - difArr[i].rem(dif)的计算结果。重点观察处理ONE美元(i=4)时的变量变化,看是否出现预期外的数值修改。

  • 检查else分支的dif更新公式:
    在else分支的第二个条件(cashBox[i][1] < dif - difArr[i].rem(dif))中,dif = dif - cashBox[i][1] + difArr[i].rem(dif)这个公式是否符合逻辑?代入异常场景的数值(比如dif=100时),计算该公式的结果是否合理,是否会导致dif被错误增加。

  • 确认数组反转的副作用:
    cid.reverse()会直接修改原数组cid,后续如果重复测试可能导致cashBox的内容意外变化。可以改成let cashBox = [...cid].reverse()创建数组副本,避免修改原数组带来的干扰。

内容的提问来源于stack exchange,提问作者Code Noober

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:25:26