【问题标题】:How do I use decimal (float) in C++?如何在 C++ 中使用小数(浮点数)?
【发布时间】:2012-02-16 17:57:11
【问题描述】:

根据IEEE 754-2008

共有三种二进制浮点基本格式(可使用 32、64 或 128 位编码)和两种十进制浮点基本格式(可使用 64 或 128 位编码)。

这张图表在它下面。在 C++ 中,我相信 floatdouble 是单精度和双精度(binary32binary64)。

Name        Common name         Base  Digits E min  E max   Digits  E max
binary32    Single precision    2     23+1   −126   +127    7.22    38.23
binary64    Double precision    2     52+1   −1022  +1023   15.95   307.95
binary128   Quadruple precision 2     112+1  -16382 +16383  34.02   4931.77
decimal32                       10    7      −95    +96     7       96
decimal64                       10    16     −383   +384    16      384
decimal128                      10    34     −6143  +6144   34      6144

我可以为decimalX 使用什么类/结构,有什么可以用于binary128 的吗?这些类/结构是标准的还是非标准的?

【问题讨论】:

  • 什么系统?例如,对于 PowerPC Mac,long double 等效于图表中的 binary64,可选择使用 binary128,而在 Intel Mac 上,long double 是 80 位。 (虽然后者有 128 位存储)
  • C++ 没有详细说明 floatdoublelong double 是如何表示的。据你所知,他们三个都可能是decimal128

标签: c++ floating-point decimal


【解决方案1】:

除了32位float和64位double之外,GCC还提供__float80__float128_Decimal32_Decimal64_Decimal128;对于 ARM 目标,它还提供半精度 __fp16

英特尔 CPU 使用旧的标量 x87 FPU 指令(但不使用 SSE 向量指令)在硬件中支持 80 位浮点数。我不知道有任何主流 CPU 硬件支持十进制 FP 类型。

看起来当前的微软编译器为 doublelong double 提供了 64 位,但旧的编译器为 long double 提供了 80 位。

在此处查看文档:

【讨论】:

  • 问题未标记 GCC。问题标记为 C++。
  • 然而 OP 似乎发现具体信息很有价值。令人惊讶,不是吗?
  • @LightnessRacesinOrbit 这个答案谈到了硬件和软件。我不在乎标准定义了什么(本质上是“我们不支持”)。我关心如何使用它和硬件支持。这个答案也很清楚,它是一个编译器扩展。 4 人中也只有 2 人真正回答了题目。我如何在 C++ 中使用它。我确实给了你一个支持标准文本的投票,很明显 C++11 本身不支持它。
  • @RussellBorogove:不;这将是题外话,尽管它无疑对某些人有价值。真的很好吃。
  • 我应该用gccvisual c++recipes标记这个问题吗?
【解决方案2】:

C++ 没有指定 floats 必须是 32 位或 doubles 必须是 64 位。它甚至不需要一个字节中有 8 位(尽管确实必须有至少 8)。

[C++11: 3.9.1/8]: 共有三种浮点类型:floatdoublelong doubledouble 类型提供的精度至少与 float 一样高,long double 类型提供的精度至少与 double 一样高。 float 类型的值集是double 类型值集的子集; double 类型的值集是long double 类型的值集的子集。 浮点类型的值表示是实现定义的。整数和浮点类型统称为算术类型。标准模板std::numeric_limits (18.3) 的特化应指定实现的每种算术类型的最大值和最小值。

请参阅您的工具链和平台的文档以了解其类型大小。它可能支持long double,而这又可能是您想要的。

【讨论】:

  • 在 x86 和 x64 平台上,他们倾向于遵循图表,不是吗?
  • @MooingDuck:我特此选择不讨论实施细节。
【解决方案3】:

英特尔有一个decimal floating-point library,它可以在 Mac、Linux、HP/UX 或 Solaris 上与 ICC 或 GCC 一起使用;或 Windows 上的 ICC 或 CL 编译器。它不如在内置类型上使用运算符有用。如果您使用的是 C++,也许有人已经编写了有用的类来覆盖所有必要的运算符。

【讨论】:

    【解决方案4】:

    C++ 不提供十进制类型;唯一的浮点类型是 floatdoublelong double

    C++ 也没有指定它们使用 IEEE754 表示,或者它们具有任何特定的大小。唯一的要求是double 提供的精度至少与float 一样高,并且long double 提供的精度至少与double 一样高。

    【讨论】:

    • 我什至不知道有任何编译器提供十进制作为扩展名。
    【解决方案5】:

    如果您想要内置运算符的便利性,但又不想自己编写,我建议您查看Bloomberg Finance's open-source C++ libraries on GitHub。特别是,BDE 包包含 IEEE 754“十进制 32/64/128”实现(请参阅bdldfp_decimal.h)

    这个库的好处是它支持多种不同的 IEEE 754 后端实现,包括 C99 参考实现、GCC 附带的 decNumber 实现以及英特尔的开源 IntelDFP 库(有关详细信息,请参阅bdldfp_decimalplatform.h)。它还支持可配置的字节序。

    【讨论】:

    • 彭博每天都在使用它。如果没有像这种实现这样全面的东西,以数学上正确的方式设计任何类型的交易、市场数据或其他与金融相关的应用程序实际上是不可能的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    • 2011-12-15
    • 1970-01-01
    相关资源
    最近更新 更多