Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why does Fortran have a separate comparison operator .eqv. for logical variables?

781 views
Skip to first unread message

Beliavsky

unread,
May 14, 2021, 11:11:56 PM5/14/21
to
Why does Fortran require .eqv. to test two logical variables for equality instead of .eq. or == as for other basic types?

jfh

unread,
May 15, 2021, 12:50:29 AM5/15/21
to
On Saturday, May 15, 2021 at 3:11:56 PM UTC+12, Beliavsky wrote:
> Why does Fortran require .eqv. to test two logical variables for equality instead of .eq. or == as for other basic types?

Because .eqv. and .eq. have different precedences, another relevant question is why they were chosen to be what they are.
You can overload == for logical variables of course, but your version of == will have a precedence different from either .eqv. or the non-logical == .
This example avoiding the use of .eqv. compiled and ran with gfortran.

module llequal
interface operator(==)
module procedure lleq
end interface operator(==)
contains
elemental logical function lleq(p,q)
logical,intent(in)::p,q
lleq = merge(0,1,p)==merge(0,1,q)
end function lleq
end module llequal

program eqtest
use llequal
logical:: p,(2),q(2),r(2)
p = [.true.,.false.]
q = [.true.,.false.]
r = [.false.,.true.]
print *,p==q, q==r
end program

gah4

unread,
May 15, 2021, 11:14:55 AM5/15/21
to
On Friday, May 14, 2021 at 9:50:29 PM UTC-7, jfh wrote:
> On Saturday, May 15, 2021 at 3:11:56 PM UTC+12, Beliavsky wrote:
> > Why does Fortran require .eqv. to test two logical variables for equality
> > instead of .eq. or == as for other basic types?

> Because .eqv. and .eq. have different precedences, another relevant question
> is why they were chosen to be what they are.
> You can overload == for logical variables of course, but your version
> of == will have a precedence different from either .eqv. or the non-logical == .

There is a story about how the bitwise C operators, & and |, got their low
precedence, as the && and || logical operators were added late.

The .NEQV. and .EQV. were added much later, as they are less needed.

These are the operators that other languages call exclusive-or and
(usually) exclusive-nor. (The latter more rarely seen.)

They are rarely enough used that even C doesn't have them.

OK, C doesn't have logical variables, but uses integer values that
are 0 (false) or non-zero (true). There are, then, the && and || operators
that work based on those values. But the relational operators always
give 0 or 1, so you can use the bitwise exclusive or operator if needed.
Otherwise, you can use ! (the .NOT. operator) to convert to a 0 or 1:

if((!a)^(!b)) ...
or
if((!a)==(!b)) ...

Java, which has boolean variables, uses == and != for them.

Just to be sure, do note that you don't use them for testing the value
of a logical variable. You don't say:

if(V.EQV..TRUE.) ...

or

if(V.NEQV..FALSE.) ...

but instead just:

if(V) ...

Note one funny thing in Java.

C uses the == operator as a relational operator, but allows use of the
assignment operator (=) in expressions. A not so rare bug in C comes
from writing

if(x=y) ...

when you meant:

if(x==y) ...

where the former assigns y to x, and then tests its value.

In Java, if() requires a boolean expression, so you can't get away
with if(x=y), except in the case that x and y are boolean variables.

I suspect, though, that it is rare enough that it doesn't cause problems.

Do you have an actual use for .EQV. or .NEQV. in Fortran?





Steve Lionel

unread,
May 15, 2021, 12:00:51 PM5/15/21
to
On 5/14/2021 11:11 PM, Beliavsky wrote:
> Why does Fortran require .eqv. to test two logical variables for equality instead of .eq. or == as for other basic types?
>
I wrote about this back in 2000:
https://stevelionel.com/drfortran/2000/04/29/doctor-fortran-in-to-eqv-or-to-neqv-that-is-the-question-or-its-only-logical/

