gpt4 book ai didi

c++ - 如何检测非 IEEE-754 float ,以及如何使用它们?

转载 作者:行者123 更新时间:2023-12-05 01:51:45 26 4
gpt4 key购买 nike

我正在为基本类型编写类,因此代码在多个平台和编译器上在逻辑上是相同的(例如 int_least16_t 对应 int)。为了娱乐! (我还是个学生。)我读到这个:

float [...] Matches IEEE-754 binary32 format if supported.

更糟糕的是:

Floating-point types MAY support special values:, NaN or -0

这意味着 float 可以是无符号的...
[编辑:是的,这是不同的东西,但没有:“,但必须支持负数”。哟,在标准中没有这样的东西它可能不支持正常的 0...(我没有规范。)see ]

我知道这就像 __int128 ,标准只是一个标准,但还是...IEEE-754 是 1985 年的,但有些机器可能很奇怪,并且一些遗留硬件没有 float 单元。

据我了解,float 是强制性的(不像 int16_t 那样是可选的),但可以在任何标准中,并且任何一组值都是可能的?


我们唯一拥有的是一些宏( <cfloat> ):

  • FLT_MIN , FLT_MAX - 即使FLT_MIN = IEEE-754::FLT_MIN , float 可以是非 IEEE-754。例如 float with: flipped exponent with fraction...

  • FLT_RADIX - 基地系统?如果是这样,可以帮助写出准确的值。但是,float 仍然可以是 3 位或 200 位(大小)...

  • FLT_EPSILON -(从 1 到下一个)我们可能会使用它(带基数)来检查分数大小...

  • FLT_MANT_DIG - 是“尾数”数字/分数大小吗?

  • FLT_MAX_EXP - 在 IEEE-754 中用 1... 填充的指数,但外面可以是一个随机数?

如果 float 类似于 IEEE-754(符号、指数、分数),那么很容易,但如果 -0 和 NaN 是可选的,那么它可能是不同的。因为我不能区分它们,所以我不能使用位表示(以安全的方式)。如果 是可选的,float不再是安全类型。

我看到的唯一出路是向编译器添加宏。

我知道这是一个理论问题,但我感兴趣的是,当我们使用 float 时,是否有任何可能的检查或者我们都编写了依赖于实现的代码。关键字?


编辑 2022 年 5 月 4 日:

我想到了这个:

用户例如。代码:

//User eg. code:

int main()
{
float_M a = 1f;
float_M b = 0f;
std::cout << a/b; //should output infinty (IEEE-754)
}

//Code:

class float_M
{
public:
#ifdef __STDC_IEC_559__
float data;
//...
float_M operator/(float_M x){return float_M(data/x.data);}
//...
#else
/*union{
float data;
struct{//For noSign case ("absolutly catastrofic" case)
uint_least8_t sign : 1;
uint_least8_t exponent : 8;
uint_least32_t fraction : 23;
}
}*/ //no noSign case 🙂
float data;
//...
float_M operator/(float_M x){return divide(this, x);}

//funtion pointer alert!
static /*const (1*) */ float_M (*divide)(float_M a, float_M b) =
/*std::numeric_limits<float>::is_signed ?(*/
std::numeric_limits<float>::has_infinity ?(
std::numeric_limits<float>::has_quiet_NaN ?(
[]{return float_M(a.data/b.data);}
): &_divide_noNaN
): &_divide_noNaN
/*): &_divide_noSign*/
//...
#endif
}

它很丑陋(有函数指针),但可以防止在运行时发生错误的跳转。我希望 c++23 有更好的宏。

此外,更多链接:

跟进:Can floats not suport negative

最佳答案

在 C++ 中, std::numeric_limits<T>::is_iec559 的值应为 true对于所有浮点类型 T "if, and only if, the type adheres to ISO/IEC/IEEE 60559" ISO/IEC/IEEE 60559:2011 与 IEEE 754-2008 相同,因此:

#include <iostream>
#include <limits>

int main() {
std::cout << std::boolalpha << std::numeric_limits<float>::is_iec559 << '\n';
}

注意:如评论中所述,某些实现可能仍会报告 true对于这个常量,即使它们的浮点类型没有完全遵循 IEEE 754-2008 标准。

例如,在gcc ,您可以使用选项 -Ofast 进行编译或 -ffast-math这反过来又设置了许多选项,这些选项可能会导致依赖于 IEEE 或 ISO 数学函数规则/规范的精确实现的程序输出不正确。


C99 (及更高版本),有条件特征宏,__STDC_IEC_559____STDC_IEC_559_COMPLEX__ ,如果在您的实现中可用,它将告诉您它是否符合 IEC 60559:1989/IEEE 754−1985。

#include <stdio.h>
int main(void) {
#ifdef __STDC_IEC_559__
puts("true");
#endif
}

请注意,如果 __STDC_IEC_559__ 定义,并不一定意味着该实现不使用 IEEE 754 float 。这可能只是意味着它没有这些条件特征宏。关于这些宏的一个有趣的注意事项是,如果您使用 -Ofast-ffast-mathgcc ,它们将不会被定义(与 C++ 测试不同)。

使用的 IEC/IEEE 标准的实际修订版在 C11 中发生了变化和 C17/18C23 (草案)将有许多与浮点相关的新宏,它(当前)指的是 ISO/IEC 60559:2020 和 IEEE 754-2019,其中包含对 IEC 60559:2011/IEEE 754-2008 的小幅升级。

关于c++ - 如何检测非 IEEE-754 float ,以及如何使用它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72032458/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com