cproj功能未按预期工作
我有以下C测试程序,它使用了cproj功能未按预期工作,c,C,我有以下C测试程序,它使用了cproj功能: #include <stdio.h> #include <math.h> #include <complex.h> int main(void) { complex double z = cproj(INFINITY + NAN * I); printf("re=%f\nim=%f", creal(z), cimag(z)); } 但是,根据N2176 7.3.9.5(以及N
cproj
功能:
#include <stdio.h>
#include <math.h>
#include <complex.h>
int main(void)
{
complex double z = cproj(INFINITY + NAN * I);
printf("re=%f\nim=%f", creal(z), cimag(z));
}
但是,根据N2176 7.3.9.5(以及N1570 7.3.9.5和N12567.3.9.4,我没有真正的ISO C标准,只有草案),这是不正确的行为:
7.3.9.5 cproj功能
无穷大+I*copysign(0.0,cimag(z))
变量
z
有一个无限部分和一个NaN部分,但函数返回两个NaN部分,而不是实部分的无穷大。这是为什么?正如@EdmCoff所指出的,问题不在于cproj
,而在于变量的初始化,INFINITY+NAN*I
。此示例显示:
complex double z = INFINITY + NAN * I;
printf("re=%f\nim=%f", creal(z), cimag(z));
输出:
re=1.#QNAN0
im=1.#QNAN0
re=1.#INF00
im=1.#QNAN0
即使未使用cproj
,变量初始化也不正确
如果CMPLX
宏可用(在任何声称实现复杂算法的C11/C17实现上,它应该是可用的,但由于某些原因,在MinGW上它不是),它应该解决以下问题:
complex double z = CMPLX(INFINITY, NAN);
printf("re=%f\nim=%f", creal(z), cimag(z));
如果宏不可用,则初始化数字的便携式一致方法为:
complex double z;
memcpy(&z, (double[2]){ INFINITY, NAN }, sizeof z);
printf("re=%f\nim=%f", creal(z), cimag(z));
或者,不使用memcpy
:
complex double z = *(complex double*)(double[2]){ INFINITY, NAN };
printf("re=%f\nim=%f", creal(z), cimag(z));
输出:
re=1.#QNAN0
im=1.#QNAN0
re=1.#INF00
im=1.#QNAN0
正如@EdmCoff所指出的,问题不在于
cproj
,而在于变量INFINITY+NAN*I
的初始化。此示例显示:
complex double z = INFINITY + NAN * I;
printf("re=%f\nim=%f", creal(z), cimag(z));
输出:
re=1.#QNAN0
im=1.#QNAN0
re=1.#INF00
im=1.#QNAN0
即使未使用cproj
,变量初始化也不正确
如果CMPLX
宏可用(在任何声称实现复杂算法的C11/C17实现上,它应该是可用的,但由于某些原因,在MinGW上它不是),它应该解决以下问题:
complex double z = CMPLX(INFINITY, NAN);
printf("re=%f\nim=%f", creal(z), cimag(z));
如果宏不可用,则初始化数字的便携式一致方法为:
complex double z;
memcpy(&z, (double[2]){ INFINITY, NAN }, sizeof z);
printf("re=%f\nim=%f", creal(z), cimag(z));
或者,不使用memcpy
:
complex double z = *(complex double*)(double[2]){ INFINITY, NAN };
printf("re=%f\nim=%f", creal(z), cimag(z));
输出:
re=1.#QNAN0
im=1.#QNAN0
re=1.#INF00
im=1.#QNAN0
我认为这是
creal
的问题,而不是cproj
@EugeneSh的问题。使用((double*)(&z))[0]
也会返回NaN。不确定强制转换在技术上是否为UB,但它应该可以工作,因为复数必须是由2个浮点组成的数组。我认为问题不在于cproj
,而在于您传递的内容。我的手册页上说(关于使用a+b*I
初始化复数):“某些复数不能用这种技术初始化,因为我实际上是一个复数。”既然你没有可用的CMPLX
,也许你可以创建自己的并使用它?e、 g.#定义我的CMPLX(x,y)((双复数){x,y})
初始值设定项在C中无效,但我明白你的意思。成功了,我很高兴你能解决。这并不重要,但我很好奇我发布的宏有什么问题。即使使用-Wall
和std=c89
编译,我也没有收到任何警告。我认为这是creal
的问题,而不是cproj
@EugeneSh的问题。使用((double*)(&z))[0]
也会返回NaN。不确定强制转换在技术上是否为UB,但它应该可以工作,因为复数必须是由2个浮点组成的数组。我认为问题不在于cproj
,而在于您传递的内容。我的手册页上说(关于使用a+b*I
初始化复数):“某些复数不能用这种技术初始化,因为我实际上是一个复数。”既然你没有可用的CMPLX
,也许你可以创建自己的并使用它?e、 g.#定义我的CMPLX(x,y)((双复数){x,y})
初始值设定项在C中无效,但我明白你的意思。成功了,我很高兴你能解决。这并不重要,但我很好奇我发布的宏有什么问题。即使使用-Wall
和std=c89
编译,我也没有收到任何警告。