在Fortran中有快速的方法嗎?在fortran中快速向上/向下翻轉兩倍?
由於正雙數的位表示的線性順序,所以可以實現如下的舍入。
pinf
和ninf
是分別+/-無窮
function roundup(x)
double precision ,intent(in) :: x
double precision :: roundup
if (isnan(x))then
roundup = pinf
return
end if
if (x==pinf)then
roundup = pinf
return
end if
if (x==ninf)then
roundup = ninf
return
end if
if (x>0)then
roundup = transfer((transfer(x,1_8)+1_8),1d0)
else if (x<0) then
roundup = transfer((transfer(x,1_8)-1_8),1d0)
else
if (transfer(x,1_8)==Z'0000000000000000')then
roundup = transfer((transfer(x,1_8)+1_8),1d0)
else
roundup = transfer((transfer(-x,1_8)+1_8),1d0)
end if
end if
end function roundup
我覺得這是沒有這樣做,因爲它的速度慢的最好辦法全局常量,但它幾乎只使用位操作。
的另一種方法是使用乘法和一些小量 eps = epsilon (1d0)
function roundup2(x)
double precision ,intent(in) :: x
double precision :: roundup2
if (isnan(x)) then
roundup2 = pinf
return
else if (x>=eps) then
roundup2 = x*(1d0+eps)
else if (x<=-eps) then
roundup2 = x*(1d0-eps)
else
roundup2 = eps
end if
end function roundup2
對於一些x
兩個函數返回相同的結果(1D0,158d0),對於一些不(0.1d0,15d0)。
第一功能是更準確的,但它比第二 慢大約3.6倍(11.1 VS3.0秒上10^9輪試驗)
print * ,x,y,abs(x-y)
do i = 1, 1000000000
x = roundup(x)
!y = roundup2(y)
end do
print * ,x,y,abs(x-y)
在沒有檢查的NaN /無窮大第一功能測試需要8.5秒(-20%)。
我使用循環功能真的很難,它需要很多時間在程序的配置文件。是否有跨平臺的方式可以更快速地完成並且沒有精確性?
更新
的問題,在沒有能力對它們重新排序的時間嫌疑人圍捕和ROUNDDOWN的電話。我沒有提到輪換,以保持話題的簡短。
提示: 第一個函數使用兩個transfer
函數和一個加法。在第二種情況下,它比一個乘法和一個加法要慢。爲什麼轉移成本這麼多,當它不做任何數字的位?是否可以用更快的功能代替傳輸或者完全避免添加呼叫?
您是否嘗試過使用nint? – cup
我需要「四捨五入」到最接近的代表double而不是int。標題可能有點誤導,但從身體清楚。 – Sergei