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

Bitwise logical functions in gfortran

2 views
Skip to first unread message

James Van Buskirk

unread,
May 13, 2008, 7:15:17 PM5/13/08
to
gfortran documents the intrinsic extension functions AND, OR, and
XOR. However, the documentation gives the impression that it
permits mixed-mode operations between INTEGER and LOGICAL types.
Also it doesn't emphasize that the functions are not elemental.

C:\gfortran\test\intrinsics>type logical1.f90
program L
write(*,*) and(3_1,[1,2,3,4])
write(*,*) and(.TRUE._1, 1_1)
end program L

C:\gfortran\test\intrinsics>gfortran logical1.f90 -ological1
logical1.f90:2.22:

write(*,*) and(3_1,[1,2,3,4])
1
Error: 'j' argument of 'and' intrinsic at (1) must be a scalar
logical1.f90:3.27:

write(*,*) and(.TRUE._1, 1_1)
1
Error: 'i' and 'j' arguments of 'and' intrinsic at (1) must have the same
type

Not to mention that the functions don't seem to work for LOGICAL inputs:

C:\gfortran\test\intrinsics>type logical2.f90
program L
write(*,*) and(.TRUE._1, .TRUE._1)
write(*,*) or(.TRUE._1, .TRUE._1)
write(*,*) xor(.TRUE._1, .TRUE._1)
end program L

C:\gfortran\test\intrinsics>gfortran logical2.f90 -ological2
logical2.f90:5.13:

end program L
1
Internal Error at (1):
gfc_range_check(): Bad type

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


Terence

unread,
May 13, 2008, 7:29:29 PM5/13/08
to
Logical variable are essentially 1-bit true/false values.
Any logical operations on these variables provide ony one bit of
resulting information.

F77 did not have bit-wise logical operations on integers and so I had
to add them to my fortran library. But later compilers have
fortunately extended the use of logical operators to apply to integer
variables.

I think that the logical operators still work as if the variables
operated upon are bit-wise integers (even if logical variables), but
if the resulting variable is defined as a Logical, then a final
operation is executed to make te result a 1-bit truth value.

Steven G. Kargl

unread,
May 13, 2008, 7:41:05 PM5/13/08
to
In article <WrKdnY3Z5d2ZvLfV...@comcast.com>,

"James Van Buskirk" <not_...@comcast.net> writes:
> gfortran documents the intrinsic extension functions AND, OR, and
> XOR. However, the documentation gives the impression that it
> permits mixed-mode operations between INTEGER and LOGICAL types.
> Also it doesn't emphasize that the functions are not elemental.

The documentation clearly states "This intrinsic routine is provided
for backwards compatibility with GNU Fortran 77." and 7 lines down
it shows "Class: Function". This clearly shows that the function
isn't elemental. 1) Fortran 77 did not support elemental functions,
and 2) if it were elemental,then it would state ""Class: Elemental
Function". I suppose one could argue that the descriptions of
the argument should include the word 'scalar'.

I agree the wording on cross-promotion could be improved. I suspect,
but I'm too lazy to read the gfortran source code for you, that the
cross promotion is for variables of the same type but different kind.

--
Steve
http://troutmask.apl.washington.edu/~kargl/

Steven G. Kargl

unread,
May 13, 2008, 8:08:10 PM5/13/08
to
In article <WrKdnY3Z5d2ZvLfV...@comcast.com>,
"James Van Buskirk" <not_...@comcast.net> writes:
>
> Not to mention that the functions don't seem to work for LOGICAL inputs:
>
> C:\gfortran\test\intrinsics>type logical2.f90
> program L
> write(*,*) and(.TRUE._1, .TRUE._1)
> write(*,*) or(.TRUE._1, .TRUE._1)
> write(*,*) xor(.TRUE._1, .TRUE._1)
> end program L
>
> C:\gfortran\test\intrinsics>gfortran logical2.f90 -ological2
> logical2.f90:5.13:
>
> end program L
> 1
> Internal Error at (1):
> gfc_range_check(): Bad type
>

