问题
I am using Intel Fortran in Visual Studio 2012 to compile a Fortran code. When I try to use logical operators I have noticed that a standalone logical expression results in T or F as expected. However, if I need the numerical T or F (0 or 1), I get a -1 when logical result is T.
For example:
integer*4 a
a = 1
logicval = (node(5,L).gt.0)
numval = 1*(node(5,L).gt.0)
write(*,*) logicval, numval
would output
T, -1
Is there a way in which I can redefine numerical values assigned to T & F?
回答1:
Yes, that is expected Intel Fortran's TRUE is indeed -1, because all bits are set to 1.
In addition, your use of integers as logical (Boolean) variables is completely non-standard. You should make your code a few lines longer and always do proper conversion. Your integer_var = 1*(node(5,L).gt.0)
is not allowed in Fortran and it will be refused by many compilers. If you drop the 1*
gfortran will issue a warning, but your form results in an error.
You can simply convert your logicals and integers in a standard conforming way
if (l) then
x = 1
else
x = 0
end if
You can convert a Fortran logical arrays to integer arrays with 1 and 0 easily using the MERGE()
intrisic or using WHERE
.
An easy fix for Intel Fortran is probably -fpscomp logicals
for Intel Fortran which switches the treatment of LOGICAL
type to consider anything nonzero as true and makes the .true.
constant to be equivalent to integer 1.
Still be careful because it does not make your program portable, it just works around one portability issue in one particular compiler.
You can use the C interoperable logical kind to match the definition to the Intel C representation:
use iso_c_binding
logical(c_bool) :: variable
These will have values of +1 and 0 as C99 dictates for _Bool. If you need them to be interoperable with int
you must do some simple conversion. C_int
is not compatible with c_bool
.
Depending on the version of Intel Compiler you may need to use -standard-semantics
(or -fpscomp logicals
) for correct logical(c_bool)
. I consider this to be very unfortunate.
回答2:
As others have stated, the Intel Fortran default for this non-standard usage is that integer values with the low bit set (odd) are true, even values (low bit clear) are false. The constant .TRUE. has the bit pattern of -1. It gets more complicated when you do conversions and up until version 17 the compiler hasn't been completely consistent in this. Note that if you use -standard-semantics, -fpscomp logicals is implied.
Please read https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/275071#comment-1548435 and also the version 17 release notes (https://software.intel.com/en-us/articles/intel-fortran-compiler-170-release-notes) for information on the changes in that version for how numeric-logical conversions are handled.
来源:https://stackoverflow.com/questions/39454349/numerical-equivalent-of-true-is-1