2012-03-05 9 views
10

Fortran은 완전히 새로운 기능입니다. 아무도 제가 해결할 수있는 문제가 있습니까? 내 모든 종류의 숫자와 내 PC에서 각 종류 번호에 대한 가장 큰 값과 가장 작은 값을 알아 내고 싶습니다. 아래에 나열된 코드가 있습니다.Fortran : 가장 큰 정수와 가장 작은 정수

내가 얻는 정수 종류 번호는 1,2,4,8입니다.

  1. 각 종류 번호에 대해 각각의 가장 큰 정수가 같은 이유 : 2147483647? 그리고 가장 작은 정수에 대한 내장 함수가 있습니까?

  2. 서브 루틴 rang을 호출 할 때 정수형 번호를 어떻게 유지합니까? 나는 이것이 가장 큰 정수의 열쇠라고 생각한다.

+0

이 나중에 많은 사람에게 적합합니다. 내장 함수는 없지만 항상 가능한 한 가장 작은 정수를 계산하기 위해'-huge (n)'을 사용할 수 있습니다. – NoseKnowsAll

답변

15

귀하의 서브 루틴 :

subroutine rang(largest) 
    integer :: largest 
    print *, huge(largest) 
end subroutine 

입력으로 디폴트 사이즈의 정수를 취하고, 그 디폴트 사이즈의 정수에 맞는 가능한 최대 값을 출력합니다. 항상은 거대한 (기본 정수) 즉, 대부분의 시스템에서 거대한 (4 바이트 정수) 또는 2147483647을 반환합니다. huge은 변수 유형 만 고려합니다. 은 어떤 식 으로든 변수를으로 해석하지 않습니다. 위에서 한 일을 할 수있는 유일한 방법은 매개 변수가있는 파생 형식을 사용하는 것입니다.이 파생 형식은 컴파일러에서 지원하기에 충분히 새롭습니다.

program integerkinds 
    use iso_fortran_env 
    implicit none 

    integer :: i 
    integer(kind=int8) :: i8 
    integer(kind=int16) :: i16 
    integer(kind=int32) :: i32 
    integer(kind=int64) :: i64 

    integer(kind=selected_int_kind(6)) :: j6 
    integer(kind=selected_int_kind(15)):: j15 

    print *,'Default:' 
    print *, huge(i) 
    print *,'Int8:' 
    print *, huge(i8) 
    print *,'Int16:' 
    print *, huge(i16) 
    print *,'Int32:' 
    print *, huge(i32) 
    print *,'Int64:' 
    print *, huge(i64) 

    print *,'' 

    print *,'Selected Integer Kind 6:' 
    print *, huge(j6) 

    print *,'Selected Integer Kind 15:' 
    print *, huge(j15) 

end program integerkinds 

실행을 제공합니다 : 당신이 정수의 다른 종류의 범위에서 살펴 봐야 할 경우

, 당신은 다른 변수를 사용해야합니다 순전히 부록으로

$ ./intkinds 
Default: 
    2147483647 
Int8: 
    127 
Int16: 
    32767 
Int32: 
    2147483647 
Int64: 
    9223372036854775807 

Selected Integer Kind 6: 
    2147483647 
Selected Integer Kind 15: 
    9223372036854775807 
+0

IF : selected_int_kind (9) = 4, 정수 (kind = selected_int_kind (9)) :: j4 및 거대한 (j4)입니다 : 2147483647 내 PC에. selected_int_kind (r)의 정의에 따르면 -10 ** r < n > 10 ** r 범위의 정수 값 n을 나타낼 수 있습니다. IF r = 9이면 가장 큰 값은 10 ** 9-1이고 2147483647 (거대한 (j4))보다 작습니까? 나는 그것을 견딜 수 없다. – echo

+0

첫 부분 : j4가 정수 (kind = selected_int_kind (9))로 정의 되었기 때문에 예, 거대한 (j4)은 2147483647이어야합니다. 그러나 당신은 * j4를 정의해야만합니다. 변수가 정의 된 후에는 종류를 바꿀 수 없습니다. 예를 들어, 나중에 원하는만큼 selected_int_kind()를 호출 할 수 있으며 아무 것도 변경하지 않습니다. 위의 예는 다양한 종류의 유형을 정의하는 방법을 보여줍니다. –

-6

을, 또는 대체적인 관점에서 Fortran 변수는 var에 할당 된 메모리의 바이트 수로 정의됩니다. 사실, 모든 비교 가능한 컴파일러는 할당 된 바이트의 측면에서 vars를 정의합니다. 그렇지 않으면 시스템이 메모리에 할당/저장하는 것이 매우 어려울 것이며, 그러한 작업 없이는 산술 등을 수행하는 것이 매우 어렵습니다.

나를 위해, 약간 더 오래된 표기법 ("konfusion"보다는 오히려)을 사용하는 것이 더 쉽습니다. 특히, 많은 컴파일러가 종류와 유형간에 직접적인 1 : 1 대응을 제공합니다. bytes/var는 최대/최소 정수의 계산을 매우 간단하게 만듭니다 (일부 컴파일러는 비선형 또는 비 직접적인 통신을 사용합니다). 예를 들어,

