简体   繁体   English

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

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

I'm trying to make a function that takes an amount of cash, and deducts the amount of coins/bills needed to make up that amount of cash from existing variables. 我正在尝试制作一个需要大量现金的功能,并扣除从现有变量中弥补现金所需的硬币/账单金额。 The code I have looks like this: 我的代码看起来像这样:

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);

What I'm trying to do with the while loop is to check if the amount of change due is above a certain bill/coin like one hundred and there are still coins or bills of this value available, and then deduct from the change due and amount of coins/bills. 我正在尝试使用while循环来检查更改的金额是否超过某个账单/硬币,如100,并且仍然有可用的硬币或账单,然后从更改到期和硬币/账单数量。 But this is resulting in an infinite loop, so I can't debug it. 但这导致无限循环,所以我无法调试它。

I thought that since I am always deducting from currentDue and I have set such a high number of coins and bills I wouldn't have such a problem but I do. 我认为,因为我总是从currentDue中扣除,而且我已经设置了如此多的硬币和账单,我不会有这样的问题,但我确实如此。 Can someone point out what I am doing wrong? 有人可以指出我做错了什么吗?

Thank you 谢谢

The first operation is 34.66 - 20, in JavaScript 34.66 - 20 = 14.659999999999997 (maybe you can round the result). 第一个操作是34.66 - 20,在JavaScript 34.66 - 20 = 14.659999999999997(也许你可以舍入结果)。

So, the currentDue will be 0.009999 for example, so, you never exit for that loop. 因此,例如currentDue将为0.009999 ,因此,您永远不会退出该循环。

There are two reasons why your loop might be infinite: 循环可能无限的原因有两个:

  1. The imprecision of floating point numbers , which JavaScript and other languages use to represent numbers with decimal places 浮点数的不精确性,JavaScript和其他语言用来表示带小数位的数字
  2. The fact that there is no way to exit the loop if you run out of coins 事实上,如果你的硬币耗尽,就无法退出循环

In this example, the first is the reason, but you should address both. 在这个例子中,第一个是原因,但你应该解决这两个问题。

To address the first problem, you can do one of two things. 要解决第一个问题,您可以执行以下两项操作之一。 You can multiply everything by 100 to use integers instead, and then divide by 100 at the end to get the answer, like so: 您可以将所有内容乘以100以使用整数,然后在末尾除以100得到答案,如下所示:

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

...

console.log(currentDue / 100);

Or you could use Math.round() , like so: 或者您可以使用Math.round() ,如下所示:

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

The first of these solutions will be more performant if that matters at all. 如果重要的话,这些解决方案中的第一个将更具性能。 Otherwise, take your pick. 否则,请选择。

To address the second problem, you can add a break statement if none of the above conditions are true: 要解决第二个问题,如果上述条件均不成立,则可以添加break语句:

...

else {
  break;
}

It loops due to floating point issues, but it would loop also for large values of due ,in particular for values over 6820.5 (that is, 50x100 + ... +50x0.01). 它由于浮点问题而循环,但是对于大的due值也会循环,特别是对于超过6820.5的值(即50x100 + ... + 50x0.01)。 Since hundred is 50 initially, the if condition 由于hundred 50开始,如果条件

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

will be repeated until and hundred=0 , that is, 50 loops. 将重复,直到和hundred=0 ,即50个循环。 After that currentDue = due -5000 hundred=0 ...and the following if applies. 在那之后currentDue = due -5000 hundred=0 ......并且以下情况适用。

If due is over 6800 at this moment currentDue is over 1800. 如果到期时超过6800,则currentDue超过1800。

Repeat the process and you will find due > 0 and hundred, ... equal to 0. 重复这个过程,你会发现due> 0和100,...等于0。

At this point no if condition applies, and since there is no else, the program loops 此时没有if条件适用,并且由于没有其他条件,程序循环

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM