[英]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.