Fortran 77 Real on Int Rounding Directions?

Porting Fortran 77 code bits. It seems that REAL variables are assigned to INTEGER variables. I have no way to run this code and wonder what the behavior is in the following case:

REAL*4 A A = 123.25 B = INT(A) 

B = 123 or B = 124?

How about a mark of 0.5?

 REAL*4 C C = 123.5 D = INT(C) 

D = 123 or D = 123.5?

+9
source share
3 answers

INT always rounded:

From the GCC documentation :

These functions return a variable or an INTEGER array according to the following rules:

(A) If A is of type INTEGER, INT (A) = A

(B) If A is of type REAL and | | <1, INT (A) is 0. If | A | \ geq 1, then INT (A) is the largest integer that does not exceed the range A and whose sign is the same as the sign of A.

(C) If A is of type COMPLEX, then rule B is applied to the real part of A.

If you want to round to the nearest integer, use NINT .

So, in your case, B and D always 123 (if they are declared as integer ).

+12
source

Here is one example of code and output, an extension of the previous answer:

 PROGRAM test implicit none integer :: i=0 real :: dummy = 0. do i = 0,30 dummy = -1.0 + (i*0.1) write(*,*) i, dummy , int(dummy) , nint(dummy) ,floor(dummy) enddo stop end PROGRAM test 

This is the conclusion:

  $ ./test 0 -1.000000 -1 -1 -1 1 -0.9000000 0 -1 -1 2 -0.8000000 0 -1 -1 3 -0.7000000 0 -1 -1 4 -0.6000000 0 -1 -1 5 -0.5000000 0 -1 -1 6 -0.4000000 0 0 -1 7 -0.3000000 0 0 -1 8 -0.2000000 0 0 -1 9 -9.9999964E-02 0 0 -1 10 0.0000000E+00 0 0 0 11 0.1000000 0 0 0 12 0.2000000 0 0 0 13 0.3000001 0 0 0 14 0.4000000 0 0 0 15 0.5000000 0 1 0 16 0.6000000 0 1 0 17 0.7000000 0 1 0 18 0.8000001 0 1 0 19 0.9000000 0 1 0 20 1.000000 1 1 1 21 1.100000 1 1 1 22 1.200000 1 1 1 23 1.300000 1 1 1 24 1.400000 1 1 1 25 1.500000 1 2 1 26 1.600000 1 2 1 27 1.700000 1 2 1 28 1.800000 1 2 1 29 1.900000 1 2 1 30 2.000000 2 2 2 

I hope this can better clarify the issue.

EDIT: compiled with ifort 2013 on xeon

+6
source

Just as a complement to existing answers, I want to add an example of how commercial rounds can be implemented without using NINT

  L = INT(F + 0.5) 

where L is INTEGER and F is a positive REAL number. I found this in the FORTRAN 77 code samples from the last century.

Extending this to negative REAL numbers

  L = SIGN(1.0,F)*INT(ABS(F) + 0.5) 

and returning to the 80s of the last century, an example of a minimal code is as follows

  PROGRAM ROUNDTEST DO 12345 I=0,30 F = -1.0 + I * 0.1 J = INT(F) K = NINT(F) L = SIGN(1.0,F)*INT(ABS(F) + 0.5) PRINT *, I, F, J, K, L 12345 CONTINUE END 

which creates a conclusion

 $ ./ROUNDTEST 0 -1.00000000 -1 -1 -1 1 -0.899999976 0 -1 -1 2 -0.800000012 0 -1 -1 3 -0.699999988 0 -1 -1 4 -0.600000024 0 -1 -1 5 -0.500000000 0 -1 -1 6 -0.399999976 0 0 0 7 -0.300000012 0 0 0 8 -0.199999988 0 0 0 9 -9.99999642E-02 0 0 0 10 0.00000000 0 0 0 11 0.100000024 0 0 0 12 0.200000048 0 0 0 13 0.300000072 0 0 0 14 0.399999976 0 0 0 15 0.500000000 0 1 1 16 0.600000024 0 1 1 17 0.700000048 0 1 1 18 0.800000072 0 1 1 19 0.899999976 0 1 1 20 1.00000000 1 1 1 21 1.10000014 1 1 1 22 1.20000005 1 1 1 23 1.29999995 1 1 1 24 1.40000010 1 1 1 25 1.50000000 1 2 2 26 1.60000014 1 2 2 27 1.70000005 1 2 2 28 1.79999995 1 2 2 29 1.90000010 1 2 2 30 2.00000000 2 2 2 

ROUNDTEST compiled and linked by gfortran version 7.4.0

 $ gfortran.exe ROUNDTEST.FOR -o ROUNDTEST 

Hope this helps you if you have to deal with the old FORTRAN code.

0
source

Source: https://habr.com/ru/post/959425/


All Articles