在C++中创建非规范化(亚正规)浮点值

Create denormalized (subnormal) floating point values in C++

本文关键字:C++ 创建 非规范 规范化      更新时间:2023-10-16

出于测试目的,我需要在C++中创建一个正的和一个负的非规范化(也称为亚正规)floatdouble数。

我怎样才能写出这样一个数字?

您可以使用-std::numeric_limits<T>::denorm_min()std::numeric_limits<T>::denorm_min()。产生的非规范化值有一个特殊的特性,这只是偶然的。如果你不想这样,可以乘以一些相当小的整数值。

为了获得充分的灵活性和覆盖率,请创建一个具有相同大小的无符号整数值和浮点值的并集。对于32位值,可能是无符号的int+float,对于64位值,则是无符号long+double。将所需的decorm值存储在integer字段中,并读取相应的浮点值。如果你想变得有趣,可以为浮点数的符号、指数和分数部分指定带位字段的整数。

对于正值,32位分母在[0x000000010x007fffff]的范围内,而对于负值,则在[0x800000010x807fffff]的范围内。

对于正值,64位去噪比在[0x00000000000000010x000fffffffffffff]的范围内,对于负去噪比,在[0x80000000000000010x800fffffffffffff]的范围中。

如果在平移并集中使用位字段,则符号位是任意的,指数是零,分数可以是除零之外的任何值。

另一种方法显然是,取最小归一化值DBL_MIN(或者,好吧,std::numeric_limits<double>::min()),并将其除以某物;类似于CCD_ 15。反转负次法线的符号。

以下是如何在内存中形成非规范化IEEE-754浮点值的演示。

const uint32_t denormal_as_int[2] = {0x0000001, 0x00000000};
double denormal;
memcpy(&denormal, &denormal_as_int, sizeof(denormal));

这样做的标准方法当然是@DietmarKüh 提到的方法