2016-08-23 144 views
0

在fortran中,我必須將經緯度舍入小數點後的一位數字。Fortran - 要舍入到小數點一位

我使用gfortran編譯器和NINT功能,但下面不工作 -

rlons(i,j) = nint(rla2rlarot*10.0)/10.0 
+0

真正簡短的答案是,你不能這樣做。浮點表示是不精確的,並且不能保證浮點除以十(或四捨五入爲十進制)可以精確地表示您正在使用的任何大小的浮點類型。這僅用於打印或顯示? – talonmies

+0

@talonmies - 不,它不打印或顯示。我有一個輸入netcdf文件,只有一位數字後小數點。我修改了經度,我想把它寫回netcdf文件。 – gansub

+0

那麼,你不能用浮點來做到這一點。您需要使用固定點或小數類型代替 – talonmies

回答

1

有沒有辦法做到你的要求。根本問題是您所需的舍入值不一定能夠用浮點表示。

例如,如果有一個值10.58,這正是表示爲1.3225000×2^3 =在IEEE754 FLOAT32 10.580000。

當這一輪重視到小數點後一位數(無論你選擇這樣做),結果將是10.6,不過10.6並沒有一個確切的表示。在float32中,最接近的表示是1.3249999 x 2^3 = 10.599999。因此,無論您如何處理舍入,都無法將10.6完全保存在float32值中,也無法將其作爲浮點值寫入netCDF文件。

+0

這取決於「將其寫回文件」的含義。如果它是一個格式(F6.1,....),那麼它會工作。 – Holmz

+0

@Holmz:注意我寫了[* netCDF文件*](http://www.unidata.ucar.edu/software/netcdf/docs/data_type.html) – talonmies

0

是的,它可以做!上面的「接受」答案在其有限的範圍內是正確的,但是在Fortran(或其他各種HGL)中實際可以實現的內容是錯誤的。

唯一的問題是,如果像使用F(6.1)寫入的內容失敗,您願意支付什麼價格?

從一個角度看,你的問題是「任意精度」計算的主題特別瑣碎的變化。你如何想象當你需要用精確的精確度來存儲,操縱和執行1024比特數字的「數學運算」時,密碼處理是如何處理的?

在這種情況下的簡單的策略將每個數字分離成其組成「LHSofD」(十進制的左手側),而「RHSofD」值。例如,你可能有一個RLon(i,j)= 105.591,並希望打印105.6(或任何方式舍入)到您的NetCDF(或任何正常)文件。將此分解爲RLonLHS(i,j)= 105和RLonRHS(i,j)= 591.

......此時,您可以選擇增加通用性,但需要花費一定的費用。爲了節省「金錢」,RHS可能保留爲0.591(但是如果你需要做更有趣的事情,則可以忽略一般性)。

爲簡單起見,假設「廉價而愉快」的第二種策略。

LHS很簡單(Int())。

現在,對於RHS,乘以10(如果您希望輪到1 DEC),例如,到達RLonRHS(i,j)= 5.91,然後將Fortran「round到最近的Int」NInt()內在......留給RLonRHS(i,j)= 6.0。

...和鮑勃是你的叔叔:

現在您打印LHS和RHS您的netCDF使用適當的寫聲明串接「偶」,並創建一個精確的表示按在所需的目標OP。

......當然後來讀入這些值會返回到上面所述的相同問題,除非讀入也是ArbPrec意識到的。

...我們寫了我們自己的ArbPrec庫,但也有一些關於VBA和其他HGL的......但被警告完整的ArbPrec機械位是一個不平凡的問題......幸運的是你的問題非常簡單。