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…(?)
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
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
Undecorated integer constants have default kind, so 33333333333333333 overflows.
You need to use 33333333333333333_wp. Same with floating point constants. Common mistake.
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!
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.