固定大小的浮点数类型

120

stdint.h(C99)、boost/cstdint.hppcstdint(C++0x)头文件中,除其他类型外,还有一个名为 int32_t 的类型。

是否存在类似的固定大小的浮点类型?例如 float32_t


4
为什么你需要那样的东西? - Khaled Alshaya
49
当你拥有一个带有浮点数值的数据结构,并且想要确切知道它的大小时,你需要类似这样的东西。 - mob
5
如果您只需要知道大小,可以使用sizeof运算符。像这样的类型在算法要求具有已知特定大小时很有用。 - Stephen Canon
6
是的,当您想要保证大小时可以使用。比如说,您的数据结构实例将适合于64位并且可以通过值传递给某些外部库。 - mob
9
考虑使用跨平台的序列化库。如何利用 sizeof 来解决浮点类型数据的一致编组与解组问题? - Kyle Strand
显示剩余3条评论
5个回答

51

目前在C或C++标准中并不存在这样的东西。事实上,甚至不能保证float一定是二进制浮点数格式。

有些编译器保证float类型将是IEEE-754 32位二进制格式,而有些则不保证。实际上,在大多数非嵌入式平台上,float实际上是IEEE-754的single类型,尽管通常会有关于某些编译器在更广泛的格式中计算表达式的注意事项。

有一个工作组正在讨论为IEEE-754 2008修订版添加C语言绑定,该工作组可以考虑建议添加此类typedef。如果这被添加到C中,我预计C++标准最终也会跟进。


3
无论是否符合IEEE-754标准,它都不能防止字节序可移植性问题。 - Mark B
1
@Pietro:更改语言不会影响您的硬件兼容性,它只会排除一些硬件的合规性。IEEE FP保证如何帮助可移植性? - Potatoswatter
2
@Potatoswatter:这将鼓励硬件供应商提供符合标准的解决方案。如果部分a支持标准C而不需要软浮点库的黑客,而部分b则不支持,那么部分a就具有市场优势。 - Stephen Canon
2
@Potatoswatter:(几乎)没有人关心硬件的速度。我们关心的是运行在硬件上的软件的速度。如果运行软件的硬件符合标准,并且软件不需要检测和修补15个不同的特殊情况,那么软件可以更快。 - Stephen Canon
8
通过让您的代码无法在一些小众架构上编译,您如何获得更好的可移植性?如果您依赖浮点数采用IEEE标准,那么您的代码已经可以在每个采用IEEE标准的实现上运行,而其他系统则不行。如果C ++保证了IEEE兼容性,您的代码并不会变得更加可移植,只是排除了它可能在那些不兼容的架构上运行的可能性。您的逻辑完全错误。 - jalf
显示剩余5条评论

39

如果您想知道您的float是否为IEEE 32位类型,请检查std::numeric_limits<float>::is_iec559。这是一个编译时常量,而不是函数。

如果您想更加可靠,还应该检查std::numeric_limits<float>::digits,以确保它们没有偷偷使用IEEE标准双精度作为float。 它应该是24。

当涉及到long double时,检查digits更加重要,因为有几种IEEE格式可以合理地使用:128位(digits = 113)或80位(digits = 64)。

由于通常希望使用浮点硬件(如果有的话),而不是回退到软件实现,因此将float32_t作为此类并不实际。


在OS X上(无论是32位还是64位的Intel),‘long double’格式恰好是IEEE-754双精度扩展格式,以小端序存储。它没有任何奇怪的地方。字节0-7保存尾数字段,字节8和9保存指数和符号字段。 - Stephen Canon
@Stephen:那是个好消息 :v)。那个数字和我发布的一致吗? - Potatoswatter
1
请记住,双扩展精度(与其他754格式不同)具有显式的前导有效数字位,因此5.0L的有效数字为a000000000000000。它的无偏指数为+2,双扩展指数偏差为3fff,因此5.0L的偏置指数为4001。以小端顺序存储时的实际字节模式为00 00 00 00 00 00 00 a0 01 40,如果将其视为两个小端顺序的64位整数,则可以看到您观察到的完全相同的结果。 - Stephen Canon
“01 40”就是我写的(上面的字节不属于数字,因此它们不需要为零)。为什么“a0”会在与“01 40”相同的半部分?“a0”是有效数字的高位字节(位56:63),因此它应该(而且确实)出现在第七个字节的编码中,这是在低地址的64位内存块中。我也不确定你所说的“旋转”是什么意思;这里没有发生旋转。 - Stephen Canon
@Stephen:编码长度为16个字节,而不是8个字节。符号+指数有16位,因此尾数的最高字节应该在104:111或小端字节13。 - Potatoswatter
显示剩余8条评论

25

如果你认为像float32_t和float64_t这样的类型定义在任何情况下都不实用,那么你可能已经太习惯于自己熟悉的操作系统和编译器,不能从自己的小窝里走出来看看外面的世界。

存在一些硬件能够本地运行32位或64位IEEE浮点数操作。有时这些系统甚至需要相互通信,在这种情况下,非常重要的是要知道每个平台上double类型是32位还是64位。如果32位平台基于其他平台的64位值进行过多计算,我们可能需要根据时间和速度要求将其转换为较低精度。

个人感觉使用浮点数和双精度浮点数时,除非我确切地知道它们在我的平台上有多少位,否则会感到不安。如果我要通过某种通信渠道将它们传输到另一个平台,那么这种不安更加明显。


我个人感觉在不清楚我的平台上有多少位时,使用浮点数和双精度数会让我感到不舒服。如果我需要将它们通过某些通信渠道传输到另一个平台上,那么这种感觉就更加强烈了。
  • 你的意思是你使用文本文件格式吗?但这样做的缺点是文件大小:32位浮点数需要4个字节;而以文本形式表示,只能表示四位数...
- Pietro

10

C++23引入了符合IEEE 754标准的定点浮点数。

以下是实例化64位浮点数的方法:

#include <stdfloat>
int main()
{
    std::float64_t f = 0.1f64;
}

实现方案可以在这里找到。


1
该功能是在GCC 13中引入的。 - NullPointerException
1
值得指出的是,std::float64_t并不保证存在。只有在目标架构支持IEEE浮点数的情况下才需要它 - 例如,为IBM大型机编译的编译器可能决定支持传统的IBM浮点数格式。 - undefined

2

5
承认,十进制类型并非IEEE 754浮点数类型。 - Mike DeSimone
等等!我们还需要decimal24,这样可以更轻松地读取带有24位采样的wav文件! - tjwrona1992

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接