我在比较C ++和MATLAB中的算法实现。
调试时我发现std::log
和MATLAB的log
似乎没有返回相同的值。
具体的例子是
X = (0.98624334784190482,0.019377216547938527)
我正在接受
std::log(std::complex<double>(0.98624334784190482,0.019377216547938527))
给出
(-0.013659176853856606,0.019644972824447767)
在MATLAB中,相同复数的对数是
(-0.013659176853856606, 0.019644972824447764)
我有两个问题。
1)这两个功能给我不同的答案是否正确?我怎么知道?我想我知道(使用union
和double
的{{1}}或者可以很容易地找到如何在C ++中查看输入和结果的基础二进制表示,但我不是确定如何在MATLAB中做到这一点。 OK. Found something that might serve for this part
行。这部分似乎已经解决了。我做了uint64_t
并打印
4581319499315104670
在C ++中,typecast(imag(log(X)), 'uint64');
的技巧给出了
4581319499315104671
所以,我猜这证实了结果的虚部是不同的。
2)如果这两个对数的实现不相等,那么我该如何构建匹配union
的MATLAB实现。也许只是一个起点就足够了,比如如何找到我正在使用的std::log
的实现?
到目前为止,我发现std :: log的虚部是按预期计算的(如预期的那样)
std::log
和
// 26.2.7/4: arg(__z): Returns the phase angle of __z.
template<typename _Tp>
inline _Tp
__complex_arg(const complex<_Tp>& __z)
{ return atan2(__z.imag(), __z.real()); }
现在我需要找到 inline _GLIBCXX_CONSTEXPR long double
atan2(long double __y, long double __x)
{ return __builtin_atan2l(__y, __x); }
的实现。
我注意到MATLAB通过计算__builtin_atan2l
具有atan2
函数。我得到的值与上面的虚部相同。所以我猜MATLAB还通过调用atan2(imag(X), real(Y))
计算虚部来实现类似于log
的{{1}}。有趣的是,atan2在C ++和MATLAB中给出了不同的结果。
注意:使用gcc-4.8.4代替rhel-x86_64-5.2和MATLAB 2011b代替64位。