浮标的零符号

时间:2013-10-28 22:26:03

标签: c++ c floating-point

考虑以下代码使用C / C ++的float执行复数操作:

float real_part = log(3.f);
float imag_part = 0.f;

float real_part2 = (imag_part)*(imag_part)-(real_part*real_part);
float imag_part2 = (imag_part)*(real_part)+(real_part*imag_part);

结果将是

real_part2= -1.20695 imag_part2= 0
angle= 3.14159

其中angle是复数的阶段,在这种情况下,是pi

现在考虑以下代码:

float real_part = log(3.f);
float imag_part = 0.f;

float real_part2 = (-imag_part)*(-imag_part)-(real_part)*(real_part);
float imag_part2 = (-imag_part)*(real_part)+(real_part)*(-imag_part);

结果将是

real_part2= -1.20695 imag_part2= 0
angle= -3.14159

结果的虚部是-0,它使结果的相位为-pi

虽然仍然使用复数的主要参数和浮点的0的signed属性来完成,但当定义复数函数时,这种变化是个问题。例如,如果通过de Moivre公式定义复数的sqrt,则会将结果的虚部符号更改为错误的值。

如何处理这种影响?

1 个答案:

答案 0 :(得分:2)

编辑:既然这个问题似乎有道理,那么Kahan在撰写文章Branch Cuts for Complex Elementary Functions时就会回答这个问题:

  

通常,应该直接执行组合实数和复数变量的混合模式算法,而不是先将实际变为复数,以免零符号呈现为无信息;对于纯虚数量与复变量的组合也是如此。并且以这种方式直接执行算术可以节省执行时间,否则会浪费操作零。

换句话说,即使是IEEE 754标准的主要设计者也不知道在计算复数时如何使零符号有意义,其中一些已经从实数中提升。


回答最初的问题:

我在你所展示的计算中没有看到任何错误。

float imag_part = 0.f;

float imag_part2 = (-imag_part)*(real_part)+(real_part*imag_part);

这会将imag_part2设置为-0. + 0.,其中+0.为圆到最近。

complex_number3b.y=complex_number3a.x*complex_number3a.y+complex_number3a.y*complex_number3a.x;

评估为-0. + -0.,其本身评估为-0.

你的两个计算不等价,他们不能产生相同的结果是正常的。两个结果均符合IEEE 754 rules for the sign of zero