For Programmers: Free Programming Magazines  


Home > Archive > Fortran > May 2005 > mixing logical with real in equation









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author mixing logical with real in equation
jam

2005-04-25, 3:59 pm

Hello,

I am looking at some fortran 90 source code that was apparently written
using Visual Fortran and am seeing something I have never seen before
and am surprised that it's legal (or is it?). The code apparently works
but when I compile using Forte on a Sun box it complains as I would
expect.

Here is a snippet of the code. Can someone explain to me how this can
be done and if it's legal?

NT=VSP(4,I)+.5
COND=-((K-1)*T2*(NT.EQ.1)+VOLT*(NT.EQ.2))

Thanks in advance.

Richard E Maine

2005-04-25, 8:57 pm

In article <1114451356.315383.17260@z14g2000cwz.googlegroups.com>,
"jam" <jamervini@abquv.com> wrote:

> Here is a snippet of the code. Can someone explain to me how this can
> be done and if it's legal?
>
> NT=VSP(4,I)+.5
> COND=-((K-1)*T2*(NT.EQ.1)+VOLT*(NT.EQ.2))


No, this isn't legal. I suspect the code is based on assuming that
logicals can be treated like integers with values 0 and 1. Although the
Vax compiler (and ones descended from it) have a good reputation in many
ways, the one thing I personally strongly dislike about them is their
tendency to accept a lot of nonstandard coding practices without even a
warning by default. One of those practices is the treatment of logicals
as being integers.

You might try turning on the switch for checking standard-conformance in
CVF. I forget the name, but I'm sure it has one - it just isn't on by
default.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
Steve Lionel

2005-04-25, 8:57 pm

On 25 Apr 2005 10:49:16 -0700, "jam" <jamervini@abquv.com> wrote:

>Here is a snippet of the code. Can someone explain to me how this can
>be done and if it's legal?
>
> NT=VSP(4,I)+.5
> COND=-((K-1)*T2*(NT.EQ.1)+VOLT*(NT.EQ.2))


This is an extension supported by the DEC compilers and those derived from
them. There is free implicit conversion between numeric and logical types, and
you're right to be surprised by this and to wonder why it's allowed. There is
a use for converting integers to logicals, especially on OpenVMS where return
statuses are designed to be tested that way, but otherwise this conversion
causes headaches. The compiler should complain if you ask for standards
checking.

Note that many people unwittingly treat integers as logicals by using
operators such as .AND. and .OR. on integers, which is not allowed by the
standard.

This extension is also the provocation for people complaining that
list-directed input on the DEC-heritage compilers accepts strings beginning
with T and F in list-directed input for numeric variables.

See
http://softwareforums.intel.com/ids...id=12984#M12984
for an article I wrote a few years ago on this general subject.


Steve Lionel
Software Products Division
Intel Corporation
Nashua, NH

User communities for Intel Software Development Products
http://softwareforums.intel.com/
Intel Fortran Support
http://developer.intel.com/software/products/support/
beliavsky@aol.com

2005-04-25, 8:57 pm

Richard E Maine wrote:
> In article <1114451356.315383.17260@z14g2000cwz.googlegroups.com>,
> "jam" <jamervini@abquv.com> wrote:
>
can[color=darkred]
>
> No, this isn't legal. I suspect the code is based on assuming that
> logicals can be treated like integers with values 0 and 1. Although

the
> Vax compiler (and ones descended from it) have a good reputation in

many
> ways, the one thing I personally strongly dislike about them is their


> tendency to accept a lot of nonstandard coding practices without even

a
> warning by default. One of those practices is the treatment of

logicals
> as being integers.
>
> You might try turning on the switch for checking standard-conformance

in
> CVF. I forget the name, but I'm sure it has one - it just isn't on by


> default.


The code

i = (1==1)
j = (1==0)
print*,i,j
end

outputs -1 0,

with CVF, so it appears in CVF that .true. and .false. are converted to
-1 and 0 when necessary. The -stand:f95 option warns about these
non-standard type conversions. Lahey/Fujitsu Fortran 95 produces a
warning by default, and it converts .true. and .false. to 1 and 0. As
Richard Maine said, relying on conversions of .true. and .false. to
integers is a bad idea.

