Search code examples
type-conversionfortranlogical-operatorsintel-fortran

Numerical equivalent of TRUE is -1?


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?


Solution

  • 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. As Steve Lionel mentioned, this option is included in the -standard-semantics flag.

    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.