Fortran: handling integer values of size: ~700000000000

22,817

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.

Share:
22,817

Related videos on Youtube

Daniel
Author by

Daniel

Updated on March 06, 2020

Comments

  • Daniel
    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
      darjab about 14 years
      If one may ask, for what do you need such range ?
  • Daniel
    Daniel about 14 years
    Unfortunately 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
    Daniel about 14 years
    Yep.. 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.
    T.E.D. about 14 years
    That sounds like a job for a bignum library. Surely there is one around for Fortran...
  • Vladimir F Героям слава
    Vladimir F Героям слава over 6 years
    Kind numbers are NOT portable. Especially given that the OP uses kind=3 and Silverfrost Fortran then kind=8 is not a good thing. There is no kind 8 in Silverfrost Fortran. At least not in normal settings. One can just directly use selected_int_kind (12) in a named constant as shown in other answers.

Related