Gordon Sande

2005-04-25, 8:57 pm



Steve Lionel wrote:

....
>
> Note that many people unwittingly treat integers as logicals by using
> operators such as .AND. and .OR. on integers, which is not allowed by the
> standard.
>


I would have said that they deliberately use .AND. and .OR. because
they find them more convenient that the masking functions IAND and IOR
even though the usage is not allowed in standard Fortran.

Often the idiom had its origins in character packing and predates
the common availability of the bit manipulation functions. The idiom
is reinforced by folks not noticing the bit manipulation functions
or assuming that they are also nonstandard.

The inline conversion of logical expressions to either 0 or 1 (a Cism!)
is a new one on me. I plead guilty to using X .OR. FF, where FF has been
set in a data statement to be hex xFF, more than a few time even though
I claim to have reformed. ;-)

Dick Hendrickson

2005-04-25, 8:57 pm



jam wrote:
> Hello,
>
> I am looking at some fortran 90 source code that was apparently written
> using Visual Fortran and am seeing something I have never seen before
> and am surprised that it's legal (or is it?). The code apparently works
> but when I compile using Forte on a Sun box it complains as I would
> expect.
>
> Here is a snippet of the code. Can someone explain to me how this can
> be done and if it's legal?
>
> NT=VSP(4,I)+.5
> COND=-((K-1)*T2*(NT.EQ.1)+VOLT*(NT.EQ.2))

Others have explained why it's not legal. If you want
to do this in a standard conforming was, try
cond = -merge((k-1)*t2, 0.0, nt .eq. 1) -
merge(volt,0.0, nt .eq. 2)

The merge function selects an argument based on
the truehness of the 3rd argument. If you are
sure that NT will be 1 or 2, then
cond = - merge ((k-1)*t2, volt, nt .eq. 1)
should also work.

Dick Hendrickson
>
> Thanks in advance.
>


Ken Fairfield

2005-04-25, 8:57 pm

Gordon Sande wrote:
>
>
> Steve Lionel wrote:
>
> ....
>
>
>
> I would have said that they deliberately use .AND. and .OR. because
> they find them more convenient that the masking functions IAND and IOR
> even though the usage is not allowed in standard Fortran.


Indeed, I was quite guilty of that in my youth. :-} .AND. and
..OR. were "obviously" bitwise operators whereas IAND and IOR were
some archaic F66 or Fortran H ugliness. <Ah, youth! How certain,
how inexperienced...>

[...]
> The inline conversion of logical expressions to either 0 or 1 (a Cism!)
> is a new one on me. I plead guilty to using X .OR. FF, where FF has been
> set in a data statement to be hex xFF, more than a few time even though
> I claim to have reformed. ;-)


There was a guess in one of the earlier posts that the values were
0 and 1. On VMS, they are 0 and -1, i.e., 0 and FFFFFFFF, as you would
expect in a masking statement. I think Steve L. confirmed that CVF also
used -1. My recollection of IBM mainframes was that the various
Fortrans used 0 and positive 1, although they were rarely used in
numeric contexts.

-Ken
--
I don't speak for Intel, Intel doesn't speak for me...

Ken Fairfield
D1C Automation VMS System Support
who: kenneth dot h dot fairfield
where: intel dot com
James Van Buskirk

2005-04-25, 8:57 pm

"Dick Hendrickson" <dick.hendrickson@att.net> wrote in message
news:9vcbe.127967$cg1.52598@bgtnsc04-news.ops.worldnet.att.net...

> Others have explained why it's not legal. If you want
> to do this in a standard conforming was, try
> cond = -merge((k-1)*t2, 0.0, nt .eq. 1) -
> merge(volt,0.0, nt .eq. 2)


Others have pointed out that the minus signs are wrong above.

> The merge function selects an argument based on
> the truehness of the 3rd argument. If you are
> sure that NT will be 1 or 2, then
> cond = - merge ((k-1)*t2, volt, nt .eq. 1)
> should also work.


Also here.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Andy Spragg

2005-04-26, 8:59 am

On 25 Apr 2005 12:16:53 -0700, beliavsky@aol.com wrote:

