Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Assigning small integer to larger one

Status
Not open for further replies.

atothep

Programmer
Mar 20, 2012
3
DE
Hi everyone,

consider the following code snippet:

ccccccccccccccccccccccccccccccc
integer*4 :: i, j
integer*8 :: k

i = 1000000
j = 2000000
k = i * j
ccccccccccccccccccccccccccccccc

My question is:
Is there any standard how this will be evaluated? Or is this compiler dependent?
I mean, the problem should be clear: if the multiplication is evaluated with 4 byte integers, this will obviously cause overflow. However, the variable to which the result is assigned allows such large numbers.

Any explanation is greatly welcome!
atothep
 
My textbook on Fortran 90/95 makes it very clear, that the result of the expression is defined by the operation. That is two integer*4 variables will result in a integer*4 value, including overflow, when 32 bit are not sufficient to carry the value.

That you save the result to another variable of a different type (integer*8) does not help.

You should write

k = dble (i) * dlble (j)

Norbert

The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
Thanks for your reply. What you say makes most sense.

But you mean probably something like

k = int(i,8) * int(j,8)

:)
 
Some addition:
F2003 Standard said:
For an expression x1 op x2 where op is a numeric intrinsic binary operator with both operands of the same type and kind type parameters, or with one real and one complex with the same kind type parameters, the kind type parameter of the expression is identical to that of each operand. In the case where both operands are integer with different kind type parameters, the kind type parameter of the expression is that of the operand with the greater decimal exponent range if the decimal exponent ranges are different; if the decimal exponent
ranges are the same, the kind type parameter of the expression is processor dependent, but it is the same as that of one of the operands.

The type and the kind of the right side expression do not depend on the type and the kind of the target.

There is INT(A,KIND) intrinsic function form in FTN 2003. It's possible to write
Code:
... see OP snippet ...
k = int(i,8) * j
That's ok, no integer overflow.
 
Yes and no....

I am using fortran 90 / 95 and there you cannot change the kind like you can do apparently in int (i,8). (Maybe I will buy a newer compiler one of these days, but only after my prog really finds a market) And, in fact, I was not aware that you can change the type that way. Must be fortran 2003.

That is why I recommended to do the calculation in real*8 by using the dble function and then saving it to k as integer*8.

Norbert


The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
Ah okay, I wasn't aware that int(i,8) is a Fortran 2003 feature. My compilers do not seem to have problems with that. But it's good to know that I might run into trouble with older compilers.

Thanks again for all your answers.
 
As far as I know, this trick is portable and works since F95 (or even F90?) epoch w/o later int(a,kind):
Code:
integer,parameter::int8=selected_int_kind(18)
...
k = (0_int8 + i) * j
 
Yes, this does work. I checked on my old Compac Fortran 90 / 95 compiler and it worked fine - but, ArkM, I do not understand this code.

I tried

Code:
integer*8 :: int8 = 0
integer*8 :: k
integer*4 :: i, j

i = 1000000000
j = 2000000000

k = (int8 + i) * j

and this worked as well in evaluating k without overflow.

Norbert




The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
I wonder that it's an old (F90) form to force constant kind but few people know about it (including me till now;)

It's very clear (argument is a power of ten for desired range), effective (100% compile-time, w/o memory) and portable method.
 
ArkM:
Could you give me some hint as to what

0_int8

is / does in your code ?

My compiler digested it and the prog did work - but I could not find any reference about this.

Norbert


The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
I have read F90 Standard (alas, I have draft text only;)

That's integer signed literal constant syntax in F90+:
Code:
signed-int-literal-constant is [sign] digit-string [_kind-param]
kind-param is digit-string
           or scalar_int-constant-name

There are lots of URLs about FTN KIND stuff. See, for example:
More kind constructs was included in F2003+...

(PLs and code portability was my hobbies in the old days that's why I recalled FTN _KIND in this thread ;)
 
Thanks ArkM.

This brought me to pages of my 8 year old well used textbook that were still as good as new..... ;-)

Norbert


The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top