Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29231 ディスカッション

Negative exponential should be compiler error - instead gives wrong answer

caplanr
新規コントリビューター I
16,029件の閲覧回数

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

66 返答(返信)
caplanr
新規コントリビューター I
625件の閲覧回数

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
andrew_4619
名誉コントリビューター III
353件の閲覧回数

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!

GVautier
新規コントリビューター III
518件の閲覧回数

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

Steve_Lionel
名誉コントリビューター III
109件の閲覧回数

@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

返信