我注意到我正在编写的某些C代码存在问题,当我将两个长双精度相乘时,我有时会得到低于预期的精度。我已经在下面分离了一个例子,请注意这是一个用于matlab的mex文件。在纯c中重复完全相同的代码会导致预期的行为。
#include <mex.h>
#include <stdint.h>
typedef int32_t q0_31; // 32 bit signed fixed point number with 31 fractional bits
// conversion to long double from q0_31
long double q0_31_to_ldouble(q0_31 d) {
return d/2147483648.0L;
}
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
mwSize nInputs = 0;
mwSize nOutputs = 0;
q0_31 b;
long double b_ld;
/* check for proper number of arguments */
if( nrhs!=nInputs )
mexErrMsgIdAndTxt("filter_interface:nrhs","wrong number of inputs!");
if( nlhs!=nOutputs )
mexErrMsgIdAndTxt("filter_interface:nlhs","wrong number of outputs!");
// random value for b
b = 0x81948b0e;
// convert to long double directly
b_ld = b/2147483648.0L;
mexPrintf("Inline calculation...\n");
mexPrintf("b_ld:\t%0.16LA\n",b_ld);
mexPrintf("b_ld^2:\t %0.16LA\n",b_ld*b_ld);
// repeat with sub function
b_ld = q0_31_to_ldouble(b);
mexPrintf("Exactly the same with sub function...\n");
mexPrintf("b_ld:\t%0.16LA\n",b_ld);
mexPrintf("b_ld^2:\t %0.16LA\n",b_ld*b_ld);
}
编译后,这是我从代码中获得的输出:
Inline calculation...
b_ld: -0XF.CD6E9E4000000000P-4
b_ld^2: 0XF.9B7D0E4BEE0D3100P-4
Exactly the same with sub function...
b_ld: -0XF.CD6E9E4000000000P-4
b_ld^2: 0XF.9B7D0E4BEE0D0000P-4
完全奇怪,函数返回的值与内联计算完全相同。然而,当我解决它时,我会得到不同的结果。
因为我只在mex中得到这种行为而不是直接用gcc编译相同的代码时我认为这可能是由于matlab使用了一些奇怪的编译器标志。但是我找不到任何东西。
有什么想法吗?任何人都可以复制吗?
MATLAB版本:7.14.0.739(R2012a)
gcc:4.8.1-10ubuntu9