Ale*_*icz 4 c c++ legacy floating-point standards
我正在为基本类型编写类,因此代码在多个平台和编译器上在逻辑上是相同的(例如int_least16_tfor int)。为了娱乐!(我还是一名学生。)\n我读到了这个:
\n\n\n
更糟糕的是:
\n\n\n\n
这意味着浮点可能是无符号的...
[编辑:是的,这是不同的事情,但没有:“,但必须支持负数”。哟,如果标准中没有这样的东西,它可能不支持正常的 0...(我没有规范。)请参阅]
我知道这就像__int128一样,标准只是一个标准,\n但仍然...\nIEEE-754 是 1985 年的,但有些机器可能很奇怪,\n而且一些旧硬件没有浮动单位。
\n据我了解, float 是强制性的(不像 int16_t 那样是可选的),\n但可以在任何标准中,并且任何值集都可以吗?
\n我们唯一拥有的就是一些宏 ( <cfloat>):
FLT_MIN, FLT_MAX- 即使FLT_MIN = IEEE-754::FLT_MIN, float 也可以是非 IEEE-754。\n例如 float:带有分数的翻转指数...
FLT_RADIX- 基础系统?如果是这样,可以帮忙写出准确的值。但是,float 仍然可以是 3 位或 200 位(大小)...
FLT_EPSILON-(从 1 到下一个)我们可以使用它(带基数)来检查分数大小......
FLT_MANT_DIG- 是“尾数”数字/分数大小吗?
FLT_MAX_EXP- IEEE-754 中指数用 1... 填充,\n但外面可以是随机数吗?
如果 float 就像 IEEE-754(符号、指数、分数),那么这很容易,\n但是如果 -0 和 NaN 是可选的,那么它可能会不同。\n因为我无法区分它们,所以我可以\n(以安全的方式)使用位表示。如果\xe2\x88\x9e是可选的,float则不再是安全类型。
我看到的唯一出路是将宏添加到编译器中。
\n我知道这是一个理论问题,但我感兴趣的是,当我们使用关键字时,是否有可能进行任何检查,或者我们都编写依赖于实现的代码float?
2022年5月4日编辑:
\n我想出了这个:
\n用户例如。代码:
\n//User eg. code:\n\nint main()\n{\n float_M a = 1f;\n float_M b = 0f;\n std::cout << a/b; //should output infinty (IEEE-754)\n}\n\n//Code:\n\nclass float_M\n{\npublic:\n#ifdef __STDC_IEC_559__\n float data;\n//...\n float_M operator/(float_M x){return float_M(data/x.data);}\n//...\n#else\n /*union{\n float data;\n struct{//For noSign case ("absolutly catastrofic" case)\n uint_least8_t sign : 1;\n uint_least8_t exponent : 8;\n uint_least32_t fraction : 23;\n }\n }*/ //no noSign case \n float data;\n//...\n float_M operator/(float_M x){return divide(this, x);}\n\n//funtion pointer alert!\n static /*const (1*) */ float_M (*divide)(float_M a, float_M b) =\n /*std::numeric_limits<float>::is_signed ?(*/\n std::numeric_limits<float>::has_infinity ?(\n std::numeric_limits<float>::has_quiet_NaN ?(\n []{return float_M(a.data/b.data);}\n ): &_divide_noNaN\n ): &_divide_noNaN\n /*): &_divide_noSign*/\n//...\n#endif\n}\nRun Code Online (Sandbox Code Playgroud)\n它很丑(有函数指针),但可以防止运行时不必要的跳转。希望c++23有更好的宏。
\n另外,更多链接:
\n后续:浮动可以不支持负数吗
\n在 C++ 中, 的值std::numeric_limits<T>::is_iec559适用true于所有浮点类型T “当且仅当该类型遵守 ISO/IEC/IEEE 60559”并且 ISO/IEC/IEEE 60559:2011 与 IEEE 754-2008 相同时,所以:
#include <iostream>\n#include <limits>\n\nint main() {\n std::cout << std::boolalpha << std::numeric_limits<float>::is_iec559 << \'\\n\';\n}\nRun Code Online (Sandbox Code Playgroud)\n注意:如注释中所述,某些实现可能仍会报告true此常量,即使它们的浮点类型未严格遵循 IEEE 754-2008 标准。
例如,在 中gcc,您可以使用选项进行编译-Ofast,或者-ffast-math依次设置多个选项,这可能会导致依赖于数学函数的 IEEE 或 ISO 规则/规范的精确实现的程序输出不正确。
在C99(及更高版本)中,有条件功能宏,__STDC_IEC_559__并且__STDC_IEC_559_COMPLEX__,如果在您的实现中可用,它将告诉您它是否符合 IEC 60559:1989 / IEEE 754\xe2\x88\x921985。
#include <stdio.h>\nint main(void) {\n#ifdef __STDC_IEC_559__\n puts("true");\n#endif\n}\nRun Code Online (Sandbox Code Playgroud)\n请注意,如果__STDC_IEC_559__未定义,并不一定意味着该实现不使用 IEEE 754 浮点数。这可能只是意味着它没有这些条件功能宏。关于这些宏的一个有趣的说明是,如果您在 中使用-Ofast或,它们将不会被定义(与 C++ 测试中不同)。-ffast-mathgcc
实际使用的 IEC / IEEE 标准修订版在C11和C17/18中发生了变化,在C23(草案)中将有许多与浮点相关的新宏,它(当前)指的是 ISO/IEC 60559:2020 和 IEEE 754-2019,其中包含对 IEC 60559:2011 / IEEE 754-2008 的细微升级。
\n