integer arithmetic

integer arithmetic

Hi,

I have a simple question, but I can't figure out the answer.  Does anyone know why the following program outputs b=-589934592 instead of b=8000000000 ?   This must be related to the product of a*a*a causing an integer overflow.  I want to have intermediate variables be integer(kind=4) and the result stored in integer(kind=8).

program test_integer8
implicit none
integer(kind=4) a
integer(kind=8) b
a = 2000
b = a*a*a    ! How do you fix this line?
write(*,*) 'b = ', b
stop
end program test_integer8

Roman

16 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

I suspect it's overflowing because the right hand side is considered kind=4.  You could try:

b = NINT(a,8)*NINT(a,8)*NINT(a,8)

but I haven't tried that -- only a guess.

Linda is correct about the overflow. Easiest is to make a integer(8) as well. Linda's suggestion will work, but you would use INT rather than NINT - NINT isn't defined on integers.

Retired 12/31/2016

Linda, thanks for the suggestion.  NINT did not work because is expects a to be of type real, but the following worked:

b = INT(a,8)*INT(a,8)*INT(a,8)

Roman

Yea, I get those confused.  The intent was right though...

An easy change would be :

b = a  ;  b = b*b*b

You only need to promote one of the 'a', e.g. b = a*a*int(a,8)

Quote:

You only need to promote one of the 'a', e.g. b = a*a*int(a,8)

b = a*(a*int(a,8))

the b=a might not work.  b=int(a,8) would be better.

Quote:

lklawrie wrote:

the b=a might not work.  b=int(a,8) would be better.

What would stop b = a from working ?

It would work, but I have a general distaste for mixed-mode arithmetic or assignments. I think it's clearer when you express conversions explicitly. (I would also discourage use of literals such as 8 for kind values - better to define PARAMETER constants using SELECTED_INT_KIND, etc.) 

Retired 12/31/2016

Thanks for the comments.

Steve, what is the reason you discourage literals for kind values?  I like them because I immediately know how much memory will be needed.  integer(kind=4) will need 4 bytes per variable, integer(kind=8) will need 8 bytes, etc.  The only exception is when working with complex variables since complex(kind=8) will need 8*2=16 bytes.  Is the problem that the kind values are not standard, and on a different platform might mean something different?

Roman

Quote:

Roman wrote:
What is the reason you discourage literals for kind values?

Kind values are not portable between compilers. For example, the NAG compiler uses kind=1 for 32-bit reals and kind=2 for 64-bit reals (.i.e., double precision).

Exactly. I would also argue that in most cases you don't need to know how much storage is taken up - you just want to know what range of values you can store. In the circumstances where you do need to know the size, there are intrinsics such as STORAGE_SIZE and C_SIZEOF that can help you with that. The C interoperability features also define kind constants for specific sizes of integers and reals.

Retired 12/31/2016

Are there any current compilers that do not support real*4 and real*8 ?

As someone who has converted codes between operating systems, I will never stop using this clear syntax.

I don't know of current compilers that don't support that extension, but I would encourage you to use standard syntax where available and when writing new code. I don't recommend going back and changing existing code.

Retired 12/31/2016

Leave a Comment

Please sign in to add a comment. Not a member? Join today