如何检测非 IEEE-754 浮点,以及如何使用它们?

2024-02-23

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

float [...] 匹配 IEEE-754 binary32 格式如果支持的话。 https://en.cppreference.com/w/cpp/language/types

更糟糕的是:

浮点类型MAY支持特殊值:∞、NaN 或 -0 https://en.cppreference.com/w/cpp/language/types

这意味着浮动MAY未签名...
[编辑:是的,这是不同的事情,但没有:“,但必须支持负数”。哟,如果标准中没有这样的东西,它可能不支持正常的 0...(我没有规范。)see https://stackoverflow.com/questions/72138837/can-floats-not-suport-negative-or-even-0]

我知道这就像__int128 https://stackoverflow.com/questions/16088282/is-there-a-128-bit-integer-in-gcc,而标准只是一个标准, 但仍然... IEEE-754 是 1985 年的,但有些机器可能很奇怪, 一些旧硬件没有浮动单元。

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


我们唯一拥有的就是一些宏(<cfloat> https://en.cppreference.com/w/cpp/header/cfloat):

  • FLT_MIN, FLT_MAX- 即使FLT_MIN = IEEE-754::FLT_MIN, float 可以是非 IEEE-754。 例如浮动:带有分数的翻转指数...

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

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

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

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

如果 float 就像 IEEE-754(符号、指数、分数),那么就很简单, 但如果 -0 和 NaN 是可选的那么它MAY有所不同。 因为我无法区分它们,所以我无法使用位表示 (以安全的方式)。而如果是可选的,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有更好的宏。

另外,更多链接:

  • 关于浮点运算 https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
  • 用户定义的文字 https://en.cppreference.com/w/cpp/language/user_literal
  • 无 const 函数指针 (1*) https://stackoverflow.com/questions/15506094/const-function-pointers

跟进:浮点数可以不支持负数吗 https://stackoverflow.com/questions/72138837/can-floats-not-suport-negative-or-even-0


在 C++ 中,值std::numeric_limits<T>::is_iec559 https://en.cppreference.com/w/cpp/types/numeric_limits/is_iec559应该true对于所有浮点类型T “当且仅当该类型符合 ISO/IEC/IEEE 60559” https://eel.is/c++draft/support.limits#lib:is_iec559,numeric_limitsISO/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 or -ffast-math这又设置了许多选项,这些选项可能会导致依赖于数学函数的 IEEE 或 ISO 规则/规范的精确实现的程序输出不正确。


In C99 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf(及更高版本),有条件特征宏,__STDC_IEC_559__ and __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__ is not定义后,并不一定意味着该实现不使用 IEEE 754 浮点。这可能只是意味着它没有这些条件功能宏。关于这些宏的一个有趣的说明是,如果您使用-Ofast or -ffast-math in gcc,它们不会被定义(与 C++ 测试不同)。

所使用的 IEC/IEEE 标准的实际修订版发生了变化C11 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf and C17/18 https://files.lhmouse.com/standards/ISO%20C%20N2176.pdf and in C23 http://open-std.org/JTC1/SC22/WG14/www/docs/n2731.pdf(草案)将会有许多与浮点相关的新宏,它(当前)引用 ISO/IEC 60559:2020 和 IEEE 754-2019,其中包含对 IEC 60559:2011 / IEEE 754-2008 的小升级。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何检测非 IEEE-754 浮点,以及如何使用它们? 的相关文章

随机推荐

  • 在 CakePHP 中使用媒体视图下载文件

    我想通过 4 个不同的链接下载 4 个不同的文件 我正在使用媒体视图下载文件 但我必须在控制器的下载功能中对文件名进行硬编码 function download this gt view Media params array id gt e
  • 通过外部站点登录 Moodle

    我正在设置一个 Moodle 环境 我需要用户能够使用其凭据通过外部站点登录that地点 理想情况下 他们会访问该网站 登录 然后单击一个按钮 将他们及其帐户信息发送到 Moodle 一旦他们到达 Moodle Moodle 将检查帐户信息
  • C++ STL 容器 ::clear ::swap

    清理 大型 STL 容器的最快方法是什么 在我的应用程序中 我需要处理大尺寸std map 例如 10000 个元素 我测试了以下3种方法来清除std map 每次需要时创建一个新容器 Calling map clear method Ca
  • 使 optgroup 标签在下拉列表中选择

    我计划为主要车型 瑞典汽车 提供一个简短的描述页面 我还想表明沃尔沃和萨博在下拉列表中位于瑞典汽车下方 然后 当我单击沃尔沃时 它应该导航到沃尔沃描述页面 如何显示最初选择的 optgroup 标签 谢谢
  • Windows:如何使用带路径的主机文件?

    这有效 127 0 0 1 www somesite com 但不是这个 127 0 0 1 somepath www www mysite com 我究竟做错了什么 是否可以绘制这样的完整路径 如果没有 完成我想做的事情的最简单方法是什么
  • 为 Android 部署 Phonegap / Cordova 应用程序?

    我正在 Android 上测试 Phonegap Cordova 3 0 应用程序 从 2 x 版本开始 Cordova 严重依赖命令行终端 我已经完成了所有设置 可以构建应用程序了 但有两件事困扰着我 首先 一个Android项目有两个w
  • 敲除剑道问题通过计算的可观察值进行绑定

    我尝试使用knockout kendo js 在knockout forEach 模板中声明kendo dropdownlist 控件 以便当新项目添加到knockout 可观察数组时 新的kendo dropdownlist 会在UI 中
  • C++ 中的函数与变量声明

    这段代码的工作原理 std ifstream f mapFilename c str std string s std string std istreambuf iterator
  • sf 对象的大小图例不会显示正确的符号

    有谁知道为什么传说size审美的BIR74不会显示点大小而是矩形 如果答案是肯定的 我该如何解决这个问题 可重现的例子 library sf devtools install github tidyverse ggplot2 library
  • 为什么这个不能是本地的?

    这是我正在运行的设置的虚拟变体 Launcher函数好像没有看到GetLevel 至少可以看到第一个印刷品 但看不到第二个印刷品 所以该函数永远不会启动 这是因为代码出现在代码中启动它的位置之后 而在启动器执行时它还不存在吗 当我删除本地标
  • FluentValidation 检查子集合中的重复实体

    我有一个MainEntity类 它有一个集合SubEntity 目前的验证情况如下 public class MainEntityValidator AbstractValidator
  • git-tf 无法找到所需的 JAR

    我正在尝试在我的 Windows 工作站上设置 git tf 桥 当我尝试执行其中一个命令时 它总是显示消息 无法找到所需的 JAR C my path to git tf lib com microsoft gittf client cl
  • 如何从 Gemfile.lock 文件安装 gem?

    我正在尝试运行一个从 Github 上取下的应用程序 我跑了bundle install从以下位置安装所需的 gemGemfile 然而 当运行应用程序时 一条错误消息告诉我安装的 gems 版本错误 关于检查Gemfile lock我注意
  • 使用 Objective C 读取发布到设备控制台的日志消息

    我的 iOS 应用程序如何从设备控制台日志中读取消息 我想以编程方式读取这些日志条目 例如读取文件 选择一些日志条目 然后通过电子邮件将其发送给支持人员 我知道有一款 iPhone 应用程序可以让您查看日志 它的名字是控制台 但是 我无法弄
  • 禁用 Zsh 中远程分支的自动完成功能?

    这与禁用 Git Bash 中远程分支的自动完成功能 https stackoverflow com questions 6623649 disable auto completion of remote branches in git b
  • MD5产生碰撞之前有多少个随机元素?

    Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 我在 Amazon S3 上有一个图像库 对于每个图像 我在服务器上对源 URL 进行 md5
  • Xcode - 我更换了硬盘,现在项目无法构建

    我很快更换了故障硬盘 我检查的所有文件似乎都正常 但是 我的 Xcode 项目无法编译 我收到这条消息 error PCH was compiled with module cache path Volumes MacintoshHD2 U
  • Lombok - 如何创建自定义设置器并应用于 java 中的不同成员

    我想了解如何在 Lombok 中创建自定义设置器并将该设置器应用于特定成员 我有一个有 100 名成员的班级 其中 50 名成员有一个自定义设置器 在设置值之前检查 X 内容 另外 50 名成员有一个自定义设置器 在设置值之前检查 Y 内容
  • Android:如何配置“tinymix”以使用“tinycap”录制系统音频

    在 Android 中 目前无法使用 Android SDK 录制系统音频 因此 我尝试了一下 TinyALSA 自 Android 4 起 希望可以重新路由音频输出 以便可以录制它 当我在设备上调用 tinymix 时 我得到以下配置 c
  • 如何检测非 IEEE-754 浮点,以及如何使用它们?

    我正在为基本类型编写类 因此代码在多个平台和编译器上在逻辑上是相同的 例如int least16 t for int 为了娱乐 我还是个学生 我读到了这个 float 匹配 IEEE 754 binary32 格式如果支持的话 https