# Integer 4 or integer 8?

Dear all,

I have a quick question, do you use integer 4 or integer 8?

For example, I define my integer 4 as

``````integer (kind=i4)
``````

and integer 8 as

``````integer (kind=i8)
``````

where

``````integer, private, parameter :: i4=selected_int_kind(9)
integer, private, parameter :: i8=selected_int_kind(15)
``````

While `np` and `nd` are all integer 4 type, `np*nd` can be big enough can become integer 8 type. So if I need a variable `jjj` to represent `np*nd`, probably I need to define `jjj` as integer 8,

``````integer(kind=i4) :: np,nd
integer(kind=i8) :: jjj
jjj = np*nd
``````

I mean if I have integer 4 and integer 8 types, I need to be careful enough and make sure when the product of integer 4 becomes big enough and requires integer 8. It is OK to use minimal data type in this way, but occasionally it may not be the most convenient perhaps.

So I wonder, how do you guys deal with such situation?
Do you just use integer 8 everywhere or something?

I found using integer 8 everywhere is perhaps not the most convenient either, and may very slightly slow down the code. So I am not exactly sure what is the best approach.

Most of the time, I just use the default kind, which I know will be at least 4 bytes on PC:

``````integer :: i
``````

If I know or suspect that the value may become big (>2^31), I use `integer(int64)` (defined in iso_fortran_env). And `int8` (8 bits) or `int16` may be useful if memory matters (big integer arrays).

Considering speed, I am not sure `int64` will be slower on nowadays 64 bits CPU.

1 Like

In the original version of OP there was an array AAA(np,nd). I guess that internally, the processor should deal properly even with AAA(100000,100000) although the indices would overflow when simply multiplied.

In explicit calculations, however, one has to make sure there is no overflow and use proper kind(s). Note also, that with your declarations:

``````integer(kind=i4) :: np,nd
integer(kind=i8) :: jjj
jjj = np*nd
``````

`jjj` will not be properly assigned if `np*nd` overflows in `i4` kind. Consider sample program:

``````program main
use iso_fortran_env, only: i4=>int32, i8=>int64
integer(i4) :: i=100000, j=100000
integer(i8) :: bi,bj
bi = i*j              ! overflows, assigns bad value
bj = int(i,kind=i8)*j ! converted to i8 before multiplication
print *, bi, bj
end program main
! outputs:    1410065408       10000000000
``````
1 Like

On WSL2 compiling the code above with `gfortran -g -ftracer -ftrapv int_overflow.f90` and running I get

``````(base) /mnt/c/fortran/test\$ ./a.out

Program received signal SIGABRT: Process abort signal.

Backtrace for this error:
#0  0x7f99f6416700 in ???
#1  0x7f99f64158a5 in ???
#2  0x7f99f622e20f in ???
#3  0x7f99f622e18b in ???
#4  0x7f99f620d858 in ???
#5  0x7f99f63dea41 in ???
#6  0x55db6d14a1b8 in MAIN__
at /mnt/c/fortran/test/int_overflow.f90:5
#7  0x55db6d14a297 in main
at /mnt/c/fortran/test/int_overflow.f90:8
Aborted
``````

I use plain `integer` in my codes but should probably compile with `-ftrapv` to ensure that I am not missing integer overflow.

1 Like

Sure if you add `-ftrapv`, signed overflow will cause exception. But w/o it, gfortran (ifort as well) produces code that silently ignores overflow giving bogus results. For `ifort` there seems to be no equivalent of `-ftrapv`. For other compilers I do not know.

2 Likes

Thank you very much @vmagnin @msz59 @Beliavsky !
How about simply just use integer 8 everywhere? Is there any drawback?

I do not think any significant slowdown can be possible on 64-bit machines, 64-bit code. Unless your huge arrays (such that `np*nd>2G`) are integer also. Then you’ll get memory requirements really bigger.

1 Like

Thank you @msz59 , your ` bi = i*j` illustration is indeed great! Thank @Beliavsky too!
I did not realize that will cause an overflow, since `bi` on the left-hand-side is integer 8, I assume i*j should automatically be integer 8 and is calculated correctly.
But it seems it is not that intelligent and I need to be careful. Probably I may just use integer 8 instead.

A general rule of Fortran is that the RHS of an assignment is computed independently of what is on the LHS and then converted to that type. The product of two default integers is always a default integer.

1 Like
1. I am too lazy to write unnecessarily more than `integer ::` and the code looks nice and simpler that way… 2. I am too old to waste 4 bytes without reason. I learned BASIC in the early 80’s on pocket computers with 1024 bytes RAM… Moreover, in the 90’s 32 bits integers were faster than 64 bits… 2 Likes

The times have changed, grandpa … 2 Likes

If anything, they have changed to make 32 bit integers more attractive. Data movement is what you pay for in time and energy and heat. If 32 bits are enough, it would be daft not to use them.