>As Richard Maine said, relying on conversions
>of .true. and .false. to integers is a bad idea.


I'm sure you're right and it's not something I'd ever do. But why is
it any worse than relying on conversions of integers to reals and vice
versa in statements like:

x = n* y

(n, x and y implicitly typed). I never do that either even though I
know I /am/ allowed to ...
Steve Lionel

2005-04-26, 4:00 pm

On Mon, 25 Apr 2005 13:48:53 -0700, Ken Fairfield <my.full.name@intel.com>
wrote:

> There was a guess in one of the earlier posts that the values were
>0 and 1. On VMS, they are 0 and -1, i.e., 0 and FFFFFFFF, as you would
>expect in a masking statement. I think Steve L. confirmed that CVF also
>used -1. My recollection of IBM mainframes was that the various
>Fortrans used 0 and positive 1, although they were rarely used in
>numeric contexts.


Yes, CVF used -1 for .TRUE. and so does Intel Fortran as of version 8. In
both compilers, an option is available to do it the "C way".


Steve Lionel
Software Products Division
Intel Corporation
Nashua, NH

User communities for Intel Software Development Products
http://softwareforums.intel.com/
Intel Fortran Support
http://developer.intel.com/software/products/support/
Richard E Maine

2005-04-26, 4:00 pm

In article <d4l9ea$4k9$01$1@news.t-online.com>,
"Michael Metcalf" <metcalfmetcalf@compuserve.com> wrote:

> "Andy Spragg" <andy.spragg@rhm.com> wrote in message
> news:1114514177. 4d41dd43d4288b6e3547a8bac05f7910@teranew
s...
>
> The former is not defined by the standard, the latter is.


Plus, at least the appropriate value from conversion from integer to
real is intuitively obvious and agreed on by all. It might not be
obvious that the conversion is happening, but given that it is
happening, the appropriate value is "obvious" (unless the values are
large enough that precision loss occurs, in which case, the approximate
value is still obvious; and one could argue about rounding vs truncation
for real to integer, which is why I choose the integer to real case).

There is no intuitively obvious universally agreed answer on what an
equivalent numerical value for .true. or .false. would be. I will not
participate in a revival of the recent thread where people argue about
what it "should" be. I take the thread itself as evidence that there is
no universally intuitive answer. Frankly, I figure that anyone who
thinks there is such a universally intuitive answer must have a pretty
narrow viewpoint and not be very good at seeing others. If you think
there is a preferred answer, well, I won't argue with you, but that
wasn't the point. The point is that whatever the answer might be, it is
not intuitive and agreed on by all.

(Note, for example, my misguess that 0 and 1 might be the values
intended in the code in question).

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
epc8@juno.com

2005-04-26, 4:00 pm


Dick Hendrickson wrote:[color=darkred]
> jam wrote:
written[color=darkred]
before[color=darkred]
works[color=darkred]
can[color=darkred]
> Others have explained why it's not legal. If you want
> to do this in a standard conforming was, try
> cond = -merge((k-1)*t2, 0.0, nt .eq. 1) -
> merge(volt,0.0, nt .eq. 2)
>
> The merge function selects an argument based on
> the truehness of the 3rd argument. If you are
> sure that NT will be 1 or 2, then
> cond = - merge ((k-1)*t2, volt, nt .eq. 1)
> should also work.
>
> Dick Hendrickson

Ouch. IMO this is as ugly as the ternary operator in C. If I had to
write this as an arithmetic expression, then I would write my own
indicator function:

function indic(q)
logical q
if (q) then
indic=1
else
indic=0
end if

Who cares about branch prediction penalties here? I'd take pity on the
next maintenance programmer and write some IF statements.

{BTW, in Pascal, ord(some_boolean) returns 1 for true and 0 for false.}

It's been years since I've seen this construct in working code, but the
last time I ran into it, it bit me - in BASIC. Some BASICs returned 1
for true, others -1.

Steve Lionel

2005-04-26, 4:00 pm

On Tue, 26 Apr 2005 07:46:22 -0700, Richard E Maine <nospam@see.signature>
wrote:

>Plus, at least the appropriate value from conversion from integer to
>real is intuitively obvious and agreed on by all.


