C ++ Money Class - 存储和舍入美分

时间:2014-09-17 19:35:20

标签: c++ floating-point-precision

提前谢谢。 我正在为我们创建自己的货币/货币类的类编写C ++作业。我无法弄清楚为什么我的漂浮不能给我足够的精确度。

实现:

private:
    long int DOLLARS;
    short int CENTS;

Currency::Currency(float tmpMoney)
{
// cout << "tmpMoney is: " << tmpMoney << endl;
    int tmpDollar;
    float tmpCent;
    tmpDollar = static_cast<int>(tmpMoney);
    tmpCent = (tmpMoney-tmpDollar)*100;
    DOLLARS = tmpDollar;
    CENTS = tmpCent;
    }

主程序:

Currency c1(2342.59);
Currency c2(2342.515); // there is no half cent coin, round it to 2342.52

如果输出'tmpMoney',它只给我(对于c2)2345.51。 如果价值甚至没有那么远,我不确定如何舍入.515。

2 个答案:

答案 0 :(得分:3)

使用浮点类型构建货币类型是个坏主意。

7位十进制数通常超过float精度。您仍然可以通过以下方式获得所需的输出:

float tmpMoney = 2342.515;
cout << setprecision(7) << tmpMoney << endl;
// 2342.515

但内部表现远非完美:

cout << setprecision(10) << tmpMoney << endl;
// 2342.514893

如果数字足够大,你会失去更多:

float tmpMoney = 123456789.12;
cout << setprecision(12) << tmpMoney << endl;
// 123456792

所以你可能会决定使用double,但是你应该非常小心,因为对于足够多的数字你会得到同样的错误:

double tmpMoney = 3333333333333333.42; // 17 digits 
cout << setprecision(18) << tmpMoney << endl;
// 3333333333333333.5

如果您有可能拥有此类号码,请不要使用Currency初始化double

我建议您只使用像Currency(int dollars, int cents)这样的构造函数。

您还可以查看this question以获取一些见解。

答案 1 :(得分:1)

    #include <cmath>

    CENTS = round(tmpCent);

由于浮点表示,这可能并不总能给出正确的结果。你能得到的最接近的是epsilon的误差,比如

    #define EPS 0.000001

然后你可以做

    CENTS = round(tmpCent + EPS);

请注意,这将接受表示为0.499999 <= x < 0.5

的值

最好使用double而不是float来保持精确度尽可能接近。