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

Negative exponential should be compiler error - instead gives wrong answer

caplanr
New Contributor II
26,115 Views

Hi,

A colleague of mine noticed a bad behavior of IFX (and IFORT) for Fortran regarding negative exponents without parenthesis.  

From our understanding, the Fortran standard does not allow this:

program negative_exponent
  write(*,*) '10.0**-2 * 2=', 10.0**-2 * 2
end program negative_exponent

However, the above code compiles and runs using gfortran, nvfortran, ifort, and ifx.

On gfortran, it gives a warning about the syntax but then "does the right thing":

```
> gfortran negative_exponent.f90
negative_exponent.f90:2:37:

    2 |   write(*,*) '10.0**-2 * 2=', 10.0**-2 * 2
      |                                     1
Warning: Extension: Unary operator following arithmetic operator (use parentheses) at (1)
> a.out
 10.0**-2 * 2=   1.99999996E-02
```

Using NVIDIA's nvfortran, there is no warning but the code gives the right answer:

```
> nvfortran negative_exponent.f90
> a.out 
 10.0**-2 * 2=   2.0000000E-02
```

However, on ifort or ifx, there is no warning and gives the wrong answer:

```
> ifx negative_exponent.f90
> a.out
 10.0**-2 * 2=  9.9999997E-05
```

It seems to me that this code should ideally throw a compiler error since it is not allowed in Fortran (maybe have a flag to ignore the error?).

However, if it IS going to be allowed, it should give the right answer following standard math PEMDAS in compilation.

 

 - Ron

1 Solution
Ron_Green
Moderator
2,284 Views

@caplanr Ron, I have been discussing this with the team internally.  A few key people have been on vacation so it has lingered a bit.  After a lot of deliberation we decided that we will emit a Warning, much like Gfortran. 

The debate on the risk of changing this constant folding is ongoing.  We do have a large user community, and the question is: how prevalent is this non-conforming expression?  For sure we will emit a Warning.  But as you know, Warnings are sometimes redirected to /dev/null (or equivalent).  My leaning is to "fix" the expression evaluation to (10**(-2) )* 2 and make this default.  For legacy codes that require the old expression eval we could add a new compiler option to allow the older folding.  Something like this is a behavior change.  For our legacy users we tend to lump behavior changes into MAJOR release version and document it in the Release Notes.  In this case perhaps 2026.0 release.  That is my inclination. 

-- iRon 

View solution in original post

0 Kudos
75 Replies
caplanr
New Contributor II
1,377 Views

We make this module:

 
module number_types
  use iso_fortran_env
  integer, parameter :: r_typ = REAL64
end module
 
Then always use things like  pi=3.1415926535897932384626433832795_r_typ in the code to ensure precision.
 
I am pretty sure this is compiler independent (absent special flags) since it uses the iso_fortran_env.

 

 
 - Ron
0 Kudos
andrew_4619
Honored Contributor III
1,105 Views

If you do not put the kind on a real constant the Fortran rules are clear. The constant will be evaluated at the default precision (32bit in this case)  which in the examples above would truncate decimal places and then it would  promote it to a 64 bit real in effect adding a load of trailing zeros. A mistake that many make!

0 Kudos
GVautier
New Contributor III
1,270 Views

_8 do the same as d0 it promotes the constant to double.

0 Kudos
Steve_Lionel
Honored Contributor III
861 Views

@GVautier wrote:

_8 do the same as d0 it promotes the constant to double.


Please do not hardcode specific kind values! See Doctor Fortran in "It Takes All KINDs" - Doctor Fortran

0 Kudos
Kevinf123
Beginner
541 Views

Hello

 I am not getting this point:

 

program negative_exponent write(*,*) '10.0**-2 * 2=', 10.0**-2 * 2 end program negative_exponent.

 

Can someone please guide me about this regard?

Thanks

0 Kudos
JohnNichols
Valued Contributor III
536 Views

Kevin:

