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

时间:2016-02-13 01:00:47

标签: javascript

我试图制作一个需要一定数量现金的功能,并从现有变量中扣除弥补该现金所需的硬币/账单金额。我的代码看起来像这样:

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循环来检查更改金额是否高于某个单一的钞票/硬币(如100)并且仍然有可用的硬币或钞票,然后扣除从变更到期和金额/账单金额。但这导致无限循环,所以我无法调试它。

我认为,因为我总是从currentDue中扣除,而且我已经设置了如此多的硬币和账单,但我不会遇到这样的问题。有人可以指出我做错了吗?

谢谢

3 个答案:

答案 0 :(得分:2)

第一个操作是34.66 - 20,在JavaScript中34.66 - 20 = 14.659999999999997(也许你可以对结果进行舍入)。

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

答案 1 :(得分:2)

为什么你的循环可能是无限的有两个原因:

  1. floating point numbers的不精确性,JavaScript和其他语言用来表示带小数位的数字
  2. 如果你的硬币耗尽,就无法退出循环
  3. 在这个例子中,第一个是原因,但你应该解决这两个问题。

    要解决第一个问题,您可以执行以下两项操作之一。您可以将所有内容乘以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;
    }
    

答案 2 :(得分:-1)

由于浮点问题而导致循环,但是对于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,则currentDue超过1800.

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

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