1

到目前为止,它可以读取更简单的十进制数字,例如 $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
4

3 回答 3

1

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

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

我还建议您删除 while 循环并将其中的所有 if 语句替换为 while 循环。

于 2013-02-01T07:15:10.523 回答
0

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

请记住,二进制浮点值不能准确地表示大多数十进制值。诸如 14.25 之类的确实具有精确的二进制表示,但 14.26 没有。(另请参阅:C 编译器错误(浮点算术)?对于观察“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
$
于 2013-02-01T07:23:28.310 回答
0

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

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

于 2013-02-01T07:31:26.397 回答