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

Compiler bug ?

WSinc
New Contributor I
2,862 Views

This simple program is supposed to calculate principal and interest as you make payments.

If the payment is <= the remaining principal,  the payment amount is reduced accordingly.

When I run it , it does NOT show that I set the principal (ypr) = to 0.

In other words, line 19 gets skipped in the compiled code, where I set ypr= 0.

Am I missing something here? Why would the compiler ignore that line?

0 Kudos
28 Replies
Steven_L_Intel1
Employee
820 Views

Ah, integer overflow...

First thing to understand is that constants have a type and kind specified by the standard. If you write 257, that is "default integer kind" - in our implementation, INTEGER(4), unless you change it with /integer_size. So 257*257 is still INTEGER(4) and that's fine. So what happens if you do something like 2147483647 + 6? Both of those are INTEGER(4) and the result overflows an INTEGER(4). It is especially important to understand that Fortran doesn't care about the kind of variable you assign such an expression to. So if you have:

integer(8) P
P = 2147483647 + 6
print *, p

it prints -2147483643 and there's no run-time error. We don't do integer overflow checking at this time.

So, no, there is no "assumption" that an expression which overflows should be considered a larger kind. In Fortran 77, where the standard didn't have more than one kind of integer, it was common for compilers that did support different kinds to give you free extension. Same holds for things such as:

DOUBLE PRECISION PI
PI=3.1415926535897

in some F77 compilers, the constant would be evaluated in maximum precision and then assigned to the variable. As of Fortran 90, that was no longer allowed (though we have an option to do it.) Otherwise it's a "default real" constant and you lose the extra digits.

0 Kudos
DavidWhite
Valued Contributor II
820 Views

Steve,

Your explanation of how xint/100/12 is evaluated does not hold up.  I do not believe the standard specifies left to right evaluation, so the compiler is not obliged to evaluate in the order you specify.  It is possible that 100/12 is evaluated first (to 8), and then xint/8 is evaluated.

David

0 Kudos
Steven_L_Intel1
Employee
820 Views

No, Walt was essentially correct. The standard says: "Once the interpretation of a numeric intrinsic operation is established, the processor may evaluate any mathematically equivalent expression, provided that the integrity of parentheses is not violated." Since division is not associative, the transformation I suggested would not be allowed. This has nothing to do with left-to-right.

 

0 Kudos
John_Campbell
New Contributor II
820 Views

Steve,

Your example is very useful to identify a problem that can vary the results between different F90+ compilers.
If the programmer has provided a constant of 14 digits, should the compiler honor this request ?
DOUBLE PRECISION PI
PI=3.1415926535897

The situation gets more confusing (annoying?) if the code is:
DOUBLE PRECISION PI
PI=0.1
 (this is a more common example that has caused problems.)

Also, the constant can be interpreted differently, as in a read statement:
DOUBLE PRECISION PI
  Read ( '3.1415926535897 ',*) PI

as reading data of higher precision will always be read as a constant at the variable's precision.

There are still some compilers that provide backward compatibility and provide maximum precision for constants.
Not providing this precision can be a very annoying result when converting old code, causing lots of program testing to find the run-time difference that results. I'm not sure that the standard got it right in this case.

John

[fortran]

DOUBLE PRECISION PI_1, PI_2, p1, p2

character string*30

 

   string = '3.1415926535897 '

   PI_1 = 3.1415926535897

   Read ( string,*) PI_2

 

   string = '0.1 '

   p1 = 0.1

   Read ( string,*) P2

!

   write (*,*) Pi_1, pi_2, PI_1-Pi_2

   write (*,*) p1, p2, p1-p2

!

end
[/fortran]

 

 

0 Kudos
WSinc
New Contributor I
820 Views

Actually, PI as a real*8 number should be given to at least 16 digits after the decimal point.

I always generated it by saying

 

PI = atan (1.D0)*4.0

 

That way I get the very last bit.

BUt you can also say :

data PI/3.14159265358979323846D0/

I dont know offhand how many places the compiler allows you to give, but too many is just overkill of course.

If you are working with REAL(16) you would give 30 digits after the decimal point,

just to be consistent.

0 Kudos
Steven_L_Intel1
Employee
820 Views

John Campbell wrote:

Steve,

Your example is very useful to identify a problem that can vary the results between different F90+ compilers.
If the programmer has provided a constant of 14 digits, should the compiler honor this request ?
DOUBLE PRECISION PI
PI=3.1415926535897

This isn't a "request" - the compiler doesn't really know what you intended here, though I suppose it could guess that if you specified significantly more digits than are represented in the precision that perhaps you made a mistake. I know some compilers give you warnings about this (we don't). But it would be non-conforming for the compiler to treat the constant as anything but default real.

0 Kudos
TimP
Honored Contributor III
820 Views

It seems that the Fortran committee must have batted this back and forth, as several compilers existed on either side of the fence when the standard was confirmed.  The compiler I learned on switched floating point constants to implied double when 9 or more digits were .  It didn't increase precision of 8-digit constants even when they were assigned to double.   This and other non-standard stuff like treating x*i/j as x*(i/j) caused more confusion than advantage. 

Fortunately few such legacy problems remain, but I could mention a few in ifort (treating integer as logical, not obvious which standard-semantics options improve and which hurt performance...)

0 Kudos
Steven_L_Intel1
Employee
820 Views

As I said earlier, Fortran 77 compilers were free to give you the extra precision because the standard didn't have the concept of "kinds". The "compiler you learned on" was likely a F77 compiler and this was a common feature - I know VAX Fortran did

0 Kudos
Reply