你在 C++ 中使用啥来表示定点?
Posted
技术标签:
【中文标题】你在 C++ 中使用啥来表示定点?【英文标题】:What do you use for fixed point representation in C++?你在 C++ 中使用什么来表示定点? 【发布时间】:2008-09-28 16:36:00 【问题描述】:我正在寻找一种用于财务数据的定点标准,您知道有什么值得尝试的吗?你对那个手工定点类的性能有什么经验吗?
【问题讨论】:
奇怪的是,有赏金时允许提出题外话。 看看 Martin Fowler 的Money pattern! @claptrap 在这里特别解释off-topic
(看不到任何接近的投票)。我知道你的意思,但 OP 似乎正在寻找标准解决方案,而没有任何(AFAIR)。可能是一些 c++11 习语可能会有所帮助...
@AugustoRadtke 恕我直言,您的问题可能更多在于平衡货币数学,而不是简单地使用没有任何交易上下文的定点小数。
@πάνταῥεῖ 在寻找工具/库的意义上偏离主题,但是当设置赏金时,您无法投票关闭它 - 这就是为什么没有关闭投票的原因。没关系,随便你的船。
【参考方案1】:
Dobb 博士有一篇关于 C++ 中定点算术类型的可能实现的文章。签出this。
【讨论】:
这是这里唯一可以将美元存储为美分的代码的答案。【参考方案2】:哎哟。金融系统很棘手,您的主要问题不是定点数学,而是舍入误差。
您可以拥有一个漂亮的电子表格,其中包含按客户类型划分的折扣和包含增值税的奇妙计算。你做了一个总数,你把它提交给一个会计师,他说这些值都是错误的。原因:输出的格式可能只有 2 位小数,但在内部该值具有浮点数或双精度数的所有小数位。他们确实加起来了。
您需要了解自己的财务状况并决定基准值的位置。意思是会计师将检查哪些值(是的,这需要业务知识,消除“棘手”的部分)。
在将值保存到持久形式(数据库、文件、内存...)之前,您会截断乘法和除法可能添加的额外小数位。
N 位小数的快速而肮脏的解决方案: ((double)((int)(Value * N * 10.0)))/10.0
当然,您需要准确检查您的财务需要哪种四舍五入。
【讨论】:
您的“N 个小数位的快速而肮脏的解决方案”应该涉及 10^N。 "你的主要问题不是定点数学,问题是舍入误差。"问题是舍入错误。 解决方案是定点数学【参考方案3】:我使用我的定点数学课。它旨在或多或少地替代浮动/双打。 http://codef00.com/coding
编辑:作为旁注,我个人不会为此目的使用定点类。相反,我只会存储美分的数量(或十分之一美分,或需要的百分之一美分)。 A 直接用它做数学。然后我会在向用户显示时适当地缩放值。
【讨论】:
如果class
增加了开销?使用像eli.thegreenplace.net/files/prog_code/fixnum.cpp.txt 这样的宏不是更好吗?
你怀疑类会增加什么开销?为什么你认为宏可以更快?
@EvanTeran:我也写过一个定点类,但是当有人观察到a*b/c
是一个常见的操作,你的代码和我的代码都增加了不必要的开销,这是非常固定的。
@MooingDuck:当我说“定点”时,Dobb 博士的解决方案并不完全符合我的想法,但我明白你的意思。在他们的实现中,小数点不是固定为位,而是固定为十进制数字。这正是我建议他们在课堂上隐藏细节的原因。无论哪种方式,您仍然会遇到舍入错误,只是针对不同的值。例如,你将如何表示 (1/3) 美元?同样的问题,只是在不同的基地
@EvanTeran:除了乘法、输入、输出、转换......我们在 C++ 中为这类问题提供了解决方案。我们将东西包装在一个类中。这个类的名字是:fixed_point<100000>
【参考方案4】:
IBM 的 decNumber++
【讨论】:
看来 decNumber++ 是浮点数,而不是定点数。【参考方案5】:ISO 指定了 C 的十进制扩展名 TR 24732 和 C++ 的 TR 24733。它们可通过ISO website 购买。它还不是任何已发布的 C++ 标准的一部分。 GCC 提供built-in types 和library implementation of it。另一个实现是available from Intel。将其包含在 C++ 中的最新推动是 here。
【讨论】:
gcc “使用十的基数”所以我猜它是为accuracy
设计的,但我需要性能,所以很可能我需要“二的基数”实现。当我正在寻找具有更好性能的定点实现时,似乎英特尔的实现是“浮点”。
这些是浮点类型,与float
具有相同的舍入误差。这些不是固定点。【参考方案6】:
64 位 int 类型应该足以表示所有以美分为单位的财务价值。
对于正确的某些定义,您只需要小心正确地舍入百分比即可。
【讨论】:
另见***.com/questions/61872/…。 实际上我不想只存储财务价值。我想做各种数学。我将一个值分配给另一个值来计算比率等。所以我认为我需要库或类似的东西。 @lhf:这不仅仅是“只是”小心舍入。也就是说,正确的乘法和除法比简单的乘法和决定要复杂得多。此外,在转换和 IO 过程中存在明显的类型漏洞。最好将它包装在一个类中。【参考方案7】:尝试直接回答
Markus Trenkwalder 有一个支持一些数学函数 - http://www.trenki.net/content/view/17/1/:
该库包含用于处理定点数的各种函数(乘法、除法、求逆、sin、cos、sqrt、rsqrt)。它还包含一个 C++ 包装类,可用于大大简化使用定点数的工作。我将此定点数类与我的 vector_math 库结合使用,以获得定点向量数学库。与浮点版本相比,这样做使 3D 计算快得多。
作者特意说他的平台不支持浮点,这就是他这样做的原因。另外,请注意,它是用于 3D 渲染,问题是针对财务数据,我们需要一个好的数学函数库......
IEEE 754-2008 Decimal Floating-Point Arithmetic 规范,针对金融应用
这看起来像是一种处理财务数据的既定方法,得到了很好的支持(来自英特尔和 IEEE)-http://software.intel.com/en-us/articles/intel-decimal-floating-point-math-library
引用:
IEEE 754-2008 Decimal Floating-Point Arithmetic 规范,针对金融应用,特别是在法律要求必须使用十进制而不是二进制浮点运算的情况下(因为使用二进制浮点运算执行的计算可能引入小但不可接受的错误)。
虽然它不是定点,但我认为它对于寻求此问题答案的人非常有用。
【讨论】:
实际上,查看 Markus Trenkwalder 的代码,它似乎无法处理非 2 次方基数,例如以美分表示的美元。以上是关于你在 C++ 中使用啥来表示定点?的主要内容,如果未能解决你的问题,请参考以下文章