c#中的浮点数和双精度

时间:2010-09-29 16:37:26

标签: c# matrix precision matrix-multiplication

这里有一个矩阵乘法码的问题。 我似乎在大矩阵乘法上失去了精度(我的代码在小矩阵上运行良好)。

我的循环如下:

for (int j = 0; j < columns; j++)
{
    float[] column = otherMatrix.Column(j);
    for (int i = 0; i < rows; i++)
    {
        double s = 0;
        for (int k = 0; k < size; k++)
            s += this[i,k] * ((double) column[k]);
        result[i, j] = (float)s;
    }
}

正如你所看到的,我强制一个(双精度)精度,以确保在乘以我的两个浮点数时不会失去精度。

看看IL代码,我可以看到两个conv.r8让我觉得IL代码中有这种浮点到双精度的转换。

但是,在运行它并查看反汇编(x86机器)时,我看到以下内容:

0000024e  fld         dword ptr [edx+eax*4+8] 
00000252  fmulp       st(1),st 
00000254  fadd        qword ptr [ebp-64h] 
00000257  fstp        qword ptr [ebp-20h] 

这让我觉得JIT认为既然我已经乘以浮点数,它不应该使用双精度乘法而是单精度乘法,这给我带来了我一直在跟踪的错误。

我是对的吗? 有没有办法强制进行这种双精度乘法?

由于

3 个答案:

答案 0 :(得分:3)

认为你误解了大会。我相信FMULP总是在80位寄存器上运行。我会惊讶地发现JIT在这里做错了。

我建议您使用我的DoubleConverter在算术前后写出精确值。这样你就可以更好地了解正在发生的事情。

答案 1 :(得分:0)

您可能希望切换到十进制以获得更好的精度

答案 2 :(得分:0)

首先,你有什么理由不能使用小数?小数保持任何数字的必要精度,并且没有烦人的“尾数的最近二进制表示”问题浮点数可能导致x-y = z + - .0000000000 ... 0000001错误。

来自MSDN:

  

十进制值类型表示   十进制数从正数   79,228,162,514,264,337,593,543,950,335   否定的   79,228,162,514,264,337,593,543,950,335。   十进制值类型是合适的   用于需要的财务计算   大量的重要积分   和小数位,没有四舍五入   错误。 Decimal类型没有   消除了舍入的需要。   相反,它最大限度地减少了由于的错误   四舍五入。

如果失败了,请尝试在乘法前将两边都加倍。 float * double可能会导致double,但是当你的double是伪装浮点数与另一个浮点数相比时,编译器可能忽略了你想要的精度,“知道”两个浮点数不会产生双倍。

相关问题