【问题标题】:is isnan preserved when asigning to different size FP type.分配给不同大小的 FP 类型时保留 isnan。
【发布时间】:2014-03-27 23:23:59
【问题描述】:

基本上:

float  nanf=std::numeric_limits::signaling_NaN<decltype(g_nanf)>();
double nand = nanf;
assert(std::isnan(nand));

可以断言火吗? 如果我将 double nan 分配给 float 怎么办

【问题讨论】:

  • decltype(g_nanf) ? ITYM float ?

标签: c++ nan ieee-754


【解决方案1】:

来自 N3337:

4.6 浮点提升[conv.fpprom]

1 float 类型的纯右值可以转换为 double 类型的纯右值。 值不变。

,

4.8 浮点转换 [conv.double]

1 浮点类型的纯右值可以转换为另一个浮点的纯右值 类型。 如果源值可以在 目标类型,转换的结果是准确的 表示。 如果源值介于两个相邻的 目标值,转换的结果是 这些值中的任何一个的实现定义的选择。否则, 行为未定义。

3.9.1 基本类型 [basic.fundamental]

8 共有三种浮点类型:floatdoublelong doubledouble 类型提供 至少与float 一样精确,并且long double 提供的类型 至少与double 一样精确。 类型的值集合 floatdouble 类型值集的子集;的集合 double 类型的值是该类型值集的子集 long double.

现在我们应该确认NaN 实际上是浮点类型的有效isnan 的定义参考了 C 标准。从 N1570:

7.12.3.4 isnan

2 isnan 宏确定其参数 value 是否为 NaN。

总结一下: 是的,从 floatdouble 应该保留 NaN 特性。从doublefloat 可能有点不确定,但由于double 支持NaN,我们得出结论,这种转换也必须通过“值的子集”措辞来保留。

(What the word "value" actually means seems to be somewhat ill-defined.)

【讨论】:

  • 我认为正确的标准是 IEEE 754 给出的问题标签。
  • @MSalters 我认为我粘贴的引号表明无论浮点类型是否遵循 IEEE 754,在 C++ 中都需要这种行为。因此,当它们这样做时仍然如此。但是,如果您可以访问 IEEE 754(或后期草案或其他任何内容。我什么都没有。)我很想看到带有相关报价的答案。
  • 但是 IEEE 754 对浮点上下文中“值”的含义要清楚得多。例如。根据 IEEE754,+0.0-0.0 绝对是相同的值。
  • +1;我还在下面为好奇者提供了相关的 IEEE-754 引用。
【解决方案2】:

C++ 不需要遵守 IEEE-754;但是,对于确实遵循标准的平台,第 6.2 条规定了安静 NaN 的行为:

对于具有安静 NaN 输入的运算,除了最大和最小运算之外,如果要传递浮点结果结果应为安静 NaN。 ..

和信号 NaN:

在默认异常处理下,任何发出无效操作异常的信号并且要传递浮点结果的操作都应传递安静的 NaN。

Signaling NaNs 应该是保留的操作数,在默认异常处理下,为每个通用计算和信令计算操作发出无效操作异常(见 7.2)的信号......

【讨论】:

    【解决方案3】:

    BoBTFish's answer 听起来很有说服力。现在,我自己没有关于这个主题的规范信息,但我想提供一个基于一点推论的替代答案:

    一般来说是这样的:

    • 一般来说,任何涉及NaN 的表达式都必须返回NaN
    • 算术表达式可能涉及从/到 singledouble 的转换,可能会多次。

    我看不出编译器如何在float/double 转换期间不保留NaN 的情况下满足这两个要求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-14
      • 2023-04-10
      • 1970-01-01
      • 2018-09-27
      • 2020-04-02
      • 1970-01-01
      • 2019-06-02
      相关资源
      最近更新 更多