为什么我的while循环是无限的?每次都更改变量,但条件仍然始终为真

Why is my while loop infinite? Changing the variable each time, but condition is still always true

本文关键字:条件 变量 改变 循环 while 我的 无限 为什么      更新时间:2023-09-26

我正在尝试创建一个函数,该函数需要一定数量的现金,并从现有变量中扣除弥补该现金数量所需的硬币/钞票数量。我拥有的代码如下所示:

var changeDue = 34.66;
  // get number of each coin
  var penny   = 50;
  var nickel  = 50;
  var dime    = 50;
  var quarter = 50;
  var one     = 50;
  var five    = 50;
  var ten     = 50;
  var twenty  = 50;
  var hundred = 50;
  function getChange(due) {
    var currentDue = due;
    while(currentDue > 0) {
      if(currentDue >= 100 && hundred > 0){
        hundred--;
        currentDue -= 100;
      }
      else if(currentDue >= 20 && twenty > 0) {
        twenty--;
        currentDue -= 20;
      }
      else if(currentDue >= 10 && ten > 0) {
        ten--;
        currentDue -= 10;
      }
      else if(currentDue >= 5 && five > 0) {
        five--;
        currentDue -= 5;
      }
      else if(currentDue >= 1 && one > 0) {
        one--;
        currentDue -= 1;
      }
      else if(currentDue >= 0.25 && quarter > 0) {
        quarter--;
        currentDue -= 0.25;
      }
      else if(currentDue >= 0.1 && dime > 0) {
        dime--;
        currentDue -= 0.1;
      }
      else if(currentDue >= 0.05 && nickel > 0) {
        nickel--;
        currentDue -= 0.05;
      }
      else if(currentDue >= 0.01 && penny > 0) {
        penny--;
        currentDue -= 0.01;
      }
    }
    console.log(currentDue);
  }
  getChange(changeDue);

我试图用while循环做的是检查到期的零钱金额是否高于某个钞票/硬币,如一百,并且仍然有这个价值的硬币或钞票可用,然后从应付的零钱和硬币/钞票的数量中扣除。但这会导致无限循环,所以我无法调试它。

我想,既然我总是从当前到期中扣除,而且我设置了如此多的硬币和钞票,所以我不会有这样的问题,但我确实有。有人可以指出我做错了什么吗?

谢谢

循环可能是无限的有两个原因:

  1. 浮点数的不精确性,JavaScript 和其他语言使用它来表示小数位的数字
  2. 事实上,如果你用完了硬币,就没有办法退出循环

在此示例中,第一个是原因,但您应该同时解决这两个问题。

要解决第一个问题,您可以执行以下两项操作之一。您可以将所有内容乘以 100 以使用整数,然后在末尾除以 100 得到答案,如下所示:

if(currentDue >= 10000 && hundred > 0){
  hundred--;
  currentDue -= 10000;
}
...
console.log(currentDue / 100);

或者你可以使用 Math.round() ,如下所示:

if(currentDue >= 100 && hundred > 0){
  hundred -= 1;
  currentDue = Math.round(currentDue - 100);
 }

如果这很重要,这些解决方案中的第一个将更具性能。否则,请选择。

要解决第二个问题,如果上述条件都不成立,则可以添加 break 语句:

...
else {
  break;
}

第一个运算是 34.66 - 20,在 JavaScript 中为 34.66 - 20 = 14.6599999999999997(也许你可以四舍五入结果(。

因此,例如,currentDue 将为 0.009999,因此,您永远不会退出该循环。

由于

浮点问题,它循环,但它也会循环用于due的大值,特别是对于超过 6820.5 的值(即 50x100 + ... +50x0.01(。由于hundred最初是 50,因此 if 条件

   if(currentDue >= 100 && hundred > 0){
    hundred--;
    currentDue -= 100;
  }

将重复直到和hundred=0,即50次循环。在那之后currentDue = due -5000 hundred=0...如果适用,则如下。

如果此时到期超过 6800,则当前到期超过 1800。

重复该过程,您会发现到期> 0 和 100,...等于 0。

此时,没有 if 条件适用,并且由于没有其他条件,程序循环