Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用C+;存储货币值的最佳方法+;_C++_Currency - Fatal编程技术网

C++ 用C+;存储货币值的最佳方法+;

C++ 用C+;存储货币值的最佳方法+;,c++,currency,C++,Currency,我知道,由于舍入错误,浮点不适合存储货币值。在C++中有表示货币的标准方法吗? 我在boost库中查找了一下,没有找到任何关于它的信息。在java中,BigInteger似乎是这样,但是我在C++中找不到等价的东西。我可以编写自己的money类,但如果有测试,我宁愿不这样做。这取决于您对舍入的业务要求。最安全的方法是存储具有所需精度的整数,并知道何时/如何应用舍入。我建议您保留一个以美分为单位的变量,而不是美元。这将消除舍入误差。以标准美元/美分格式显示它应该是一个视图问题。在实际金融系统中处理

我知道,由于舍入错误,浮点不适合存储货币值。在C++中有表示货币的标准方法吗?
我在boost库中查找了一下,没有找到任何关于它的信息。在java中,BigInteger似乎是这样,但是我在C++中找不到等价的东西。我可以编写自己的money类,但如果有测试,我宁愿不这样做。

这取决于您对舍入的业务要求。最安全的方法是存储具有所需精度的整数,并知道何时/如何应用舍入。

我建议您保留一个以美分为单位的变量,而不是美元。这将消除舍入误差。以标准美元/美分格式显示它应该是一个视图问题。

在实际金融系统中处理过这一问题后,我可以告诉您,您可能希望使用精度至少为小数点后6位的数字(假设美元)。希望既然你谈论的是货币价值,你就不会在这里失控。有一些建议将十进制类型添加到C++中,但我不知道实际上还有哪些。 <>这里使用的最好的本地C++类型是长双倍。

其他只使用int的方法的问题是,您必须存储的不仅仅是美分。通常,金融交易会乘以非整数值,这会给您带来麻烦,因为将100.25美元换算为10025*0.000123523(例如APR)会导致问题。你最终会在浮点土地上结束,而转换将花费你很多

现在这个问题在大多数简单的情况下都不会发生。我给你举一个确切的例子:

给定数千个货币值,如果将每个值乘以一个百分比,然后将它们相加,那么最终得到的数字将不同于如果没有保留足够的小数位数,则将总数乘以该百分比得到的数字。这在某些情况下可能会奏效,但你通常会很快就被罚下几便士。根据我的一般经验,确保精度保持在小数点后6位(确保剩余精度适用于整数部分)

也要明白,如果你用一种不太精确的方式做数学运算,你用什么类型来存储它并不重要。如果你的数学是在单精度的土地上进行的,那么你是否在双精度的土地上存储它也没关系。您的精度将精确到最不精确的计算



这就是说,如果你只做简单的加法或减法运算,然后存储数字,那么你就没事了,但一旦出现比这更复杂的事情,你就有麻烦了。

我建议使用长整数以最小面额存储货币(例如,美国货币是美分),如果使用的是十进制货币

非常重要:确保根据实际包含的内容命名所有货币值。(例如:账户余额)这将避免很多问题


(另一个例子是百分比。当某个值实际上包含一个不乘以100的比率时,千万不要将其命名为“XXX_percent”。

查看相对较新的值。它专门用于金融应用程序,实现了一些。

该库具有“bignum”实现,您可以使用它进行处理货币所需的任意大小的整数计算。请参阅文档(警告:这是非常不完整的,但提供了完整的算术运算符)。

无论您选择哪种类型,我建议将其包装在“typedef”中,以便您可以在不同的时间更改它。

一个选项是将$10.01存储为1001,并以便士进行所有计算,显示值时除以100D

或者,使用浮动,并且仅在最后可能的时刻循环

通常,通过改变操作顺序可以缓解这些问题

使用(value*10)/100,而不是10%折扣的值*.10,这将大有帮助。(请记住.1是一个重复的二进制)

整数,始终--将其存储为美分(或您编程时使用的最低货币)。问题是,不管您使用浮点做什么,总有一天您会发现如果使用浮点,计算结果会有所不同。在最后一分钟取整并不是解决办法,因为实际货币计算是在进行时取整的


您也无法通过更改操作顺序来避免这个问题——当您有一个百分比使您没有正确的二进制表示时,这将失败。如果你只差一分钱,会计师们就会发疯。

我们的金融机构使用“双倍”。因为我们是一家“固定收入”商店,所以我们有很多讨厌的复杂算法,无论如何都要用到double。诀窍在于确保最终用户的演示不会超出double的精度。例如,当我们有一个总额为万亿美元的交易列表时,我们必须确保不会因为舍入问题而打印垃圾。

不要将其存储为美分,因为在税收和利息相乘时,您会很快累积错误。至少,多保留两个有效数字:$12.45将存储为124500。如果你把它保存在一个有符号的32位整数中,你将有200000美元(正数或负数)。如果您需要更大的数字或更高的精度,有符号64位整数可能会为您提供长期所需的所有空间

将该值封装在类中,为您提供一个位置来创建这些值、对它们执行算术运算并格式化它们以供显示,这可能会有所帮助。这还将为您提供一个中心位置,以便携带存储的货币(美元、加元、欧元等)。

了解您的ran
#include <iostream>
#include <iomanip>
#include <boost/multiprecision/cpp_dec_float.hpp>

int main()
{
    float bogus = 1.0 / 3.0;
    boost::multiprecision::cpp_dec_float_50 correct = 1.0 / 3.0;

    std::cout << std::setprecision(16) << std::fixed 
              << "float: " << bogus << std::endl
              << "cpp_dec_float: " << correct << std::endl;
          
    return 0;
}