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
각각 무한대 +/-하는 전역 상수하지만, 거의 유일한 비트 연산을 사용합니다. 일부는하지 (0.1d0, 15d0)을 수행하기위한
또 다른 방법
이 같은 결과 (1D0, 158d0)를 곱셈과 일부x
두 함수의 일부 엡실론
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
을 반환 사용하고 있습니다.
첫번째 기능은 더 정확하지만,이 NaN 없음 수표
print * ,x,y,abs(x-y)
do i = 1, 1000000000
x = roundup(x)
!y = roundup2(y)
end do
print * ,x,y,abs(x-y)
(10^9 발사 시험 11.1 VS 3.0 초) 초 보다 약 3.6 배 느리다/무한대 제 1 기능 테스트는 소요 8.5 초 (-20 %).
난 둥근 기능을 정말 열심히 사용하며 프로그램의 프로필에서 많은 시간이 걸립니다. 정밀도가 떨어지지 않고 더 빨리 라운드 할 수있는 크로스 플랫폼 방식이 있습니까?
업데이트
문제는 그 순서를 할 수없는 능력을 가진시 검거 및 ROUNDDOWN의 호출을 의심. 나는 주제를 짧게 유지하기 위해 라운드 다운을 언급하지 않았다.
힌트 : 첫 번째 기능은 두 개의 transfer
기능과 하나의 기능을 사용합니다. 그리고 두 번째 경우에는 하나의 곱셈과 하나의 덧셈보다 느립니다. 숫자를 조금이라도 옮기지 않으면 비용이 많이 들지 않는 이유는 무엇입니까? 더 빠른 기능으로 전송을 대체하거나 추가 호출을 전혀 피할 수 있습니까?
nint를 사용해 보셨습니까? – cup
int가 아닌 가장 가까운 대표 값으로 "round"해야합니다. 제목은 다소 오도 될 수 있지만 신체에서 분명합니다. – Sergei