刚刚完成我的第一周C ++(使用Visual Studio 2017),我写了一个程序,询问用户的金额,并将打印账单和硬币的数量。它起初工作,但有时只打印错误的数字。(当用户输入1.28美元时,它显示1美元,1个季度和2个便士。) 这是我的代码,有什么不对吗?算法或数据类型?
#include<iostream>
using namespace std;
float Q = 0.25;
float D = 0.10;
float N = 0.05;
float P = 0.01;
float Dollar = 1;
float money;
float dollars, quarters, dimes, nickels, pennies;
int main() //to break money into coins.
{
cout << "how many money do u have?" << endl;
cin >> money;
dollars = (int)money;
quarters = (int)((money - dollars*Dollar)/Q);
dimes = (int)((money - dollars*Dollar - quarters*Q) / D);
nickels = (int)((money - dollars*Dollar - quarters*Q - dimes*D) / N);
pennies = (int)((money - dollars*Dollar - quarters*Q - dimes*D - nickels*N) / P);
cout << "$" << money << " can be break into :" << endl;
cout << dollars << " dollars. " << endl;
cout << quarters << " quarters. " << endl;
cout << dimes << " dimes. " << endl;
cout << nickels << " nickels. " << endl;
cout << pennies << " pennies. " << endl;
}
答案 0 :(得分:0)
如何避免在尝试数字时丢失精度? (C ++)
当您从浮点数转换为整数时,小数部分将被截断。为了确保不丢失整数精度(获得正确的“整数”),每次添加0.5到结果,例如:
quarters = static_cast<int>(((money - dollars*Dollar)/Q)+0.5);
但是当结果为否定时,这不起作用: 50.5 - 100 = -49.5 - &gt; +1 = -48.5 - &gt; -48 ...不是49
对于否定词,您希望因此减去0.5。
答案 1 :(得分:0)
我假设,在行
pennies = (int)((money - dollars*Dollar - quarters*Q - dimes*D - nickels*N) / P);
部分(money - dollars*Dollar - quarters*Q - dimes*D - nickels*N)
会产生一个不完全是.03
的值,但下面会有一点。这是由于浮点运算的本质,你应该阅读。鉴于它类似于.029999999995
,除以.01将不会产生3.0,但可能是2.9999999995
。由于你没有舍入,而是将值转换为整数,所以在整个句点之后的整个部分将被抛弃,因此它会产生2个便士。
最简单的方法是对值进行舍入而不是对其进行舍入,这应该会产生正确的值,但这是一个解决问题的hacky解决方案。您也可以尝试使用double
而不是float
,但这也无法解决问题。你可能会得到这个正确的,但相同的仍然可能发生类似的错误。
您可以将整个金额存储为整数(整个便士)
int amountInPennies;
int penniesPerDollar = 100;
int penniesPerQuarter = 25;
int penniesPerDime = 10;
int penniesPerNickle = 5;
int totalDollars = amountPennies / penniesPerDollar;
int totalQuarters = (amountPennies - totalDollars * penniesPerDollar) / penniesPerQuarter;
...
在处理金钱的现实世界应用程序中(嗯,取决于类型),您最有可能使用某种十进制类型而不是float
。根据{{3}},在GNU许可下可以使用具有任意精度算术的库。您仍然可以滚动自己的十进制类型,或多或少 - 执行我在第一种方法中提供的内容。这可能是一个很好的学习练习,但是在现实世界的应用程序中,现成的库可能是更好的选择。