到目前为止,这可以读取更简单的十进制数字,如$ 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
答案 0 :(得分:1)
我认为你的问题在于input2 > 0.0
。像input2 >= 0.00001
这样的东西会更好。这是因为浮点在内存中的表示方式。 (x+y) - x - y
不能保证= 0
。
更简单的方法是将输入转换为整数乘以100。
我还建议你删除while循环并用while循环替换所有if语句。
答案 1 :(得分:0)
我相信你还没有覆盖结构。如果有,则需要重新访问代码。事实上,你可以用数组来改进,但结构数组会更好。
请记住,二进制浮点值不能精确表示大多数十进制值。那些像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
$
答案 2 :(得分:0)
你已到达浮点运算不像我们在学校想的那样。 : - )
要将input2
与零进行比较,您需要使用绝对epsilon,其值为FLT_EPSILON的一小部分。这是因为浮点/双精度不能精确地表示所有值,例如double(.1) == 0.1000000000000000055511151231257827021181583404541015625
。为了解决这个问题,您需要确定您的号码何时足够接近&#34;为零。