- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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 copiado
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
Very inconsistent behavior across compilers. NAGFOR does throw an error and aborts compilation. Which seems to be the right behavior. But for sure, Intel's results are incorrect. I will write up a bug report.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
As the NAG compiler indicates, it's not standard to have two consecutive operators. I discuss this very point in Doctor Fortran in "Order! Order!" - Doctor Fortran
Intel Fortran allows this as an extension, and will complain if you ask for standards checking:
D:\Projects>ifx -stand t.f90
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2025.2.0 Build 20250605
Copyright (C) 1985-2025 Intel Corporation. All rights reserved.
t.f90(2): warning #8810: Consecutive operators are an extension to the Fortran 2018 standard.
write(*,*) '10.0**-2 * 2=', 10.0**-2 * 2
------------------------------------^
The Intel documentation covers this case explicitly:
---
Ordinarily, the exponentiation operator would be evaluated first in the following example. However, because Intel Fortran allows the combination of the exponentiation and minus operators, the exponentiation operator is not evaluated until the minus operator is evaluated:
A**-B*C is evaluated as A**(-(B*C))
Note that the multiplication operator is evaluated first, since it takes precedence over the minus operator.
When consecutive operators are used with constants, the unary plus or minus before the constant is treated the same as any other operator. This can produce unexpected results. In the following example, the multiplication operator is evaluated first, since it takes precedence over the minus operator:
X/-15.0*Y is evaluated as X/-(15.0*Y)
---
So, 10.0**-2*2 is evaluated as 10.0** (-(2*2)) or 10.0**-4, which is what gets displayed (within the limits of single precision real.)
Not a bug, but an extension. Other compilers are free to interpret this as they like.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
May I state my mild objection to "operator is evaluated" in the quoted Intel documentation extracts?
An operator has no value, and certainly not without the requisite number of operands being provided in proper juxtaposition.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
You can get a Warning by using the option -stand or -stand f18
Still, it is a bug in the computation. CMPLRLLVM-69904
It's a bug in a compiler transform called "constant folding".
This slightly modified example demonstrates the bug more fully:
$ cat bad_constant_folding.f90
program negative_exponent
write(*,*) '10.0**-2 * 3 should be 3.0E-2'
write(*,*) '10.0**-2 * 3 result ', 10.0**-2 * 3
end program negative_exponent
$
$ ifx -O0 -stand bad_constant_folding.f90 ; ./a.out
bad_constant_folding.f90(3): warning #8810: Consecutive operators are an extension to the Fortran 2018 standard.
write(*,*) '10.0**-2 * 3 result ', 10.0**-2 * 3
-------------------------------------------^
GNU ld (GNU Binutils for Ubuntu) 2.43.1
10.0**-2 * 3 should be 3.0E-2
10.0**-2 * 3 result 1.0000000E-06
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
I still don’t think this is a bug. Rather, it’s implementation-dependent behavior of non-standard code. I explained why above - did I get it wrong? That other compilers choose to interpret the non-standard code in a different way doesn’t make it a bug. If anything, the differing interpretations should discourage the reliance on the behavior and encourage the proper use of parentheses.
If this “bug” is “fixed”, I guarantee that you’ll see complaints from other users that their code broke, and you’ll also have to change the documentation. I’d also comment that the documented behavior is far older than any of the other compilers cited here.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
What you said Steve is consistent with what the Intel documents says..... Thus it seems to me that this (like it or not) is the intended behaviour, thus the answer is to do nothing. The only other option at this stage would be to flag an error for invalid Fortran and break the codes of anyone that used the extension. From my selfish point of view that would be the better option as to be frank the historic choice doesn't seem very wise IMO .....
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
The fact that the other major compilers interpret it "correctly" or do not allow it makes Intel an outlier.
It is difficult to think there is production code out there that relies on the "incorrect" math operator precedence in ifort/ifx to the extent the developers never have run the code on gfortran or any other compiler.
Such a thing CAN happen (and I have seen this with some HPC codes that only are ever run on a specific system) but having code like that in a code base sounds like a really bad idea.
I agree that if the Intel compiler does not want to regress the chosen interpretation, it would be better to just not compile it by default and throw an error.
Adding a compatibility compiler flag to allow the compilation using the "Intel interpretation" could allow rare cases to continue to compile their non-conforming code that relies on non-standard math operation orders.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
We had a discussion with the whole team. The consensus follows Steve and Andrew's recommendation - non-conforming code behavior is up to the implementation. The -stand flag should be used to catch illegal code. In addition, this is a bit of a corner case. If this was a common usage we would have had more that 1 other report of this in 35+ years (there was just 1 other issue on this according to my bug database search). that one was closed as 'will not fix'.
Similarly, based on feedback from my development team, I closed this issue as 'will not fix'. This is a corner case. And -stand should be used during development or initial porting to catch potential code issues. The extension is to allow expressions like this:
10**-2
10**+2
which are allowed and do give "correct" results. It's when you then add additional operators and values where results that "correct results" no longer apply. We do not want to penalize codes using the extension for simple cases to accommodate the corner cases such as yours: 10**+2 * 2. Simply not seen frequent enough to warrant change in behavior.
Issue is closed as 'will not fix'. Recommendation is to use -stand option and validate that codes conform to the Standard and do not rely on vendor extensions.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
There are two answers, depending on how you "nominally" allow for the missing brackets. As this is a pure math error, then both answers are correct in terms of getting an answer, otherwise signal an error. IFX gives answer 2 assuming (-2*2) - one must assume that there are many hundreds of millions of errors like this in all the old Fortran code that people just miss.
I see a similar thing in the beam theory equations, Harrison (72) provides the complete equations for 2D - they are never taught, three Canadian engineers who only published one paper did the 3D ones, these are not implemented in any commercial code. But they become important as you seek to match frequency response data.
So errors abound.
The problem is the reality that the coder did not follow high school math procedures or they should use LISP where this cannot occur easily.
It is the same as saying, do not sit in the chairs in a thunder storm, someone will.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
Just today, I fixed a code that was happily committed into one of the models that is part our 1-million line Space Weather Modeling Framwork: https://github.com/dpawlows/MGITM/commit/494a2aa84a6313baeb4ac1eedf8da8dbc8a255e4)
The code looks like this (there were 2 similar lines, I show one of them):
rtCOP_e = 4.82e-6*te**-0.55*1.0e-6
that is now replaced with
rtCOP_e = 4.82e-6*te**(-0.55)*1.0e-6
The developer, who uses gfortran and ifort, did not see any error messages, and did not know that the two compilers will give different results. I noticed the error because we do nightly tests with several compilers, including nagfor, which immediately refused to compile this. I fixed a similar error a couple of months ago, committed by another person into another model. That's when I learned that ifort does this amazing evaluation.
Did I file a bug report to Intel (or gfortran)? No, because nagfor did find the error, and I fixed it. Do I think that the Intel compiler evaluating this as
rtCOP_e = 4.82e-6*te**(-0.55*1.0e-6)
is correct? No!!! Whoever implemented this Intel extension had no idea about mathematics, and should have been prohibited from working on a compiler that supposed to produce mathematically correct results.
So your choice of just letting this go on, is
1. Will hurt people who assume that this "extension" works in a mathematically correct way.
2. Will hurt the reputation of your compiler.
The argument about backward compatibility or the use of -stand flag is lame at best. Here is the result with the -stand flag:
ifort -stand negative_exponent.f90
negative_exponent.f90(2): warning #8810: Consecutive operators are an extension to the Fortran 2008 standard.
<pfe26:~/Bug>a.out
10.0**-2 * 2= 9.9999997E-05
So the warning is about the **-2 and there is nothing said about the following multiplication. The user will assume that the extension works as a normal mathematically educated person would evaluate it. The code still compiled. And it produced a completely incorrect value. So how did the -stand help?
There are potentially useful extensions, like the isnan() function understood by both gfortran and ifort. Now it is obsolete, because there is the is_nan_ieee() function, but before that this extension was very useful. I compiled the 1-line code "write(*,*) 'Is 1.0 a Nan?', isnan(1.0)" and it does this:
<pfe26:~/Bug>ifort -stand isnan.f90
isnan.f90(2): warning #7416: Fortran 2008 does not allow this intrinsic procedure. [ISNAN]
<pfe26:~/Bug>a.out
Is 1.0 a Nan? F
So I got a warning, but the code gives the expected result. Would it be OK, if isnan(-1.0) would return true? Just because it is an extension and the original compiler developer did not believe in negative numbers?
I hope you get the point and will actually fix the compiler. And if you feel like preserving the incorrect behavior has some value, please add a flag like -MathematicallyIncorrectResults so the user understands the implications.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
I’d just like to add a caution on the “corner case” argument. The fact that only one or two bug reports exist over decades doesn’t necessarily mean the issue is rare in practice. It could simply reflect a reporting bias - plenty of legacy Fortran codes may be producing incorrect results without their developers realising it, since outputs often go unchecked unless they trigger an obvious failure.
This matters because Fortran is not just an academic language; it remains at the core of mission-critical simulations in aerospace, nuclear energy, and weather/space forecasting. NASA missions, the aviation industry, and even nuclear reactor simulations continue to rely heavily on Fortran. In those contexts, seemingly “rare” conditions can have catastrophic consequences (remember the Ariane 5 failure?).
That’s why dismissing this as “not worth fixing” carries real risk. Even if the problem is indeed uncommon, the cost of being wrong is disproportionately high compared to the effort required to address it.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
rtCOP_e = 4.82e-6*te**-0.55*1.0e-6
I would avoid this form of equation as it is easy to get the numbers wrong. mecej4, who has not posted since December, which is a huge loss, taught me to use a base module and put all the standard numbers in the base module and this helps to minimize errors.
!---------------------------------------------------------------------------------------------------------------------------
!
! Four modules are called from the main program.
! Base holds the underlying FORTRAN elements such as dp etc.
! Subroutines
! OpenFiles (i,j,k,l,m)
! LineBlank(sw)
! Line(sw)
! Timingline(sw)
!
!---------------------------------------------------------------------------------------------------------------------------
Module Base
INTEGER, PARAMETER :: dp = selected_real_kind(15, 307)
INTEGER, PARAMETER :: sw = 2 ! Output file
INTEGER, PARAMETER :: srA = 15 ! output.txt file
INTEGER, PARAMETER :: st = 14
INTEGER, PARAMETER :: sCAD = 12
INTEGER, PARAMETER :: sa = 3 ! Output file
INTEGER, PARAMETER :: smWrite = 4
INTEGER, PARAMETER :: si = 1
Integer, parameter :: slog = 9 ! Log file
Integer, parameter :: nta = 200 ! Log file
Integer, parameter :: outNode = 63 ! Log file
Integer, parameter :: inNode = 0 ! Log file
integer, parameter :: nt1 = 2000
integer, parameter :: mt1 = 2000 ! Number of members
integer, parameter :: mn1 = 2
integer, parameter :: ml1 = 3
REAL (KIND=dp), PARAMETER :: gr = 9.806_DP, pi = 3.14159265_DP ! Standard parameters
REAL (KIND=dp), PARAMETER :: delta = 0.0001_DP ! Error number of checking for zero
REAL (KIND=dp), PARAMETER :: ZERO = 0.0_DP
REAL (KIND=dp), PARAMETER :: ONE = 1.0_DP
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
rtCOP_e = 4.82e-6*te**-0.55*1.0e-6
var1 = 4.82e-6
var2 = -0.55
var3 = 1.0/1000000.0
rtCOP_e = var1*var3*te**var2
Much easier to understand.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
An aside really but in your Base module pi = acos(-1.0_DP) would be better as it gives PI to the DP precision (17sf) and not to the number of significant figures you happened to type in.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
Since I am a beginner, according to this forum, I will refrain from commenting on all the great advice I got about defining constants as Var1, Var2, Var3 and defining pi as a function. Instead I will focus on the actual issue, which has been _correctly_ raised by many people, and has been _completely_ignored_and_misunderstood_ by the Intel compiler team.
The issue is the following: there are N ~10,000 lines of Fortran code with expressions like this:
a**-b * c
a**+b * c
a**-b / c
a**+b / c
Out of N occurrences, there are M << N lines (~100), where the programmer intended this to be evaluated as
a**(-b*c)
a**(+b*c)
a**(-b / c)
a**(+b/c)
There are also L >> N lines of code where the signed exponent occurs without a following multiplication or division. These lines are interpreted in the mathematically correct manner and consistent with gfortran and other compilers.
Now let's look at the following actions:
1. Let's do nothing, because Intel has documented this 20 years ago, and it is the fault of the programmer not to read the great documentation we have produced.
2. Let's issue an error for every occurrence of **- and **+ (and while at it /- and /+)
3. Let's issue an error for every occurrence of **-b * c, **+b *c, **-b * c, **+b/c, **-b/c, /-b*c, /+b*c, /-b/c, /+b/c
Let's look at consequences:
Action 1 will result in N - M lines of code contain an undiscovered bug. Since the -stand option does not reveal _anything_ about the actual problem, even if somehow the word would spread that this flag to be used (it does not), it will _not_ change anything.
Action 2 will result in L lines of code stop compiling. L-N>>N lines are perfectly fine, so if the user gets the option to suppress the error, they will, and we end up again with N-M lines of code with undiscovered bugs.
Action 3 will show a potential error for N lines of code with a _proper_error_message_. The developers will then decide if they truly want the result documented by Intel, or if they prefer to get the result taught in high school. Now the result is that we _discover_ N-M bugs, while having a few people who really read the Intel document, and really wanted to write a code that would only work with Intel and definitely fail with every other compiler to add parentheses. Yes, that's the big deal. They have to add parentheses around the exponent, and as a result it will actually work with other compilers. How bad is that?
So your decision of doing nothing results in maintaining 1000s of bugs, and your justification for it is to avoid annoying about 10 people in the world who used the extension as you defined it at the expense of a non-portable code, and that's what they _really_ want.
So please spend some time on this and ask yourself: are you in the business of creating high quality compilers that behave as people would expect? Or are you making sure that people don't notice that their codes have bugs?
Best regards,
A beginner
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
"Since I am a beginner, according to this forum, ..."
Please ignore the label that the forum software assigns to you. If a forum member loses the forum password, wishes to use a different email, etc., and creates a new Intel Forum account, that person will be considered to be a "beginner". I expect to be treated just so tomorrow, since I have been away for over a year, although I had been posting in this forum since 2010, and Intel named me "black-belt" for many years.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
Even if we all agree that something needs to be fixed, the question "Who's to bell the cat?" remains. Should the fix be the responsibility of the authors of the non-standard-conforming Fortran code, of of the authors of the over-lenient compiler?I am inclined to place the onus on the Fortran code writers. They can modify the code to make it standards-compliant, run test problems with several compilers, and then pay attention to simplifying and bettering the code.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
The typical reaction when I mention to people that 10.0**-2 * 3 =0.000001 (BTW, the autofill gave 0.03

- Subscrever fonte RSS
- Marcar tópico como novo
- Marcar tópico como lido
- Flutuar este Tópico para o utilizador atual
- Marcador
- Subscrever
- Página amigável para impressora