troutmask:sgk[219] cat l.f90
program L
write(*,*) and(.TRUE., .TRUE.)
write(*,*) or(.TRUE., .TRUE.)
write(*,*) xor(.TRUE., .TRUE.)
end program L

troutmask:sgk[220] gfc4x -o z l.f90
troutmask:sgk[221] ./z
T
T
F
troutmask:sgk[222] nedit l.f90
troutmask:sgk[223] cat l.f90


program L
write(*,*) and(.TRUE._1, .TRUE._1)
write(*,*) or(.TRUE._1, .TRUE._1)
write(*,*) xor(.TRUE._1, .TRUE._1)
end program L

troutmask:sgk[224] gfc4x -o z l.f90
troutmask:sgk[225] ./z
T
T
F


Index: simplify.c
===================================================================
--- simplify.c (revision 135271)
+++ simplify.c (working copy)
@@ -505,14 +505,15 @@ gfc_simplify_and (gfc_expr *x, gfc_expr
{
result = gfc_constant_result (BT_INTEGER, kind, &x->where);
mpz_and (result->value.integer, x->value.integer, y->value.integer);
+ return range_check (result, "AND");
}
else /* BT_LOGICAL */
{
result = gfc_constant_result (BT_LOGICAL, kind, &x->where);
result->value.logical = x->value.logical && y->value.logical;
+ return result;
}

- return range_check (result, "AND");
}


@@ -3079,14 +3080,14 @@ gfc_simplify_or (gfc_expr *x, gfc_expr *
{
result = gfc_constant_result (BT_INTEGER, kind, &x->where);
mpz_ior (result->value.integer, x->value.integer, y->value.integer);
+ return range_check (result, "OR");
}
else /* BT_LOGICAL */
{
result = gfc_constant_result (BT_LOGICAL, kind, &x->where);
result->value.logical = x->value.logical || y->value.logical;
+ return result;
}
-
- return range_check (result, "OR");
}


@@ -4582,15 +4583,16 @@ gfc_simplify_xor (gfc_expr *x, gfc_expr
{
result = gfc_constant_result (BT_INTEGER, kind, &x->where);
mpz_xor (result->value.integer, x->value.integer, y->value.integer);
+ return range_check (result, "XOR");
}
else /* BT_LOGICAL */
{
result = gfc_constant_result (BT_LOGICAL, kind, &x->where);
result->value.logical = (x->value.logical && !y->value.logical)
|| (!x->value.logical && y->value.logical);
+ return result;
}

- return range_check (result, "XOR");
}

--
Steve
http://troutmask.apl.washington.edu/~kargl/

glen herrmannsfeldt

unread,
May 13, 2008, 8:15:20 PM5/13/08
to
Terence wrote:
(snip)

> I think that the logical operators still work as if the variables
> operated upon are bit-wise integers (even if logical variables), but
> if the resulting variable is defined as a Logical, then a final
> operation is executed to make te result a 1-bit truth value.

It is system dependent. Some will do conversion between integer
and logical values, and allow logical operators to be used on
integers. On those it is likely that all bits are computed.

On some, only one byte or bit of a multi-byte logical variable
is computed.

-- glen

James Van Buskirk

unread,
May 14, 2008, 1:20:46 AM5/14/08
to
"Steven G. Kargl" <ka...@troutmask.apl.washington.edu> wrote in message
news:g0daha$enf$1...@gnus01.u.washington.edu...

> @@ -4582,15 +4583,16 @@ gfc_simplify_xor (gfc_expr *x, gfc_expr
> {
> result = gfc_constant_result (BT_INTEGER, kind, &x->where);
> mpz_xor (result->value.integer, x->value.integer, y->value.integer);
> + return range_check (result, "XOR");
> }
> else /* BT_LOGICAL */
> {
> result = gfc_constant_result (BT_LOGICAL, kind, &x->where);
> result->value.logical = (x->value.logical && !y->value.logical)
> || (!x->value.logical && y->value.logical);
> + return result;
> }
>
> - return range_check (result, "XOR");
> }

And you even hit the documentation out of the park! Awesome!

0 new messages