Bug? (large integers...)

integer :: x

x = (2*33333333333333333)

print *, x

end program

Calculated a (large) negative value (!) yet use 1 less “3” or one more “3” returns large positive integer…(?)

Not a bug. See Integer overflow.

Fortran integers are signed integers. On most systems the default integer is 32-bit. The maximum value of a 32-bit signed integer is 2147483647.

You can see this with a simpler example.

$ cat overflow.f90
  integer :: x
  x = 33333333333333333
  write(*,*) x
end

$ gfortran -o overflow.exe -Wall overflow.f90
overflow.f90:2:23:

    2 |   x = 33333333333333333
      |                       1
Error: Integer too big for its kind at (1). This check can be disabled with the option ‘-fno-range-check’

$ gfortran -o overflow.exe -Wall -fno-range-check overflow.f90

$ ./overflow.exe
  1954764117

You need to use an integer of a kind with sufficient range to store your values. Something like

$ cat nooverflow.f90
  integer, parameter :: k =  selected_int_kind(20)
  integer(kind=k) :: x
  x = 33333333333333333_k
  write(*,*) x
end

$ gfortran -o nooverflow.exe -Wall nooverflow.f90

$ ./nooverflow.exe
                        33333333333333333
1 Like

Edit: I got beat to the answer. I’ll leave mine because I’m still curious about the error I have.
Edit 2: I see from the example above I need to do z = (2*33333333333333333_wp) which removes the error.

In principle I think you should use SELECTED_INT_KIND (The GNU Fortran Compiler) to ensure the integer is big enough to hold the value.

program ex1

integer :: x
integer(8) :: y
integer,parameter :: wp = selected_int_kind(17)
integer(kind=wp) :: z

x = (2*33333333333333333)
y = (2*33333333333333333)
z = (2*33333333333333333)

print *, wp
print *, x, y, z

end program
% gfortran ex1.f90 -fno-range-check -o ex
% ./ex
           8
  -385439062    66666666666666666    66666666666666666

An 8-byte int is required… curiously, if I compile without the -fno-range-check I get an error for all three assignments.

% gfortran ex1.f90 -o ex
ex1.f90:8:25:

    8 | x = (2*33333333333333333)
      |                         1
Error: Integer too big for its kind at (1). This check can be disabled with the option ‘-fno-range-check’
ex1.f90:9:25:

    9 | y = (2*33333333333333333)
      |                         1
Error: Integer too big for its kind at (1). This check can be disabled with the option ‘-fno-range-check’
ex1.f90:10:25:

   10 | z = (2*33333333333333333)
      |                         1
Error: Integer too big for its kind at (1). This check can be disabled with the option ‘-fno-range-check’

See also Doctor Fortran in "It Takes All KINDs" - Doctor Fortran

1 Like

Now if you really need to deal with huge integers there are few libraries for it

1 Like

Undecorated integer constants have default kind, so 33333333333333333 overflows.

You need to use 33333333333333333_wp. Same with floating point constants. Common mistake.

2 Likes

Thanks for the clarification!
(Ah, ok) yep- it’s been a wee while …FORTRAN 77 , back in 1984 ( ! ) on an ICL mainframe
Glad 2 see this proj & love the Mandelbrot , BTW all the best Tim

Thanx! :grinning::+1:

It is interesting that with gfortran -fno-range-check, 4-byte integer constants are promoted to 8-byte.

The following adaptation removes the requirement for “-fno-range-check”, while still allowing integer overflow for calculating x

program ex1

integer,parameter :: wp = selected_int_kind(17)
integer :: x
integer(8) :: y
integer(kind=wp) :: z
integer(wp) :: t = 33333333333333333_wp

y = (2*33333333333333333_wp)
z = (2*t)
! x = (2*33333333333333333_wp)
x = y

print *, wp
print *, x, y, z, t

end program

I have always objected to Fortran compilers not being allowed to correctly interpret the integer constant 33333333333333333, which would be read correctly from an input file.

1 Like