有人能解释一下为什么下面的代码为test4变量产生的输出与其他3变量不同吗?我已经用gcc版本4.2.1和4.5.3(以及介于两者之间的其他版本)对此进行了检查。
也许我错过了一些显而易见的东西,但它看起来很简单。。。
#include <stdio.h>
#include <complex.h>
main()
{
double complex test1, test2, test3, test4;
test1 = 81141117.0;
test2 = 81141117.0 + I * 0;
test3 = 81141117 + I * 0.0;
test4 = 81141117 + I * 0;
printf("%ld + %ld I, %ld + %ld I, ", (long)creal(test1), (long)cimag(test1), (long)creal(test2), (long)cimag(test2));
printf("%ld + %ld I, %ld + %ld In", (long)creal(test3), (long)cimag(test3), (long)creal(test4), (long)cimag(test4));
}
输出:
81141117 + 0 I, 81141117 + 0 I
81141117 + 0 I, 81141120 + 0 I
看起来,只有整数项的test4被提升为float,而不是声明的double,四舍五入开始发挥作用。
我在Mac OS X 10.7.5(自制GCC)上测试了GCC 4.7.1,系统还提供了/usr/bin/gcc
和/usr/bin/clang
,它们都产生了与您报告的相同的结果。
我同意你的分析,当复数的两项都表示为整数时,必须转换为float
而不是double
。C 2011标准包括以下示例:
ISO/IEC 9899:2011§6.7.9初始化
¶24示例1假设
<complex.h>
为#include
d,则声明int i = 3.5; double complex c = 5 + 3 * I;
用值3定义并初始化i,用值5定义并初始化c。0+i3。0.
这清楚地表明您应该能够编写整数表达式并获得有效的double complex
(尽管示例不是规范性的)。然而,它并没有说明整数值在转换为double
之前是否应该转换为float
,但语言中没有其他地方可以自动做到这一点(显然,你可以强制执行),因此它不太可能是预期的解释。
总的来说,我认为这很可能是一个可以向GCC团队报告的错误(我不主张轻易这样做)。如果运行gcc --help
,输出以消息结束:
For bug reporting instructions, please see:
<http://gcc.gnu.org/bugs.html>
我将扩展您的示例如下所示(或者,更确切地说,我确实扩展了您的示例,如下所示):
#include <stdio.h>
#include <complex.h>
int main(void)
{
double complex test1, test2, test3, test4, test5, test6, test7, test8;
test1 = 81141117.0;
test2 = 81141117.0 + I * 0;
test3 = 81141117 + I * 0.0;
test4 = 81141117 + I * 0;
test5 = (float)81141117 + I * 0;
test6 = 81141117 + I * (float)0;
test7 = 81141117.F + I * 0;
test8 = 81141117 + I * 0.F;
printf("%ld + %ld I, %ld + %ld In", (long)creal(test1), (long)cimag(test1), (long)creal(test2), (long)cimag(test2));
printf("%ld + %ld I, %ld + %ld In", (long)creal(test3), (long)cimag(test3), (long)creal(test4), (long)cimag(test4));
printf("%ld + %ld I, %ld + %ld In", (long)creal(test5), (long)cimag(test5), (long)creal(test6), (long)cimag(test6));
printf("%ld + %ld I, %ld + %ld In", (long)creal(test7), (long)cimag(test7), (long)creal(test8), (long)cimag(test8));
}
我得到的结果是:
81141117 + 0 I, 81141117 + 0 I
81141117 + 0 I, 81141120 + 0 I
81141120 + 0 I, 81141120 + 0 I
81141120 + 0 I, 81141120 + 0 I
正如您所看到的,最后两行中存在显式(float)
强制转换或显式浮点常量,会产生与有问题的行相同的结果(但值是合法的)。
您可能(也可能不)想要尝试CMPLX
、CMPLXF
(可能还有CMPLXL
)宏;只有当它们为"有趣"的某些定义产生了"有趣"值时,我才会将它们添加到报告的示例中。
编译器版本号:
$ /usr/gcc/v4.7.1/bin/gcc --version
gcc (GCC) 4.7.1
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ /usr/bin/gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ clang --version
Apple clang version 4.1 (tags/Apple/clang-421.11.65) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.4.2
Thread model: posix
$