【问题标题】:Not sure what's causing this error, Moneyconverter program in C不确定是什么导致了这个错误,C 中的 Moneyconverter 程序
【发布时间】:2013-01-16 11:14:45
【问题描述】:

到目前为止,它可以读取更简单的十进制数字,例如 $10.00、$220.50、$14.25。但是当它变成像 12.76 美元、320.84 美元、47.53 美元这样的数字时,它甚至不会运行。

我想知道是什么原因造成的以及如何解决它。

这是.h文件

#define TWENTY_BILL 20.00
#define TEN_BILL 10.00
#define FIVE_BILL 5.00
#define ONE_BILL 1.00
#define QUARTER_COIN 0.25
#define DIME_COIN 0.10
#define NICKEL_COIN 0.05
#define PENNY_COIN 0.01

这是.c文件

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "Value.h"

int main(int argc, char *argv[] ) {

 /*
 *Checks if argc has just one argument
 *If not, give error message
 */
if (argc < 2) {
    printf("Error: One argument required.");
    return 0;//If more than 1 argument, stops it
}//end if

/*
 * Converts argv[1] into double input
 * Then input2 is created as a float
 * input is transferred to input2
 *  Floor function is used, Multiplies
 *  input2 by 100 and then divide by 100 to
 *  leave only 2 decimal places
 *  Then Prints input2, %6.2f sets the field width
 *  for 2 decimal places
 */
double input = atof(argv[1]);
float input2;
input2 = input;
input2 = floor(input2 * 100) / 100;
printf("You have entered: %6.2f\n", input2);

/*
 * Creates variables for dollar
 * bill and coin set to 0
 */
int twentycount = 0;
int tencount = 0;
int fivecount = 0;
int onecount = 0;
int quartercount = 0;
int dimecount = 0;
int nickelcount = 0;
int pennycount = 0;

//Loops when input is greater than 0.0
while (input2 > 0.0)
    {
        /*Twenty Dollar Bill
         * When $20 is less than input2,
         * input2 - $20 = new input2
         * Add count to twentycount
         */
        if (TWENTY_BILL <= input2)
        {
            input2 = input2 - TWENTY_BILL;
            twentycount++;
        }//end if twenty
        /************************/
        /*Ten Dollar Bill
         * When $10 is less than input2,
         * input2 - $10 = new input2
         * Add count to tencount
         */
        else if (TEN_BILL <= input2)
        {
            input2 = input2 - TEN_BILL;
            tencount++;
        }//end if ten
        /***********************/
        /*Five Dollar Bill
         * When $5 is less than input2,
         * input2 - $5 = new input2
         * Add count to fivecount
         */
        else if (FIVE_BILL <= input2)
        {
            input2 = input2 - FIVE_BILL;
            fivecount++;
        }//end if five
        /**********************/
        /*One Dollar Bill
         * When $1 is less than input2,
         * input2 - $1 = new input2
         * Add count to onecount
         */
        else if (ONE_BILL <= input2)
        {
            input2 = input2 - ONE_BILL;
            onecount++;
        }//end if one
        /*********************/
        /*Quarter Coin
         * When $0.25 is less than input2,
         * input2 - $0.25 = new input2
         * Add count to quartercount
         */
        else if (QUARTER_COIN <= input2)
        {
            input2 = input2 - QUARTER_COIN;
            quartercount++;
        }//end if quarter
        /*********************/
        /*Dime Coin
         * When $0.10 is less than input2,
         * input2 - $0.10 = new input2
         * Add count to dimecount
         */
        else if (DIME_COIN <= input2)
        {
            input2 = input2 - DIME_COIN;
            dimecount++;
        }//end if dime
        /*********************/
        /*Nickel Coin
         * When $0.05 is less than input2,
         * input2 - $0.05 = new input2
         * Add count to nickelcount
         */
        else if (NICKEL_COIN <= input2)
        {
            input2 = input2 - NICKEL_COIN;
            nickelcount++;
        }//end if nickel
        /*********************/
        /*Penny Coin
         * When $0.01 is less than input2,
         * input2 - $0.01 = new input2
         * Add count to pennycount
         */
        else if (PENNY_COIN <= input2)
        {
            input2 = input2 - PENNY_COIN;
            pennycount++;
        }//end if penny
        /********************/
        /*
         * If anything else
         * Print Invalid Change
         */
        else
        {
            printf("Invalid change");
        }

    }//end while loop

    /*
     * If twentycount is more than 0
     * Print amount of $20 bills used
     */
    if (twentycount > 0)
    {
        printf("Amount of $20: %i\n", twentycount);
    }//end twentycount
    /*
     * If tencount is more than 0
     * Print amount of $10 bills used
     */
    if (tencount > 0)
    {
        printf("Amount of $10: %i\n", tencount);
    }//end tencount
    /*
     * If fivecount is more than 0
     * Print amount of $5 bills used
     */
    if (fivecount > 0)
    {
        printf("Amount of $5: %i\n", fivecount);
    }//end fivecount
    /*
     * If onecount is more than 0
     * Print amount of $1 bills used
     */
    if (onecount > 0)
    {
        printf("Amount of $1: %i\n", onecount);
    }//end onecount
    /*
     * If quartercount is more than 0
     * Print amount of $0.25 bills used
     */
    if (quartercount > 0)
    {
        printf("Amount of $0.25: %i\n", quartercount);
    }//end quartercount
    /*
     * If dimecount is more than 0
     * Print amount of $0.10 bills used
     */
    if (dimecount > 0)
    {
        printf("Amount of $0.10: %i\n", dimecount);
    }//end dimecount
    /*
     * If nickelcount is more than 0
     * Print amount of $0.05 bills used
     */
    if (nickelcount > 0)
    {
        printf("Amount of $0.05: %i\n", nickelcount);
    }//end nickelcount
    /*
     * If pennycount is more than 0
     * Print amount of $0.01 bills used
     */
    if (pennycount > 0)
    {
        printf("Amount of $0.01: %i\n", pennycount);
    }//end pennycount


return 0;
}//end main

