C/C++中的固定宽度浮点数

kqlmhetl  于 2023-10-16  发布在  C/C++
关注(0)|答案(7)|浏览(173)

int通常是32位,但在标准中,int不保证具有恒定的宽度。因此,如果我们想要一个32位的int,我们包括stdint.h并使用int32_t
有没有一个等价的浮动?我意识到浮点数有点复杂,因为它们不是以一种同构的方式存储的,即。符号、指数、有效数。我只想要一个double,它保证以64位存储,其中有1个符号位,10位指数和52/53位有效位(取决于您是否计算隐藏位)。

zhte4eai

zhte4eai1#

根据the current C99 draft standard,附件F,这应该是两倍。当然,这是假设您的编译器满足这部分标准。
对于C++,我已经检查了0x草案和1998年版本的标准草案,但似乎都没有像C99标准那样指定任何关于表示的内容,除了numeric_limits中的bool指定IEEE 754/IEC 559在该平台上使用,就像Josh Kelley提到的那样。
很少有平台不支持IEEE 754,但是-它通常不值得设计另一种浮点格式,因为IEEE 754定义良好,工作得很好-如果支持,那么它是一个合理的假设,double确实是64位(IEEE 754-1985称该格式为双精度,毕竟,所以它是有意义的)。
万一double不是双精度的,那么就构建一个健全性检查,这样用户就可以报告它,而您可以单独处理该平台。如果平台不支持IEEE 754,那么除非您自己实现它,否则无论如何都不会得到该表示。

mnowg1ta

mnowg1ta2#

虽然我不知道有什么类型可以保证特定的大小和格式,但在C++中确实有一些选项。您可以使用<limits>头及其std::numeric_limits类模板来确定给定类型的大小,std::numeric_limits::digits告诉您尾数中的位数,std::numeric_limits::is_iec559应该告诉您该类型是否遵循IEEE格式。(有关在位级别操作IEEE数字的示例代码,请参见Google Test的gtest-internal.h中的FloatingPoint类模板。

k2fxgqgv

k2fxgqgv3#

另一个问题是浮点数的表示。这通常取决于您正在运行的硬件(但不总是)。大多数系统使用IEEE 754浮点标准,但其他系统也可以有自己的标准(例如VAX计算机)。
IEEE 754 http://en.wikipedia.org/wiki/IEEE_754-2008的维基百科解释

km0tfn4u

km0tfn4u4#

据我所知,float/double没有变化。浮点数一直是32位,双精度数一直是64位。浮点语义相当复杂,但

#include <limits>

如果你不需要std::numeric_limits中的所有内容,boost.numeric.bounds是一个更简单的接口。

wfypjpf4

wfypjpf45#

不幸的是,这也不能保证。您必须在<limits>中检查numeric_limits< T >
但话说回来,我从来没有听说过一个双精度型不是64位长的实现。如果你只是假设,你可能会逃脱。

bnl4lu3b

bnl4lu3b6#

在C++23标准(ISO/IEC 14882:2023)中,有<stdfloat>
cppreference.com提到以下内容:

namespace std {
  #if defined(__STDCPP_FLOAT16_T__)
    using float16_t  = /* implementation-defined */;
  #endif
  #if defined(__STDCPP_FLOAT32_T__)
    using float32_t  = /* implementation-defined */;
  #endif
  #if defined(__STDCPP_FLOAT64_T__)
    using float64_t  = /* implementation-defined */;
  #endif
  #if defined(__STDCPP_FLOAT128_T__)
    using float128_t = /* implementation-defined */;
  #endif
  #if defined(__STDCPP_BFLOAT16_T__)
    using bfloat16_t = /* implementation-defined */;
  #endif
}

我不知道C的等价物。但是,你可以尝试一下这里建议的东西:https://stackoverflow.com/a/72440929/9962617

rjee0c15

rjee0c157#

这种“固定宽度类型”的最大问题之一是很容易出错。你可能不想要一个32位的整数。有什么意义?你想要的是一个至少可以存储1>>31的整数类型。这是long int。你甚至不需要<stdint.h>
类似地,你的脚本语言可以实现一个FP类型,只要底层C++ float是 * 至少 * 32位就可以工作。请注意,这仍然不能给予精确的行为。我相当肯定C++不保证-1.0/-3.0==1.0/3.0

相关问题