Re: Garbage in dead zone
- From: "James Van Buskirk" <not_valid@xxxxxxxxxxx>
- Date: Sat, 31 May 2008 14:18:11 -0600
"Charles Coldwell" <coldwell@xxxxxxxxx> wrote in message
news:rzpod6mmzei.fsf@xxxxxxxxxxxx
Let me see if I understand this expression
transfer([real(cc),0.0_10],0_16)
correctly. In order to keep things 32-bit aligned, a REAL(KIND=10)
variable actually occupies twelve bytes in memory instead of ten.
It's more complicated than that. Actually a REAL(KIND=10) variable
takes up 16 bytes on the compiler in question (gfortran for 64-bit
Windows). I gather that some if not all compilers which implement
REAL(KIND=10) variables on 32-bit Windows pad them out to only 12
bytes. I guess the 32-bit Windows people never read
http://www.intel.com/design/processor/manuals/248966.pdf
where it is recommended in section 3.6.3:
"Align 80-bit data so that its base address is a multiple of
sixteen."
So
the actual arguments supplied to
TRANSFER(SOURCE, MOLD [,SIZE])
are
SOURCE : a two-element rank-1 array occupying 24 bytes
MOLD : a scalar occupying 16 bytes
Actually as explained above for the system in question SOURCE
occupies 32 bytes.
The result should be "of type and type parameters those of MOLD", so
the result is going to be a 16-byte scalar integer. Furthermore, "If
the physical representation of the result is as long as or longer than
that of SOURCE, the result contains SOURCE as its leding part and the
rest is undefined; otherwise the result is the leading part of
SOURCE." So, IIUC the goal of
transfer([real(cc),0.0_10],0_16)
is to express REAL(cc) as a 16-byte integer.
That is correct.
Since REAL(cc) is a ten
byte floating point number plus two bytes of padding, TRANSFER-ing it
into a 16-byte integer scalar would leave at least four bytes
undefined, or six bytes undefined if we include the two padding bytes.
Therefore, you create a two element rank-1 REAL(KIND=10) array, for 24
bytes total, then transfer the first 16 bytes of this array into an
integer. So the first ten bytes of the 16-byte integer are the bits
from your original REAL(KIND=10), the next two (undefined) bytes are
alignment padding, and the last four are zeros taken from the 0.0_10
second array element.
As explained it's more complicated than that.
Then you
write(*,'(z0.20)') transfer([real(cc),0.0_10],0_16)
write(*,'(z0.20)') transfer([aimag(cc),0.0_10],0_16)
which should show us the bits in the COMPLEX(KIND=10) variable cc:
Invoking ACOSH...
00000000000000000000
7FF000000000000000000000000
so the real part is zero, and the imaginary part has some other stuff
in it. What puzzles me is the placement of that other stuff. I would
not have been surprised to find that the alignment padding bytes
contain random garbage, but if I'm counting zeros correctly, the
7FF garbage is above that:
00000000 (LSB)
00000000
00000000
000007FF (MSB)
In other words, the garbage is in the most significant 4 bytes of the
16-byte integer value returned by the TRANSFER. I think those should
have been zeroed by the second element in your two-element temporary
array. You're on a little-endian (W64) machine, right?
What you haven't seen is that if the above-quoted WRITE statements
are reversed, it's the REAL part that picks up the garbage.
gfortran seems to be inconsistent about the entire upper 6 bytes of
a REAL(KIND=10) variable, sometimes meticulously copying the lower
12 bytes, obviously an FSTP instruction that writes such a variable
writes 10 bytes, and sometimes all 16 bytes after they get corrupted
as shown are preserved.
An extra call to IBITS would work around this problem but some
people might claim that the original WRITE statements are already
quite complicated because they contain an invocation of TRANSFER in
in them. What's so hard to read about TRANSFER?
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
.
- References:
- Garbage in dead zone
- From: James Van Buskirk
- Re: Garbage in dead zone
- From: Charles Coldwell
- Garbage in dead zone
- Prev by Date: Re: warning on running image !!!!!
- Next by Date: Re: Module compile order
- Previous by thread: Re: Garbage in dead zone
- Next by thread: newbie: that mapping CHARACTER*2 to INTEGER*2 question
- Index(es):
Relevant Pages
|
|