所以我写了这个小练习程序,告诉您所需数量的镍和美分。我不理解为什么即使数学是正确的,程序也会输出0美分。我无法理解问题所在。
// Example program
#include <iostream>
using namespace std;
int main()
{
const double nickels{0.05};
const double cents{0.01};
int amt_needed_nickels{0}, amt_needed_cents{0};
double amt_val{0.06f}; // for 0.06 cents
double amt_val_copy{amt_val};
amt_needed_nickels = amt_val / nickels;
if(amt_needed_nickels != 0)
amt_val -= (nickels * amt_needed_nickels);
amt_needed_cents = amt_val / cents;
cout << "If it costs $" << amt_val_copy << ", you'll need:\nNickels: " << amt_needed_nickels << "\nCents: " << amt_needed_cents << "\n";
cout << "Even though amt_val is " << amt_val << ", and cents is also " << cents << ", and 0.01/0.01 does equal 1, why is amt_needed_cents not 1?\n";
}
公平地说,我知道我是否将const double cents {0.01}更改为const float cents {0.01},并从double amt_val {0.06f}中删除f;加倍amt_val {0.06};它会起作用,但是我无法理解表面下到底发生了什么。为什么程序在上面的amt_needed_cents中给出0,而在其他情况下给出1?// Example program
#include <iostream>
using namespace std;
int main()
{
const double nickels{0.05};
const float cents{0.01};
int amt_needed_nickels{0}, amt_needed_cents{0};
double amt_val{0.06}; // for 0.06 cents
double amt_val_copy{amt_val};
amt_needed_nickels = amt_val / nickels;
if(amt_needed_nickels != 0)
amt_val -= (nickels * amt_needed_nickels);
amt_needed_cents = amt_val / cents;
cout << "If it costs $" << amt_val_copy << ", you'll need:\nNickels: " << amt_needed_nickels << "\nCents: " << amt_needed_cents << "\n";
cout << "I know this is correct, but I don't know what the compiler is thinking with this as compared to the other\n\n";
}
最佳答案
浮点计算并不精确,在进行数学运算时会得到很小的差异,如果您尝试检查数字的精确相等性,则会破坏程序。例如,1.2 * 3
并不完全是3.6
(请注意,这并不意味着所有计算都是不精确的:例如,乘以2
的任何幂总是正确的:诸如1.5 * 2
和1.1 / 4
之类的东西总能给出最佳答案)。这是因为像1/10
和1/100
这样的十进制分数不能精确地用二进制表示,这在我们的硬币基于1/100
(美分)的情况下是一个问题。
在您的程序中,您应该通过将所有值转换为美分来将硬币表示为整数,然后一切正常。也就是说,您知道您将要处理的最大分母是100
,因此您最好将所有内容乘以100
。因此,nickels
将是5
,cents
将是1
,所有计算都将是精确的。
为避免混淆,这是整数代码:
int dollars = 100, nickels = 5, cents = 1;
int amt_needed_dollars = amt_val / dollars;
amt_val -= amt_needed_dollars * dollars;
int amt_needed_nickels = amt_val / nickels;
amt_val -= amt_needed_nickels * nickels;
// skipped dividing by cents, because it's '1' anyway
int amt_needed_cents = amt_val;
关于c++ - double,float,{0.0},{0.0f},有什么大不了的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62826117/