From: frank on

dan(a)dan-desktop:~/source$ gfortran temp1.f90 -Wall -Wextra -o out
dan(a)dan-desktop:~/source$ ./out
NaN
1111111110000000000000000000000
a is T F F T F T F F T T T F T T F F T F F F T T T F T T T F T F F F
dan(a)dan-desktop:~/source$ cat temp1.f90
PROGRAM test_transfer
integer :: x = 2143289344
logical :: a(32)
print *, transfer(x, 1.0) ! prints "NaN" on i686
write(*, '(B32)') x

a = transfer(x, a, 32)
print *, " a is ", a
END PROGRAM
! gfortran temp1.f90 -Wall -Wextra -o out
dan(a)dan-desktop:~/source$

I don't think that I'm populating a with the bits from x correctly. I
thought this would work. ??
--
frank

"Guns: yes, they are harmful."
From: Tim Prince on
frank wrote:
> dan(a)dan-desktop:~/source$ gfortran temp1.f90 -Wall -Wextra -o out
> dan(a)dan-desktop:~/source$ ./out
> NaN
> 1111111110000000000000000000000
> a is T F F T F T F F T T T F T T F F T F F F T T T F T T T F T F F F
> dan(a)dan-desktop:~/source$ cat temp1.f90
> PROGRAM test_transfer
> integer :: x = 2143289344
> logical :: a(32)
> print *, transfer(x, 1.0) ! prints "NaN" on i686
> write(*, '(B32)') x
>
> a = transfer(x, a, 32)
> print *, " a is ", a
> END PROGRAM
> ! gfortran temp1.f90 -Wall -Wextra -o out
> dan(a)dan-desktop:~/source$
>
> I don't think that I'm populating a with the bits from x correctly. I
> thought this would work. ??
The books on my desk say the resulting elements of a, other than the
first, are "processor dependent." Whatever happened to be in memory as a
result of what came before? No doubt, whether the first element displays
as True or False also would be processor dependent, even though the bit
pattern of that element may be predictable among most current platforms,
and non-zero is likely to show as T on many platforms.
So, it probably "works," but doesn't do anything useful.
Did I step into a troll's nest?
From: Frank on
On Wed, 02 Dec 2009 20:12:17 -0800, Tim Prince wrote:

> frank wrote:
>> dan(a)dan-desktop:~/source$ gfortran temp1.f90 -Wall -Wextra -o out
>> dan(a)dan-desktop:~/source$ ./out
>> NaN
>> 1111111110000000000000000000000
>> a is T F F T F T F F T T T F T T F F T F F F T T T F T T T F T F F F
>> dan(a)dan-desktop:~/source$ cat temp1.f90
>> PROGRAM test_transfer
>> integer :: x = 2143289344
>> logical :: a(32)
>> print *, transfer(x, 1.0) ! prints "NaN" on i686
>> write(*, '(B32)') x
>>
>> a = transfer(x, a, 32)
>> print *, " a is ", a
>> END PROGRAM
>> ! gfortran temp1.f90 -Wall -Wextra -o out
>> dan(a)dan-desktop:~/source$
>>
>> I don't think that I'm populating a with the bits from x correctly. I
>> thought this would work. ??
> The books on my desk say the resulting elements of a, other than the
> first, are "processor dependent."

This is what I was looking at:

8.217 TRANSFER �X Transfer bit patterns

Description:
Interprets the bitwise representation of SOURCE in memory as if it is
the representation of a variable or array of the same type and type
parameters as MOLD.

This is approximately equivalent to the C concept of casting one type
to another.
Standard:
Fortran 95 and later
Class:
Transformational function
Syntax:
RESULT = TRANSFER(SOURCE, MOLD[, SIZE])
Arguments:

SOURCE Shall be a scalar or an array of any type.
MOLD Shall be a scalar or an array of any type.
SIZE (Optional) shall be a scalar of type INTEGER.

Return value:
The result has the same type as MOLD, with the bit level representation
of SOURCE. If SIZE is present, the result is a one-dimensional array of
length SIZE. If SIZE is absent but MOLD is an array (of any size or shape),
the result is a one- dimensional array of the minimum length needed to
contain the entirety of the bitwise representation of SOURCE. If SIZE is
absent and MOLD is a scalar, the result is a scalar.

If the bitwise representation of the result is longer than that of
SOURCE, then the leading bits of the result correspond to those of SOURCE
and any trailing bits are filled arbitrarily.

When the resulting bit representation does not correspond to a valid
representation of a variable of the same type as MOLD, the results are
undefined, and subsequent operations on the result cannot be guaranteed to
produce sensible behavior. For example, it is possible to create LOGICAL
variables for which VAR and .NOT.VAR both appear to be true.
Example:

PROGRAM test_transfer
integer :: x = 2143289344
print *, transfer(x, 1.0) ! prints "NaN" on i686
END PROGRAM

> Whatever happened to be in memory as a
> result of what came before?

The T F pattern looked random and very much unlike the heterogenous all
ones then all zeroes.

> No doubt, whether the first element displays
> as True or False also would be processor dependent, even though the bit
> pattern of that element may be predictable among most current platforms,
> and non-zero is likely to show as T on many platforms.
> So, it probably "works," but doesn't do anything useful.

I'm still trying to herd the bits of a real into an array.
> Did I step into a troll's nest?

I don't see any trolls in these representations. YMMV.
--
frank
From: glen herrmannsfeldt on
Frank <frank(a)example.invalid> wrote:
> On Wed, 02 Dec 2009 20:12:17 -0800, Tim Prince wrote:

(snip)
> This is what I was looking at:

> 8.217 TRANSFER ? Transfer bit patterns

> Description:
> Interprets the bitwise representation of SOURCE in memory as if it is
> the representation of a variable or array of the same type and type
> parameters as MOLD.

> This is approximately equivalent to the C concept of
> casting one type to another.

C casts do the appropriate conversion. If you want to see the
bits through casts you have to dereference a pointer cast to
a pointer to a different type, though in that case the standard
does not guarantee the result.

To do it following the standard (at least C90), you cast a
pointer to (unsigned char *), memcpy() the bits to a variable
through a pointer also cast to (unsigned char *).

-- glen
From: m_b_metcalf on
On Dec 3, 4:52 am, frank <fr...(a)example.invalid> wrote:
> dan(a)dan-desktop:~/source$ gfortran temp1.f90 -Wall -Wextra -o out
> dan(a)dan-desktop:~/source$ ./out
>              NaN
>  1111111110000000000000000000000
>   a is  T F F T F T F F T T T F T T F F T F F F T T T F T T T F T F F F
> dan(a)dan-desktop:~/source$ cat temp1.f90
> PROGRAM test_transfer
> integer :: x = 2143289344
> logical :: a(32)
> print *, transfer(x, 1.0)    ! prints "NaN" on i686
> write(*, '(B32)') x
>
> a = transfer(x, a, 32)
> print *, " a is ", a
> END PROGRAM
> ! gfortran temp1.f90 -Wall -Wextra -o out
> dan(a)dan-desktop:~/source$
>
> I don't think that I'm populating a with the bits from x correctly.  I
> thought this would work.  ??
> --
> frank
>
> "Guns: yes, they are harmful."

Think of transfer as pouring bits from source to the function result.
As you're pouring 32 bits of source into 32**2 bits of target, only
the first 32 bits, i.e. a(1), get defined. The other 31 elements have
processor-dependent values. If you want to unpack bits, try:

write(*, '(B32.32)') x
forall(i=0:31) a(i+1) = btest(x, i)

where you should also note the form of the edit descriptor that allows
you to see leading zeros.

Regards,

Mike Metcalf