Fortran: handling integer values of size: ~700000000000
Solution 1
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.
Solution 2
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.
Solution 3
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.
Solution 4
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.
Related videos on Youtube
Daniel
Updated on March 06, 2020Comments
-
Daniel about 4 years
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?
-
darjab about 14 yearsIf one may ask, for what do you need such range ?
-
-
Daniel about 14 yearsUnfortunately I am.. The problem is actually the problem of finding the larges prime factor of a humongous number.. The initial idea is pure bruteforce followed by a smar solution if i ever find one. The current idea is, the following but for obvious reasons that isen't really possible: INTEGER :: I=0,J=0,STATE=0,LARGE_DIV=0 long MAX=7100000000000 DO I=2,MAX STATE=0 DO J=2,I IF (MOD(I,J)==0) STATE=STATE+1 IF (STATE>=2) EXIT END DO IF (STATE >=2) CYCLE IF (MOD(MAX,I)==0) LARGE_DIV=I END DO WRITE(,)LARGE_DIV
-
Daniel about 14 yearsYep.. As far as i can see the highest modification allowed is kind=3.. the compiler error would be: C:\FTN_Projects\xxxxxx.F95(3) : error 217 - INTEGER(KIND=3) constant out of range (kind=3) is set by the compiler, supplied argument is kind=4
-
T.E.D. about 14 yearsThat sounds like a job for a bignum library. Surely there is one around for Fortran...
-
Vladimir F Героям слава over 6 yearsKind numbers are NOT portable. Especially given that the OP uses
kind=3
and Silverfrost Fortran thenkind=8
is not a good thing. There is no kind 8 in Silverfrost Fortran. At least not in normal settings. One can just directly useselected_int_kind (12)
in a named constant as shown in other answers.