Если я напечатаю 0.01 или 0.02, программа сразу же выйдет. Что я делаю? Благодарю.
мой пост – это в основном код. Мне нужно добавить некоторые подробности.
#include 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: 0\nDimes: 0\nNickels: 0\nPennies: 0"); if (amount == 0.01) printf("Quarters: 0\nDimes: 0\nNickels: 0\nPennies: 1"); if (amount == 0.02) printf("Quarters: 0\nDimes: 0\nNickels: 0\nPennies: 2"); return (0); }
Объявите свою сравнительную ценность как float.
if (amount == 0.01f) printf("Quarters: 0\nDimes: 0\nNickels: 0\nPennies: 1");
Обратите внимание, что вы можете столкнуться с каким-то неопределенным поведением, непосредственно тестируя равенство float, если вы сделали некоторые вычисления с помощью переменной float.
Каков наиболее эффективный способ для плавающего и двойного сравнения?
Вы должны использовать что-то вроде этого
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
s или не выходите из double
как можно быстрее. Либо используйте библиотеку с фиксированной точкой (немного сложную для того, что вы хотите), либо просто выполните:
int cents = (int)round(amount * 100);
затем вместо этого работайте с cents
. Вы можете сравнить их с содержанием вашего сердца.
В-третьих, если идея состоит в том, чтобы выработать изменения в кварталах, копейках, никелях и пенни, compilation if
заявлений – это не путь, если вам не нужны длинные и неэффективные программы. Вам нужно будет сделать это программно. И это будет намного проще, если у вас есть целое число cents
выше (подсказка: посмотрите на оператор %
).
Я думаю, что мы могли бы масштабироваться и получить относительное сравнение следующим образом:
#define EPSILON (0.000001) if (fabs(a - b) <= EPSILON * fmax(fabs(a), fabs(b))) { }
который является более надежным, чем абсолютное сравнение:
if (fabs(a - b) <= EPSILON ) { // ... }
которые, возможно, зависят от масштаба. Кстати, оптимальный масштаб зависит также от функции, мы не должны использовать ту же формулу для журнала и для греха.