Integer(1)  :: Int1  ! corresponds to a 1 byte integer 
Integer(2)  :: Int1  ! corresponds to a 2 byte integer 
Integer(4)  :: Int1  ! corresponds to a 4 byte integer 
Integer(8)  :: Int1  ! corresponds to an 8 byte integer 

비슷한 표기법은 다른 포트란 유형 (실수, 논리 등)에 적용됩니다. 모든 var 유형은 "크기"가 지정되지 않은 경우 할당 된 기본 바이트 수를가집니다

특정 유형의 최대 바이트 수는 컴파일러와 시스템에 따라 다릅니다 (예 : 정수 (16)는 모든 시스템에서 사용할 수있는 것은 아닙니다.

바이트는 8 비트이므로 1부터 번호가 매겨지면 단일 바이트는 2^8 = 256의 최대 값을 수용 할 수 있어야합니다.

그러나 Fortran에서는 (거의 모든) 숫자 변수가 "서명 됨"입니다. 이는 비트 표현의 어딘가에서 비트가 + ve 또는 -ve인지 여부를 추적하는 데 하나의 비트가 필요하다는 것을 의미합니다. 따라서이 예에서 max는 2^7이 될 것입니다. 왜냐하면 한 비트가 "부호"정보에 대해 "유실/예약"되기 때문입니다. 따라서 부호가있는 1 바이트 정수의 값은 -127 : +128입니다 (Abs (제한) 합계가 255로 표시됨). "0"은 한 곳을 차지하므로 합계 256 개의 "things"가 필요합니다. 있다).

유사한 규칙이 2^n의 지수 n과 함께 모든 바이트에 적용되며 바이트 수에 따라 다릅니다. 예를 들어 Integer (8) var는 부호 정보 용으로 1 비트 손실/예약 된 8 바이트 또는 64 비트를 가지므로 가장 큰 값은 2^63 = 9223372036854775808 (1부터 번호가 매겨진 경우) 또는 시작시 4611686018427387904

IntNum = s * Sum[ w(k) * 2^(k-1), k=1:(NumBytes*8)-1], 

은 (k)는 w (S) = "사인"(+/- 1)의 k 번째 비트에 1 또는 0이다 : 0.

의 표준 정수 데이터 모델은 다음과 같이 일반화 될 값.

형식 선언에 명시 적 숫자 또는 env 변수를 사용할 필요가 없습니다. 사용자 정의 컴파일 타임 상수 (즉, 매개 변수)가 허용됩니다.

Integer, Parameter  :: DP = Kind(1.0d0) ! a standard Double Precision/8-byte declaration 
Integer, Parameter  :: I4B = 4    ! NOTICE, here the "Integer" bit has not been explicitly "sized", so defaults to "Integer(4)" 
! 
Real(DP)     :: ADoublePrecReal  ! an 8-byte Real (approx 15 decimal places with exp +/- approx 300, see Real data model) 
! 
Integer(I4B)    :: AStandardInt  ! a 4-byte integer. 

매개 변수 문 등의 사용을 통해 액세스 할 다른 모듈에있을 수 있기 때문에 예를

를 들어, 원하는 "정밀도"의 다른 정의를 큰 복잡한 코드를 컴파일하는 간단한 문제입니다. 예를 들어, DP를 Kind (1.0)로 편집하면 선언이 적용되는 모든 곳에서 "단 정밀도"Real이됩니다.

Fortran 내장 함수 Huge(), Tiny() 등은 주어진 시스템에서 가능한 것을 결정하는 데 도움이됩니다.

Fortran "비트"내장 함수 및 기타 도구/메소드를 사용하면 훨씬 많은 작업을 수행 할 수 있습니다.

+6

이 대답은 잘못된 것부터 시작합니다 : 포트란 변수는 그들이 차지하고있는 바이트 수로 정의되지 않습니다. 종류 선택자 인'integer (8)'이나'real (4)'와 같은 표현식의 정수는 단순히 컴파일러가 지원하는 종류 중 하나를 식별합니다. 예를 들어, NAG Fortran 컴파일러는 4 바이트 정수의 경우 'integer (2)'로, 8 바이트 정수의 경우 'integer (3)'로 기본 설정됩니다. 컴파일러는 사용 된 바이트 수와 일치하는 종류 선택기를 사용하는 것이 일반적이지만 표준에서는 필요하지 않습니다. –

+3

이것은 일반적인 오해입니다. 또한 http://stackoverflow.com/questions/3170239/fortran-integer4-vs-integer4-vs-integerkind-4 –

+0

예. 각 컴파일러 공급 업체는 원하는대로 할 수 있으며 종종 그렇게합니다. 그리고 네, 시스템 간 차이에 중점을 두는 데 도움이되었을 것입니다 (분명히, 일단 충분하지 않은 경우). 여전히 원래의 주석은 Compaq, DEC, IBM, CRAY, Oracle, Intel 등의 컴파일러에 대해 정확하고 종류/바이트가 정확히 일치합니다.나는 또한 다른 사람들이 와드를 인용하는 것과 같은 이유로 똑같은 좋은 관행으로서 세계적인 매개 변수의 사용을 강조했다. 또한 Integer Data 모델 공식이 정확하다는 것이 확실합니다. 모든 책을 확인하십시오. – DrOli

관련 문제