繁体   English   中英

C#中的浮点数和双精度

[英]Float and double precision in c#

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

我的循环如下:

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;
    }
}

如您所见,我强制执行(double)精度以确保两个浮点数相乘时不会失去精度。

查看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一直认为,由于我已经在乘以浮点数,因此它不应该使用双精度乘法,而应该使用单精度乘法,这给了我一直在跟踪的错误。

我对吗 ? 有什么办法可以强制这种双精度乘法吗?

谢谢

认为您在误解大会。 我相信FMULP始终在80位寄存器上运行。 看到JIT在这里做错了事,我会感到惊讶。

我建议您使用我的DoubleConverter在算术前后写出精确的值。 这样,您应该对发生的事情有更好的了解。

您可能需要切换到十进制以提高精度

首先,有什么原因不能使用十进制? 小数保持任何数字的必要精度,并且没有令人讨厌的“浮点数的最近二进制表示”问题,浮点数会导致xy = z +-.0000000000 ... 0000001错误。

从MSDN:

十进制值类型表示十进制数,范围从正数79,228,162,514,264,337,593,543,950,335到负数79,228,162,514,264,337,593,543,950,335。 十进制值类型适用于需要大量有效整数和小数位数且无舍入误差的财务计算。 十进制类型不能消除舍入的需要。 而是,它使由于舍入而产生的错误最小化。

如果失败,请尝试在乘法之前将双方都翻倍。 float * double可能会导致加倍,但是由于double是与另一个float相比变相的float,因此编译器可能会忽略您所需的精度,“知道”两个float不会成为double。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM