如果我键入 0.01 或 0.02,程序会立即退出。我该怎么办?
#include <stdio.h>
char line[100];
float amount;
int main()
{
printf("Enter the amount of money: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%f", &amount);
if (amount == 0.0)
printf("Quarters: 0nDimes: 0nNickels: 0nPennies: 0");
if (amount == 0.01)
printf("Quarters: 0nDimes: 0nNickels: 0nPennies: 1");
if (amount == 0.02)
printf("Quarters: 0nDimes: 0nNickels: 0nPennies: 2");
return (0);
}
浮点数和双重比较最有效的方法是什么?
你应该使用这样的东西
bool isEqual(double a, double b)
{
return fabs(a - b) < EPSILON;
}
或者这个
#define ISEQUAL(a,b) ( fabs((a) - (b)) < EPSILON)
并定义 EPSILON
#define EPSILON (0.000001)
首先,不要试图比较double
s,或者比较float
s,或者比较double
s和float
s(例外:与0比较是可以的,可以说是所有整数)。其他答案给出了很好的链接,但我特别喜欢:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
其次,如果您正在处理一笔钱,请不要使用double
,或者尽快摆脱double
。要么使用定点库(对于你想要的有点复杂),要么干脆做:
int cents = (int)round(amount * 100);
然后改用cents
。您可以将这些与你内心的内容进行比较。
第三,如果这里的想法是计算季度、一角钱、镍币和便士的变化,那么收集if
语句不是要走的路,除非你喜欢冗长而低效的程序。您需要以编程方式执行此操作。如果你有上面的cents
整数,这将容易得多(提示:查看%
运算符)。
我们可以针对一个因素进行缩放并进行这样的相对比较:
#define EPSILON (0.000001)
if (fabs(a - b) <= EPSILON * fmax(fabs(a), fabs(b))) {
}
这比绝对比较更可靠:
if (fabs(a - b) <= EPSILON ) {
// ...
}
这可能取决于规模。顺便说一下,具有最佳比例也取决于函数,我们不应该对日志和罪恶使用相同的公式。
这个答案的反对票是当之无愧的,它错误地提倡一个简单的平等测试。虽然这是未定义的行为,不应鼓励,但即便如此,它有时也会起作用。
切勿测试浮点值的相等性。相反,请使用 epsilon 值针对某个范围测试您的变量,因为这个答案暗示了它。
举个例子:
#include <stdio.h>
#include <math.h>
#define EPSILON 0.00001f
int main() {
float a = 3.234324333f;
float b = a;
b += 1;
b -= 1;
printf("a value is %fn", a);
printf("b value is %fn", b);
printf("na == b ?n");
if (a == b) {
printf("truen");
} else {
printf("falsen");
}
printf("a ~= b with epsilon = %f ?n", EPSILON);
if (fabs(a - b) <= EPSILON) {
printf("truen");
} else {
printf("falsen");
}
return 0;
}
运行时:
a value is 3.234324
b value is 3.234324
a == b ?
false
a ~= b with epsilon = 0.000010 ?
true