【问题标题】:cl: compile time vs. run time: inf vs. -nan(ind)cl:编译时间与运行时间:inf 与 -nan(ind)
【发布时间】:2021-02-13 10:42:09
【问题描述】:

示例代码 (t50.c):

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <math.h>
#include <float.h>
#include <assert.h>

const float d1 = NAN;
const float d2 = -0x0p+0;
const float d3 = NAN / -0x0p+0;

typedef union { uint32_t u; float d; } u_t;

int main(void)
{
        u_t u1;
        u_t u2;
        u_t u3;

        u1.d = *(volatile float*)&d1 / *(volatile float*)&d2;
        u2.d = d3;
        u3.d = d1 / d2;
        if ( u1.u != u2.u || u1.u != u3.u )
        {
                printf("error:\n");
                printf("u1 (run time)     %08"PRIx32" %.*e\n", u1.u, DECIMAL_DIG, u1.d);
                printf("u2 (compile time) %08"PRIx32" %.*e\n", u2.u, DECIMAL_DIG, u2.d);
                printf("u3                %08"PRIx32" %.*e\n", u3.u, DECIMAL_DIG, u3.d);
        }
        return 0;
}

编译器调用:cl t50.c /O1 /fp:precise &amp;&amp; t50

预期结果:&lt;nothing&gt;

实际结果(cl x86cl x64 相同):

error:
u1 (run time)     ffc00000 -nan(ind)
u2 (compile time) 7f800000 inf
u3                ffc00000 -nan(ind)

我指定了/fp:strict:cl t50.c /O1 /fp:strict &amp;&amp; t50,但得到了:

t50.c(8): error C2099: initializer is not a constant
t50.c(10): error C2099: initializer is not a constant

cl 版本:19.25.28611 for x8619.25.28611 for x64

gcc (10.2.0) 和clang (11.0.0) 比较:

gcc t50.c -O2 && a.exe
<nothing>

clang t50.c -O2 && a.exe
<nothing>

为什么?我在这里缺少什么? 标准(C / IEEE)怎么说?

UPD1:

  1. if ( u1.d != u2.d || u1.d != u3.d ) 的结果相同。
  2. 同样的结果w/o unions(即使用float u1, u2, u3)。

UPD2:

  1. 编译器的 NAN 定义:Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_math.h:#define NAN ((float)(INFINITY * 0.0F))
  2. u1.d = NAN; printf("NAN %08"PRIx32" %.*e\n", u1.u, DECIMAL_DIG, u1.d); 的输出(cl x86cl x64):NAN ffc00000 -nan(ind)

【问题讨论】:

  • 关于“initializer not constant”错误,可能是MSVC将NAN宏定义为函数调用。
  • 您缺少一个体面的符合标准的编译器......可悲的是。
  • @MarcoBonelli:标准并没有承诺与工会打双关时会得到什么,是吗?
  • @NateEldredge 根据 C 标准,通过联合进行类型双关是完全可以的。它是定义的实现,是的,但它应该可以工作。这里的问题可能是cl 的一些虚假浮点数学怪癖。
  • "C2099 也可能发生,因为编译器无法对 /fp:strict 下的表达式执行常量折叠,因为浮点精度环境设置(有关更多信息,请参见 _controlfp_s)可能与编译运行时。”

标签: c floating-point nan ieee-754 cl


【解决方案1】:

为什么?

cl 不关注IEEE-754 关于NAN

我在这里缺少什么?

假设符合标准的 C 编译器遵循 IEEE。

标准 C 怎么说?

C 对 NAN 部门的规范松懈。我认为编译器是合规的,只是关于NAN 的实现质量较差。

IEEE 标准是怎么说的?

不合规。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2012-10-04
    • 1970-01-01
    • 2011-05-15
    • 2014-11-16
    相关资源
    最近更新 更多