[英]Operation on floats loses precision and changes sign
我有一個特殊的問題。 我的任務是在工作中重構一些舊的c代碼,我遇到了一個問題。
我有三個浮點陣列名稱VIL,ZET和GZ3D。
使用以下代碼生成VIL中的值:
for(k=1;k<sommet[i];k++)
{
if(ZET[k][i]>0)
{
Z=pow(10.0,ZET[k][i]/10.0);
VIL[i]=VIL[i]+0.00344*(GZ3D[k][i]-GZ3D[k-1][i])*(float)pow(Z,(4.0/7.0))/1000.0;
}
}
我復制了包含計算的函數,我已經運行了它。 但是現在當我比較舊代碼(核心)和我的結果創建的結果時,我得到了這個:
VIL is not equal between the two files at the index [10748]
Values "old:new" :0.079468:-0.086186
VIL is not equal between the two files at the index [10749]
Values "old:new" :0.073242:-0.085514
VIL is not equal between the two files at the index [10750]
Values "old:new" :0.070435:-0.083805
VIL is not equal between the two files at the index [10751]
Values "old:new" :0.067200:-0.081059
VIL is not equal between the two files at the index [10752]
Values "old:new" :0.063843:-0.077580
VIL is not equal between the two files at the index [10753]
Values "old:new" :0.056824:-0.072087
VIL is not equal between the two files at the index [10754]
Values "old:new" :0.054077:-0.068363
所以我得到的結果是負面的,總是相差約10%。
有人知道是什么原因引起的嗎?
嘗試使用double而不是float來進行強制轉換和變量類型。 雙倍大小為8字節,而浮點數為4。
如上所述使用雙重計算並將手動優先級設置為操作
VIL[i]=VIL[i]+ ((0.00344*(GZ3D[k][i]-GZ3D[k-1][i])) * ((float)pow(Z,(4.0/7.0))) /1000.0);
如果可能的話,你應該避免降低精度的操作:兩個非常大或很小的值的乘法,加法或減法,其中一個操作數很大而第二個很小,等等......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.