- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- « Previous
- Next »
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We make this module:
module number_types
use iso_fortran_env
integer, parameter :: r_typ = REAL64
end module
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
_8 do the same as d0 it promotes the constant to double.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
- Next »