Ran*_*tep 4 c c++ floating-point bit-manipulation
最近,我对在浮点数上使用位移位进行一些快速计算很感兴趣。
为了让它们以更通用的方式工作,我想让我的函数使用不同的浮点类型,可能是通过模板,不仅限于float
and double
,还有“半宽”或“四倍宽”浮点数等等.
然后我注意到:
- Half --- 5 exponent bits --- 10 signicant bits
- Float --- 8 exponent bits --- 23 signicant bits
- Double --- 11 exponent bits --- 52 signicant bits
Run Code Online (Sandbox Code Playgroud)
到目前为止,我认为exponent bits = logbase2(total byte) * 3 + 2
,
这意味着 128 位浮点数应该有 14 个指数位,而 256 位浮点数应该有 17 个指数位。
然而,后来我了解到:
- Quad --- 15 exponent bits --- 112 signicant bits
- Octuple--- 19 exponent bits --- 237 signicant bits
Run Code Online (Sandbox Code Playgroud)
那么,有没有一个公式可以找到它?或者,有没有办法通过一些内置函数来调用它?
C 或 C++ 是首选,但对其他语言开放。
谢谢。
C++ 通过std::numeric_limits
模板提供此信息:
#include <iostream>
#include <limits>
#include <cmath>
template<typename T> void ShowCharacteristics()
{
int radix = std::numeric_limits<T>::radix;
std::cout << "The floating-point radix is " << radix << ".\n";
std::cout << "There are " << std::numeric_limits<T>::digits
<< " base-" << radix << " digits in the significand.\n";
int min = std::numeric_limits<T>::min_exponent;
int max = std::numeric_limits<T>::max_exponent;
std::cout << "Exponents range from " << min << " to " << max << ".\n";
std::cout << "So there must be " << std::ceil(std::log2(max-min+1))
<< " bits in the exponent field.\n";
}
int main()
{
ShowCharacteristics<double>();
}
Run Code Online (Sandbox Code Playgroud)
示例输出:
浮点基数为 2。 有效数中有 53 个基数为 2 的数字。 指数范围从 -1021 到 1024。 所以指数字段中必须有 11 位。
C还提供了信息,通过宏定义等DBL_MANT_DIG
所定义<float.h>
的,但该标准定义了仅针对类型的名称float
(前缀FLT
), (double
),DBL
和long double
(LDBL
),所以在C实现一个支持附加的浮点类型的名称将不可预测的。
请注意,C 和 C++ 标准中指定的指数与 IEEE-754 中描述的常用指数不同:它针对缩放为 [½, 1) 而不是 [1, 2) 的有效数进行调整,因此它是 1大于通常的 IEEE-754 指数。(上面的例子显示指数范围从 ?1021 到 1024,但 IEEE-754 指数范围是?1022 到 1023。)
IEEE-754 确实提供了推荐字段宽度的公式,但它不要求 IEEE-754 实现符合这些,当然 C 和 C++ 标准不要求 C 和 C++ 实现符合 IEEE-754。交换格式参数在 IEEE 754-2008 3.6 中规定,二进制参数为: