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

integer arithmetic

Roman1
新分销商 I
2,873 次查看

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).

[fortran]
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
[/fortran]

Roman

0 项奖励
15 回复数
lklawrie
初学者
2,873 次查看

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.

0 项奖励
Steven_L_Intel1
2,873 次查看

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.

0 项奖励
Roman1
新分销商 I
2,873 次查看

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

0 项奖励
lklawrie
初学者
2,873 次查看

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

0 项奖励
John_Campbell
新分销商 II
2,873 次查看

An easy change would be :

b = a  ;  b = b*b*b

0 项奖励
Simon_Geard
新分销商 I
2,873 次查看

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

0 项奖励
TimP
名誉分销商 III
2,873 次查看

[email protected] wrote:

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

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

0 项奖励
lklawrie
初学者
2,873 次查看

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

0 项奖励
John_Campbell
新分销商 II
2,873 次查看

lklawrie wrote:

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

What would stop b = a from working ?

0 项奖励
Steven_L_Intel1
2,873 次查看

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.) 

0 项奖励
Roman1
新分销商 I
2,873 次查看

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

0 项奖励
mecej4
名誉分销商 III
2,873 次查看

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).

0 项奖励
Steven_L_Intel1
2,873 次查看

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.

0 项奖励
John_Campbell
新分销商 II
2,873 次查看

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.

0 项奖励
Steven_L_Intel1
2,873 次查看

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.

0 项奖励
回复