Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29486 Discussions

Compiler bug with integer(8) computations (?)

WSinc
New Contributor I
1,081 Views
I realize there was an issue with multiplying two integer(4) quantites, but this is an entirely different
"can of worms." See source code.

! Apparently the compiler does not know how to work with some literal expressions
! larger than 31 bits. It computes the wrong values for MASK, MAXREP, etc.
! As long as I keep the power of 2 < 31, it computes the correct expression values.
! I didn't see anything in the writeups about this limitation.
! The compiler does not give any warning messages.
PROGRAM TEST_DoLoop
implicit NONE
integer(2) ipwr,iadd
integer(8) nrep,maxrep,mask,wrong1,wrong2
! mask=2**32 + 2**16 + 2**5 + 1 ! DOES NOT WORK
mask=2**16 ! the workaround
mask=mask*mask + 2**16 + 2**5 + 1 ! the workaround
print *,"mask=",mask
! if I set ipwr to 31 and addon to -1
! it executes the proper number of reps.
! If addon = 0 or higher, the # of reps is ZERO.
print *,"power of 2, addon:"
read *,ipwr,iadd
maxrep=2**ipwr+iadd ! gives wrong results for ipwr > 31
! to get around this problem, I have to resort to something like thei
maxrep=2**(ipwr/2)
maxrep=maxrep**2 + iadd
! is there anything in the compiler setup parameters that might address this issue?
! this seems pretty straightforward - - - -
do nrep=1,maxrep
enddo
print *,"nrep=",nrep
wrong1=5**30 ! gives wrong results
wrong2=7**27 ! Same here
! Could it be the ** operator?
print *,"wrong1=",wrong1
print *,"wrong2=",wrong2
pause "exiting"
end program

Suggestion: Give a REWARD for finding these problems (if not detected already).
0 Kudos
6 Replies
Steven_L_Intel1
Employee
1,081 Views
Bill,

You will find a "writeup" of this issue, and others you have reported, in a Fortran 90/95/2003 textbook. You share a common misunderstanding of how Fortran determines the type and kind of an expression.

In the case of:

mask=2**32 + 2**16 + 2**5 + 1

everything on the right side of ther assignment is "default integer" or integer(4). It does not matter that the variable being assigned to is integer(8) - that is not taken into consideration. Since all elements of the expression are integer(4), the whole expression is integer(4). It would be nice if the compiler warned you of integer overflow, but it doesn't.

One solution is to use kind specifiers, as I recommended in an earlier thread. For example:

mask=2_8**32 + 2_8**16 + 2_8**5 + 1_8

Your workaround works because mask, an integer(8) entity, is in the expression so the other operand gets converted to integer(8) before the addition. This can still be risky, though, if other elements are still integer(4).

Read up on mixed-mode arithmetic and take care to use kind specifiers consistently when you are using non-default kinds.
0 Kudos
WSinc
New Contributor I
1,081 Views
Still, wouldn't it be nice if we could at least get a warning, namely

that integer(4) computations are being used for an integer(8) result?

The book I have doesn't discuss this issue in much of any useful detail.

Perhaps you can recommend a better text (?) if that isn't against Intel's

policy.

Even if the computations ARE integer(4), why wouldn't the compiler flag
a quantity like 5**30, since it's pretty obvious that won't fit into a 32
bit word?

Or if you multiply two literals together, i.e. 14289473*34582930, the compiler should KNOW that
the result would be too big.

Seems pretty obvious to me anyway . . . .
0 Kudos
Steven_L_Intel1
Employee
1,081 Views
A warning would not be appropriate for the assignment as that's perfectly legal Fortran.

There are several books listed in our documentation under "Related Information", as follows:

  • Introduction to Programming with Fortran with coverage of Fortran 90, 95, 2003 and 77, by I.D. Chivers and J. Sleightholme; published by Springer, ISBN 9781846280535

  • The Fortran 2003 Handbook: The Complete Syntax, Features and Procedures, by Adams, J.C., Brainerd, W.S., Hendrickson, R.A., Maine, R.E., Martin, J.T., Smith, B.T., published by Springer Verlag, ISBN: 9781846283789

  • Fortran 95/2003 For Scientists and Engineers, by Chapman S.J., published by McGraw- Hill. ISBN ISBN 0073191574

  • Fortran 95/2003 Explained, by Metcalf M., Reid J. and Cohen M., 2004, published by Oxford University Press. ISBN 0-19-852693-8

I have read the Chapman, not the others. You might browse the descriptions and reviews on Amazon, etc., to see what people think of them.

I agree that the compiler should warn when a compile-time expression overflows. I will ask the developers about that.
0 Kudos
WSinc
New Contributor I
1,081 Views
Ok, to play it safe, I did as you suggested, and used 8 byte literals everywhere appropriate.

BTW, this gives the wrong answer also:

print *,2_8**63

It gives a negative number.
This is germaine to our previous discussion.

So a good compiler option (enhancement) would be to allow the user to specify that all literal expressions
could use 64 bit (integer(8)) computations instead.

Especially when it give wrong results with no warnings.
0 Kudos
Steven_L_Intel1
Employee
1,081 Views
What would you expect that to print? 2**63 is, in two's-complement binary, a negative number. Fortran does not have unsigned numbers.
0 Kudos
WSinc
New Contributor I
1,081 Views
An unaware person would think that 2**63 should be a positive number, since any power of a positive integer has to be > 0.

Of course, we know that 2**63-1 is the largest number possible in the integer(8) range.

print *,2_8**63 -1

does give the correct answer.
0 Kudos
Reply