【问题讨论】:

  • “连跑都不会”是什么意思?
  • 请说得更具体一些,它不会运行,因为它会立即崩溃?它永远不会结束?完全不同的东西?
  • 好吧,我想我用错了词,我的意思是没有显示任何内容
  • 尝试让它在通过 while 循环时打印出 input2 的值(或者在它循环时使用调试器进行检查)。这应该可以帮助您找到它开始无限循环的点,从那里您可以找到修复或编辑您的问题以非常精确。
  • 我建议使用代表美分数的整数。它们更容易处理。

标签: c decimal converter currency


【解决方案1】:

我认为你的问题在于input2 &gt; 0.0。像input2 &gt;= 0.00001 这样的东西会更好。这是因为浮点数在内存中的表示方式。 (x+y) - x - y 不保证是= 0

更简单的方法是将输入乘以 100 转换为整数。

我还建议你删除 while 循环并将里面的所有 if 语句替换为 while 循环。

【讨论】:

    【解决方案2】:

    您已经到了浮点算术与我们在学校所想的不太一样的地步。 :-)

    要将 input2 与零进行比较,您需要使用绝对 epsilon,其值是 FLT_EPSILON 的一些小的倍数。这是因为浮点数/双精度数不能精确地表示所有值,例如double(.1) == 0.1000000000000000055511151231257827021181583404541015625。为了解决这个问题,您需要确定您的数字何时“足够接近”为零。

    【讨论】:

      【解决方案3】:

      我相信您还没有涵盖结构。如果有,您需要重新访问您的代码。事实上,你可以用数组来改进,但结构数组会更好。

      请记住,二进制浮点值不能准确地表示大多数十进制值。诸如 14.25 之类的确实具有精确的二进制表示,但 14.26 没有。 (另请参阅:C compiler bug (floating point arithmetic)? 观察“10 * 0.1 几乎不是 1.0”和“浮点数就像一小堆沙子;每次移动一个,你就会失去一点沙子并获得一点泥土”。)

      您应该将值转换为整数美分。你也应该避免float;使用double,但优先使用int

      当我将Invalid change 子句中的代码更改为:

              else
              {
                  printf("Invalid change (%e)\n", input2);
                  break;
              }
      

      然后,当我使用参数 14.26 和 14.48 运行程序时,我得到了输出:

      $ ./change 14.26
      You have entered:  14.26
      Invalid change (2.288818e-07)
      Amount of $10: 1
      Amount of $1: 4
      Amount of $0.25: 1
      Amount of $0.01: 1
      $ ./change 14.48
      You have entered:  14.48
      Invalid change (9.999549e-03)
      Amount of $10: 1
      Amount of $1: 4
      Amount of $0.25: 1
      Amount of $0.10: 2
      Amount of $0.01: 2
      $
      

      请注意,错误消息包含换行符。该子句也终止了循环。我可能应该设置一个标志来指示存在错误并抑制更改的输出。 14.26 的计算是正确的,但 14.48 的计算是空头一美分。如您所见,我的诊断会打印出导致问题的值,因此很明显 14.26 剩余的金额很小,而 14.48 的剩余金额不到 1 美分。

      使用数组和整数,你可以这样写:

      #include <stdlib.h>
      #include <stdio.h>
      #include <math.h>
      
      int main(int argc, char *argv[] )
      {
          for (int n = 1; n < argc; n++)
          {
              double input = atof(argv[n]);
              int    cents = (100 * input + 0.5);
              printf("You have entered: %6d.%.2d\n", cents / 100, cents % 100);
              int denom[] = { 2000, 1000, 500, 100, 25, 10, 5, 1, 0 };
      
              for (int i = 0; denom[i] != 0 && cents > 0; i++)
              {
                  if (cents >= denom[i])
                  {
                      int count = cents / denom[i];
                      cents = cents - count * denom[i];
                      printf("Amount of $%2d.%.2d: %i\n", denom[i] / 100, denom[i] % 100, count);
                  }
              }
          }
      
          return 0;
      }
      

      输出:

      $ ./change 14.48 14.26 14.47 14.31  14.00  20 10 5 1 0.25 0.10 0.05 0.01
      You have entered:     14.48
      Amount of $10.00: 1
      Amount of $ 1.00: 4
      Amount of $ 0.25: 1
      Amount of $ 0.10: 2
      Amount of $ 0.01: 3
      You have entered:     14.26
      Amount of $10.00: 1
      Amount of $ 1.00: 4
      Amount of $ 0.25: 1
      Amount of $ 0.01: 1
      You have entered:     14.47
      Amount of $10.00: 1
      Amount of $ 1.00: 4
      Amount of $ 0.25: 1
      Amount of $ 0.10: 2
      Amount of $ 0.01: 2
      You have entered:     14.31
      Amount of $10.00: 1
      Amount of $ 1.00: 4
      Amount of $ 0.25: 1
      Amount of $ 0.05: 1
      Amount of $ 0.01: 1
      You have entered:     14.00
      Amount of $10.00: 1
      Amount of $ 1.00: 4
      You have entered:     20.00
      Amount of $20.00: 1
      You have entered:     10.00
      Amount of $10.00: 1
      You have entered:      5.00
      Amount of $ 5.00: 1
      You have entered:      1.00
      Amount of $ 1.00: 1
      You have entered:      0.25
      Amount of $ 0.25: 1
      You have entered:      0.10
      Amount of $ 0.10: 1
      You have entered:      0.05
      Amount of $ 0.05: 1
      You have entered:      0.01
      Amount of $ 0.01: 1
      $
      

      【讨论】:

        猜你喜欢
        • 2016-04-06
        • 1970-01-01
        • 2010-11-08
        • 2011-08-13
        • 2012-10-06
        • 1970-01-01
        • 1970-01-01
        • 2012-09-21
        • 2010-10-12
        相关资源
        最近更新 更多