Main point, the use of () is highly recommended, so a maintainer in 30 years can understand your intention. 

Fortran unlike LISP allows us the freedom to use the equation format rules but these can be hard for a compiler to pick up all of the variations, hence someone like me prefers Lisp for readability and FORTRAN for brute speed. 

Do not do this at all.  

Use

variables

a = -2

b = 10

c = 2

(b**a)*c == no chance the compiler will misunderstand you and neither will I + you can create a function and reuse the equation, which with recursion is the beauty of LISP.  MIT taught programming with LISP for many years and the Sussman textbook covers a lot of good crap. 

If you have a Finite Element Program like ULARC it is easy to propagate an equation error and unless you are careful to check that the results match hand answers you can be in for a world of hurt. 

I have this problem with FEM in just comparing the answers - for instance one of the large German FEM programs has an error in one of the major equations.  

 

 

0 Kudos
Arjen_Markus
Honored Contributor II
508 Views

The point is that Fortran does not allow two (or more) operators next to each other. In this case: ** and -. Some languages consider the minus sign to be part of the number, but that is not the case in Fortran. The Intel compiler has a long history and at some point in that history this misuse was allowed with some particular interpretation. But as evidenced in this thread, the interpretation may not coincide with the human interpretation. 

Conclusion: use parentheses or any of the other suggested solutions.

Steve_Lionel
Honored Contributor III
375 Views

This answer reads like AI and the action of a bot, and is wrong, at least in suggesting that ifx has a bug, as has been explained earlier in this thread. The user has only three posts, all in the last few days, and a user bio that seems way off topic for a technical forum.

0 Kudos
AlHill
Super User
304 Views

@Steve_Lionel   I agree and he is gone - until management decides otherwise.

 

Doc (not an Intel employee or contractor)
[AI is the same as snake-oil]

0 Kudos
jeroldjast
Beginner
227 Views

Hi Ron,

You’re right—some compilers misinterpret 10.0**-2 without parentheses, which can give wrong results. Using 10.0**(-2) ensures consistent behavior across all Fortran compilers.

0 Kudos
Ron_Green
Moderator
2,285 Views

@caplanr Ron, I have been discussing this with the team internally.  A few key people have been on vacation so it has lingered a bit.  After a lot of deliberation we decided that we will emit a Warning, much like Gfortran. 

The debate on the risk of changing this constant folding is ongoing.  We do have a large user community, and the question is: how prevalent is this non-conforming expression?  For sure we will emit a Warning.  But as you know, Warnings are sometimes redirected to /dev/null (or equivalent).  My leaning is to "fix" the expression evaluation to (10**(-2) )* 2 and make this default.  For legacy codes that require the old expression eval we could add a new compiler option to allow the older folding.  Something like this is a behavior change.  For our legacy users we tend to lump behavior changes into MAJOR release version and document it in the Release Notes.  In this case perhaps 2026.0 release.  That is my inclination. 

-- iRon 

0 Kudos
caplanr
New Contributor II
125 Views

Hi,

 

Looking forward to the fix in 2026.0!

 

 - Ron

0 Kudos
JohnNichols
Valued Contributor III
85 Views

In this case perhaps 2026.0 release. 

You may have missed the perhaps. 

per·haps
/pərˈ(h)aps/
 

 

adverb
 
  1. used to express uncertainty or possibility.
    "perhaps I should have been frank with him"
     
    Similar:
    maybe
     
    for all I know
    for all you know
    it could be (that)
    it may be (that)
     
    it is possible (that)
    possibly
     
    conceivably
     
    feasibly
     
    happen
     
    peradventure
     
    perchance
     
    mayhap
     
    haply
     
    percase
     
    • used when one does not wish to be too definite or assertive in the expression of an opinion.
      "perhaps not surprisingly, he was cautious about committing himself"
    • used when making a polite request, offer, or suggestion.
      "would you perhaps consent to act as our guide?"
0 Kudos
Reply