你在 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++ 中使用啥来表示定点?的主要内容,如果未能解决你的问题,请参考以下文章

你在 SQL Server 中做啥来创建或更改?

FFT 使用 C++ 定点优化 ARM 设备的性能

我应该用啥来替换 WinAPI Beep() 函数?

C++ 在变量的内存地址上做了啥来“释放”它?

具有替代测量单位的定点/整数表示的名称

我可以使用啥来代替箭头运算符`->`?