WPS icon indicating copy to clipboard operation
WPS copied to clipboard

Outside integer(kind=8) range?

Open davegill opened this issue 5 years ago • 4 comments

In WPS, I am looking at the file ungrib/src/ngl/g2/intmath.f.

Here is the entire function (with line numbers to make identification easy):

     80       function ilog2_8(i_in)
     81       implicit none
     82       integer(kind=8), value :: i_in
     83       integer(kind=8)::ilog2_8,i
     84       ilog2_8=0
     85       i=i_in
     86       if(i<=0) return
     87       if(iand(i,i-1)/=0) then
     88          !write(0,*) 'iand i-1'
     89          ilog2_8=1
     90       endif
     91       if(iand(i,Z'FFFFFFFF00000000')/=0) then
     92          ilog2_8=ilog2_8+32
     93          i=ishft(i,-32)
     94          !write(0,*) 'iand ffffffff',i,ilog2_8
     95       endif
     96       if(iand(i,Z'00000000FFFF0000')/=0) then
     97          ilog2_8=ilog2_8+16
     98          i=ishft(i,-16)
     99          !write(0,*) 'iand ffff' ,i,ilog2_8
    100       endif
    101       if(iand(i,Z'000000000000FF00')/=0) then
    102          ilog2_8=ilog2_8+8
    103          i=ishft(i,-8)
    104          !write(0,*) 'iand ff',i,ilog2_8
    105       endif
    106       if(iand(i,Z'00000000000000F0')/=0) then
    107          ilog2_8=ilog2_8+4
    108          i=ishft(i,-4)
    109          !write(0,*) 'iand f',i,ilog2_8
    110       endif
    111       if(iand(i,Z'000000000000000C')/=0) then
    112          ilog2_8=ilog2_8+2
    113          i=ishft(i,-2)
    114          !write(0,*) 'iand c',i,ilog2_8
    115       endif
    116       if(iand(i,Z'0000000000000002')/=0) then
    117          ilog2_8=ilog2_8+1
    118          i=ishft(i,-1)
    119          !write(0,*) 'iand 2',i,ilog2_8
    120       endif
    121       end function ilog2_8

I am getting a compile-time error that says that the value on line 91 is larger than an integer(kind=8).

From this page, https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gfortran/BOZ-literal-constants.html, there is a line:

Note that initializing an INTEGER variable with a statement such as DATA i/Z'FFFFFFFF'/ will give an integer overflow error rather than the desired result of -1 when i is a 32-bit integer on a system that supports 64-bit integers. 

From this page, the largest integer(kind=8) is 9.2(10)^18: http://www.cs.uwm.edu/classes/cs151/Bacon/Lecture/HTML/ch06s09.html

The value of FFFF FFFF FFFF FFFF is twice as large, 1.8(10)^19.

davegill avatar Oct 27 '20 15:10 davegill

@mgduda @micurry Folks, Please take a look at this question about the size of an integer(kind=8).

davegill avatar Oct 27 '20 15:10 davegill

@mgduda @MiCurry I am thinking that since Fortran does not have an unsigned integer, that the largest 8 byte integer should be:

7F FF FF FF FF FF FF FF

davegill avatar Oct 27 '20 15:10 davegill

This part of the Fortran 2003 standard may be relevant:

4.4.1 Integer type

C410 (R411) A boz-literal-constant shall appear only as a data-stmt-constant in
a DATA statement, as the actual argument associated with the dummy argument A of
the numeric intrinsic functions DBLE, REAL or INT, or as the actual argument
associated with the X or Y dummy argument of the intrinsic function CMPLX.

Does it help matters to change line 91 so that it reads:

       if(iand(i,int(Z'FFFFFFFF00000000',kind=8)/=0) then

The GNU 10 compilers generate the following error when compiling module_ra_cam_support.F, so I've been interested in the use of BOZ literal integer constants as well:

module_ra_cam_support.F:11:35:

   11 |       integer, parameter:: bigint = O'17777777777'           ! largest possible 32-bit integer
      |                                   1
Error: BOZ literal constant at (1) is neither a data-stmt-constant nor an actual argument to INT, REAL, DBLE, or CMPLX intrinsic function [see ‘-fno-a
llow-invalid-boz’]

mgduda avatar Oct 27 '20 15:10 mgduda

There's a forum post with some discussion of this issue, too.

mgduda avatar Dec 02 '20 21:12 mgduda