True, but the reverse is not so obvious nor agreed to by all. In Fortran
contexts, real to integer conversion truncates, which, once you understand
that 2.999999999999 converts to 2, is ok. But when you get into rounding, you
suddenly find yourself asking "which kind of rounding"? NINT has a different
definition than IEEE "round to nearest", for example. The behavior of the F
edit desciptor simply says "rounded" without specifying which kind of rounding
to do.

Here be dragons!


Steve Lionel
Software Products Division
Intel Corporation
Nashua, NH

User communities for Intel Software Development Products
http://softwareforums.intel.com/
Intel Fortran Support
http://developer.intel.com/software/products/support/
glen herrmannsfeldt

2005-04-27, 3:58 am

Ken Fairfield wrote:

[color=darkred]

If I remember right, the DEC Fortran 66 compilers would use .AND. and
..OR. on integers, and/or convert between INTEGER and LOGICAL.
[color=darkred]
> Indeed, I was quite guilty of that in my youth. :-} .AND. and
> .OR. were "obviously" bitwise operators whereas IAND and IOR were
> some archaic F66 or Fortran H ugliness. <Ah, youth! How certain,
> how inexperienced...>


Fortran G and H would NOT convert between INTEGER and LOGICAL, nor
apply logical operators to INTEGER variables. Fortran H, with a
special option, would supply the IAND and IOR functions, as those
were needed to compile the Fortran H compiler.

The biggest problem was that the only one byte data type was
LOGICAL*1, and relational operators could not be applied to it.

[color=darkred]
> There was a guess in one of the earlier posts that the values were
> 0 and 1. On VMS, they are 0 and -1, i.e., 0 and FFFFFFFF, as you would
> expect in a masking statement. I think Steve L. confirmed that CVF also
> used -1. My recollection of IBM mainframes was that the various
> Fortrans used 0 and positive 1, although they were rarely used in
> numeric contexts.


They were also 0 and -1 on the TOPS-10 and RT-11 compilers.
IBM Fortran G and H used the low bit only (0 and 1), though EQUIVALENCE
would be needed to test that.

-- glen

mcalhoun@ksu.edu

2005-05-01, 9:08 pm

<<Here is a snippet of the code. Can someone explain to me how this can
<<be done and if it's legal?
<< NT=VSP(4,I)+.5
<< COND=-((K-1)*T2*(NT.EQ.1)+VOLT*(NT.EQ.2))

<This is an extension supported by the DEC compilers and ....
<Note that many people unwittingly treat integers as logicals by using
<operators such as .AND. and .OR. on integers, which is not allowed by the
<standard.

But aren't IOR, ISHFT, IEOR, IAND, and NOT essentially standardized
by MIL-STD 1753?
--
--Myron A. Calhoun.
Five boxes preserve our freedoms: soap, ballot, witness, jury, and cartridge
PhD EE (retired). "Barbershop" tenor. CDL(PTXS). W0PBV. (785) 539-4448
NRA Life Member and Certified Instructor (Home Firearm Safety, Rifle, Pistol)
Richard E Maine

2005-05-01, 9:08 pm

In article <b7k271d0ng4v89isd8ct6dnu3s4bhpqnrf@4ax.com>,
Steve Lionel <Steve.Lionel@REMOVEintelME.com> wrote:

> On 28 Apr 2005 15:51:48 -0500, mcalhoun@ksu.edu wrote:
>
>
> Yes, and, more importantly, by Fortran 90.


But note that they do not "mix logicals and integers" in the same way as
the nonstandard usages that are the main subject of this thread. They
are purely arithmetic operations, taking integer operands and delivering
integer results. In fact, as defined by the f90 standard, they do *NOT*
depend on the actual bits used to represent integers. A binary model is
used to define the operation, but this is purely a model. If, for
example, the processor happens to use something like BCD to represent
integers, these intrinsics still deliver results based on the binary
model - they do not operate on actual bits in the BCD representation.
Yes, that would give different results.

There are no logicals "in sight" in the f90 definition of these
intrinsics. Using logical arguments would be an error (unless you added
extra specifics in addition to the standard ones).

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com