--
Steve Lionel
ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
Retired Intel Fortran developer/support
Email: firstname at firstnamelastname dot com
Twitter: @DoctorFortran
LinkedIn: https://www.linkedin.com/in/stevelionel
Blog: https://stevelionel.com/drfortran
WG5: https://wg5-fortran.org

gah4

unread,
May 15, 2021, 3:07:22 PM5/15/21
to
On Saturday, May 15, 2021 at 9:00:51 AM UTC-7, Steve Lionel wrote:
> On 5/14/2021 11:11 PM, Beliavsky wrote:
> > Why does Fortran require .eqv. to test two logical variables for equality instead of .eq. or == as for other basic types?

> I wrote about this back in 2000:
> https://stevelionel.com/drfortran/2000/04/29/doctor-fortran-in-to-eqv-or-to-neqv-that-is-the-question-or-its-only-logical/

Just to note, your example:

DO WHILE ((K .LE. 2) .AND. (FOUND .EQV. .FALSE.))

might have been written as:

DO WHILE ((K .LE. 2) .AND. .NOT. FOUND)

Which avoids the complication of .EQV. precedence,
and is probably more readable.

As for doing the actual exclusive or operation between logical expressions,
I can almost remember the times doing it, as they are so rare, and so
unusually interesting.

The most recent one was about 5 years ago in assembler on
an IBM 360/20. How do you test if a number, after dividing by
two, is even or odd? Normally it should be easy to just check
the two's bit, however in this case the value was in BCD.

Not thinking about enough, my first try did check the two's
bit, but in the case of BCD, it is the exclusive-or of the
two's bit and the 10's bit. There is an interesting instruction
for S/360, TM (test under mask) where you can test some bits
in a byte and ask if they are all zeros, all ones, or mixed.

I might remember another time needing this in about
the last 30 years.

Otherwise for C programmers, the ! (not) operator converts
a value that is zero/not zero into 1/0, and !! (not not)
converts zero/not zero into 0/1. This allows easily avoiding
the problem of unknown bit patterns being compared,
such as using the C bitwise operators. That helps C and
Java survive without a logical exclusive or operator.






jfh

unread,
May 16, 2021, 12:05:15 AM5/16/21
to
On Sunday, May 16, 2021 at 3:14:55 AM UTC+12, gah4 wrote:
> On Friday, May 14, 2021 at 9:50:29 PM UTC-7, jfh wrote:
> > On Saturday, May 15, 2021 at 3:11:56 PM UTC+12, Beliavsky wrote:
> > > Why does Fortran require .eqv. to test two logical variables for equality
> > > instead of .eq. or == as for other basic types?
>
> > Because .eqv. and .eq. have different precedences, another relevant question
> > is why they were chosen to be what they are.
> > You can overload == for logical variables of course, but your version
> > of == will have a precedence different from either .eqv. or the non-logical == .
> There is a story about how the bitwise C operators, & and |, got their low
> precedence, as the && and || logical operators were added late.

A dyadic defined operator in Fortran has the lowest possible precedence, but does overloading an intrinsic dyadic operator, e.g. to allow logical==logical, give it the same precedence as the intrinsic == operator, or does it count as a defined operator? The F2018 standard may say so but I did not find where.

Steve Lionel

unread,
May 16, 2021, 10:02:02 AM5/16/21
to
On 5/15/2021 3:07 PM, gah4 wrote:
> Just to note, your example:
>
> DO WHILE ((K .LE. 2) .AND. (FOUND .EQV. .FALSE.))
>
> might have been written as:
>
> DO WHILE ((K .LE. 2) .AND. .NOT. FOUND)
>
> Which avoids the complication of .EQV. precedence,
> and is probably more readable.

Of course, but I was quoting from a customer's code and used it to
illustrate an operator precedence issue. (I wrote much more recently
about operator precedence in
https://stevelionel.com/drfortran/2021/04/03/doctor-fortran-in-order-order/
)
0 new messages