作为这个问题的后续行动:
当我注意到如果使用该支持进行计算时,我 正在使用Apple 的复数支持实现一个计算器应用程序,最终会得到以下结果:
(1+i)^2=1.2246063538223773e-16 + 2i
当然正确的恒等式是(1+i)^2=2i。这是一个更普遍现象的具体例子——如果舍入错误将一个应该为零的部分舍入到稍微不为零的部分,那么它们可能真的很烦人。
关于如何处理的建议?我可以用其他方式实现复数的整数幂,但一般问题仍然存在,我的解决方案本身可能会导致其他不一致。
作为这个问题的后续行动:
当我注意到如果使用该支持进行计算时,我 正在使用Apple 的复数支持实现一个计算器应用程序,最终会得到以下结果:
(1+i)^2=1.2246063538223773e-16 + 2i
当然正确的恒等式是(1+i)^2=2i。这是一个更普遍现象的具体例子——如果舍入错误将一个应该为零的部分舍入到稍微不为零的部分,那么它们可能真的很烦人。
关于如何处理的建议?我可以用其他方式实现复数的整数幂,但一般问题仍然存在,我的解决方案本身可能会导致其他不一致。
正如您所注意到的,这是浮点的标准舍入误差问题。@Howard 指出,您可能应该在显示之前将您的双精度结果四舍五入到浮点范围内。
我通常FLT_EPSILON
也用来帮助我处理这些事情。
#define fequal(a,b) (fabs((a) - (b)) < FLT_EPSILON)
#define fequalzero(a) (fabs(a) < FLT_EPSILON)
有了这些,您可能会喜欢这样的功能(未经测试)
inline void froundzero(a) { if (fequalzero(a)) a = 0; }
正如他们所说,复杂的版本留给读者作为练习:D