2017-01-21 1 views
0

1E-1200과 같이 포트란에서 아주 작은 숫자를 얻을 수 있습니까? 나는 파이썬에서 그것을하는 법을 알고 있지만, 석사 학위 논문의 코드는 너무 느리게 실행됩니다. 상사가 Fortran을 사용하도록 권유하지만, 이것이 문제가되는지 확실하지 않습니다.포트란의 숫자가 매우 작음

+0

나는 요새이지만, 그럼에도 알고리즘이 충분히 빠르는지 확인하고 싶습니다. 언어를 변경해도 기적을 일으키지 않습니다. 일부 루프는 Python에서 느립니다. –

+3

안녕하세요 @wafelos, 적절한 단위 시스템 (즉, 원자 단위 https://en.wikipedia.org/wiki/Atomic_units)을 사용하면 부동 소수점 숫자의 범위가 훨씬 좁아지는 경우가 종종 있습니다. 128 가지 정밀도 유형을 사용하면 계산이 하드웨어에서 지원되지 않으므로 속도가 느려질 수 있다는 점을 알아야합니다. –

답변

0

대부분의 Fortran 컴파일러는 IEEE binary128과 일치하는 REAL128 데이터 형식을 지원합니다. 일부는 비슷한 범위의 REAL80을 지원하며 C long double과 일치합니다. 이것들은 REAL64의 퍼포먼스를 가지고 있지 않지만 파이썬보다 훨씬 빠르다.

+0

C는'long double '형식을 지정하지 않으므로 다른 형식도 있습니다. MSVC에서 'long double'은 'double'과 정확히 동일합니다. 80 비트 확장 정밀도가없는 플랫폼에서는 IEEE-754 배정도 또는 4 배 정밀도 일 수 있습니다 –

1

짧은 대답은 '예'입니다.

현대 컴파일러는 일반적으로 128 비트 실수 인 소위 4 배 정밀도를 지원합니다. 이 유형에 액세스하는 이동식 방법은 ISO_FORTRAN_ENV입니다. 방법은 다음과 같습니다 크고 작은이 숫자를 얻을 보여줄 수있는 샘플 프로그램은 다음과 같습니다

program main 
    use ISO_FORTRAN_ENV, only : REAL32, REAL64, REAL128 

    ! -- tiny and huge grab the smallest and largest 
    ! -- representable number of each type 
    write(*,*) 'Range for REAL32: ', tiny(1._REAL32), huge(1._REAL32) 
    write(*,*) 'Range for REAL62: ', tiny(1._REAL64), huge(1._REAL64) 
    write(*,*) 'Range for REAL128: ', tiny(1._REAL128), huge(1._REAL128) 
end program main 

REAL32, REAL64REAL128는 일반적으로 싱글, 더블, 및 쿼드 정밀도로 알려져 있습니다 종류. 긴 타입은 표현할 수있는 숫자의 범위가 더 크다. 이 더 정확하다. gfortran 4.8 내 시스템에서

, 내가 얻을 : 당신이 볼 수 있듯이

mach5% gfortran types.f90 && ./a.out 
Range for REAL32:  1.17549435E-38 3.40282347E+38 
Range for REAL62:  2.2250738585072014E-308 1.7976931348623157E+308 
Range for REAL128: 3.36210314311209350626E-4932 1.18973149535723176502E+4932 

는 쿼드 정밀도는 3.4E-4932 작게 숫자를 나타낼 수 있습니다.

4

ISO_FORTRAN_ENV에서 REAL128을 사용하라는 이전 답변은 휴대용이 아닌 해결책을 설명합니다. 여기서 얻으려는 것은 128 비트의 표현을 가진 실제 유형이지만 유형의 범위 나 정밀도에 대해서는 아무 것도 말하지 않습니다! 예를 들어, 일부 IBM 시스템은 128 비트 실제 종류를 가지며 실제로는 오프셋 지수가있는 두 개의 복식입니다. 이렇게하면 정밀도가 향상되지만 범위는 크게 확대되지는 않습니다.

올바른 방법은 SELECTED_REAL_KIND 내장 함수를 사용하여 원하는 범위를 지원하는 구현의 종류를 결정하는 것입니다. 구현이 플러스 또는 마이너스 1200의 진수 지수로 값을 나타낼 수있는 실제 종류가없는 경우

integer, parameter :: bigreal = SELECTED_REAL_KIND(R=1200) 
real(KIND=bigreal) :: x 

것은, 당신이 오류가 발생합니다 그렇지 않으면 당신은 가장 작은 적절한를 얻을 수 있습니다 : 예를 들어, 종류.

호출에서 P = 값을 지정하여 최소 정밀도 (십진수)를 나타낼 수도 있습니다.