【问题标题】:C - unexpected behavior in complex.h on different OSC - complex.h 在不同操作系统上的意外行为
【发布时间】:2023-04-09 13:50:02
【问题描述】:

考虑以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
int main()
{
   complex double aaa = INFINITY + 0*I;
   printf("%.f + %.f*I\n", creal(aaa), cimag(aaa));
   complex double bbb = 1.0/aaa;
   printf("%.f + %.f*I\n", creal(bbb), cimag(bbb));
   return EXIT_SUCCESS;
}

gcc -std=gnu99 -lm编译,我希望输出是

inf + 0*I

0 + 0*I

这在 Linux 上是正确的(在带有 gcc 4.4.7 的 Scientific Linux 6.8、带有 gcc 5.3.1 的 Fedora 23 和带有 gcc 4.8.4 的 Ubuntu 14.04.5 上测试)。

但是,在 OS X(带有 clang-602.0.53 的 10.11.5)上,我得到了

inf + 0*I

南+南*我

很明显,clang 不符合 C99 标准(参见N1256,第 G.5.1 节;严格来说,这只是推荐的做法,而不是标准)。 事实上,clang 并没有定义宏__STDC_IEC_559_COMPLEX__,这个宏在 Sec. 中介绍。 G.1. clang 是否故意做出这种行为? 更新:经过一些检查,我发现我测试的几个 Linux 环境也没有定义这个宏,但代码仍然在那里正常工作。

目前,我对跨平台支持的解决方法是检查宏

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
int main()
{
   complex double aaa = INFINITY + 0*I;
   printf("%.f + %.f*I\n", creal(aaa), cimag(aaa));
   complex double bbb = 1.0/aaa;
   #ifndef __STDC_IEC_559_COMPLEX__
   if(isnan(bbb)) 
   { 
      bbb = 0; //or do some trick that has to do with the problem context
   }
   #endif
   printf("%.f + %.f*I\n", creal(bbb), cimag(bbb));

   return EXIT_SUCCESS;
}   

但我不确定它是否强大...有什么建议吗?

【问题讨论】:

  • C standard: INFINITY 扩展为浮点类型的常量表达式,表示正无穷或无符号无穷(如果可用);否则为在翻译时溢出的浮点类型的正常量。因此它的行为可能在不同平台上并不相同......
  • @EugeneSh。 1. 在这种情况下,INFINITY 确实会扩展为正无穷大,这可以通过输出的第一行或在调试器中进行检查; 2.这里我写INFINITY只是为了提供一个MWE。你可以在不改变结论的情况下写出像complex double aaa = 1.0/0.0; 这样溢出来的东西; 3.如果这不起作用真的没有意义,因为我已经测试了double对应的对象(将所有complex double替换为double,去掉crealcimag的功能,等)。
  • @LeoFang 它的数学处理方式和printf() 的表示方式可能并不完全相同。也许确定问题是否真的是clang 或架构的最佳方法是使用gcc 在OSX 上编译它。
  • 这似乎是在较新版本中修复的 LLVM/Clang 问题。 LLVM/Clang 3.6.2(日期在clang-602.0.53 之后)具有预期的行为,而 LLVM/Clang 3.5.2 具有所描述的行为。
  • @kdhp,你是对的。在发布之前,我在 LLVM 3.6.0 (clang-602.0.53) 上进行测试,我刚刚在另一台运行 OS X 10.10.5 和 LLVM 3.7.0 (clang-700.1.81) 的机器上进行了测试,这给了我正确的结果。您可以发布答案,我会接受。谢谢!

标签: c clang c99


【解决方案1】:

您使用 %f 而不是 %lf 作为双参数。我认为这会导致不可预测的行为。

【讨论】:

    猜你喜欢
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 2015-09-14
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多