Fortran: handling integer values of size: ~700000000000
Currently I'm brushing up on my Fortran95 knowledge (don't ask why)...
I'm running in to a problem though. How does one handle large integers, eg. the size of: ~700000000000
INTEGER(KIND=3) cannot hold this number. If anyone is interested the compiler I have available is Silverfrost FTN95.
I am using the integer to run through a larger set of data.开发者_运维知识库
Do you have any suggestions?
The standard solution (since Fortran 95, so I assume your compiler supports it) is to use the SELECTED_INT_KIND
intrinsic to probe for valid integer kinds (whose values are compiler dependent) and the HUGE
intrinsic.
SELECTED_INT_KIND (R)
returns the kind type parameter of an integer type that represents all integer values n with −10^R < n < 10^R (and returns -1 if no such type exist).HUGE (K)
returns the largest representable number in integer type of kind K.
For example, on my Mac with an x86_64 processor (gfortran compiler, 64-bit mode), the following program:
print *, selected_int_kind(1)
print *, selected_int_kind(4)
print *, selected_int_kind(8)
print *, selected_int_kind(16)
print *, selected_int_kind(32)
print *, selected_int_kind(64)
print *, huge(0_1)
print *, huge(0_2)
print *, huge(0_4)
print *, huge(0_8)
print *, huge(0_16)
end
outputs:
1
2
4
8
16
-1
127
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
which tells me that I'd use an integer(kind=8)
for your job.
The portable to declare an integer "index" that will have at least 12 decimal digits is:
integer, parameter :: MyLongIntType = selected_int_kind (12)
integer (kind=MyLongIntType) :: index
The "kind=" may be omitted.
Using specific values such as 3 is completely non-portable and not recommended. Some compilers use the type numbers consecutively, others use the number of bytes. The "selected_int_kind" will return the kind number of the smallest integer kind available to the compiler that can represent that requested number of digits. If no such type exists, -1 will be returned, and the value will fail when used kind value to declare an integer.
Both gfortran and ifort return a kind for decimal digits input to selected_int_kind up up to 18. Large values such as 18 will typically select an 8-byte integer with a largest positive value of 9223372036854775807. This has 19 digits, but if a compiler supports this type but not a longer one, selected_int_kind (19) will be -1, because not all 19 digit integers are representable.
There are a number of free arbitrary-precision libraries available for Fortran which would deal with this problem. FMLIB is one. Five or six more alternatives are linked from this page.
If you are using it as a loop control variable, but aren't using the integer directly (which I guess you can't be, as you can't declare an array larger than the largest index representable, right?), then I guess the thing to do is divide that puppy by something like 100000 and nest its loop in another loop that iterates that many times.
Have you tried INTEGER(KIND=4)?
Our answer to that was to put the value in a double precision variable and do a DINT on it to get rid of any fractional parts. The results are an integer placed in a double precision variable. The function DINT is not always available to all FORTRANs. The function is a double precision integer function and this will allow for very large integers (up to 17 digits).
精彩评论