From: robin on
LC's No-Spam Newsreading account wrote in message ...
>It is at least 18 years I've been using a set of byteswapping routines
>of mine. Since when I first wrote them, there were only REAL*8 but
>REAL*4 and INTEGER*4, I wrote two routines but called them in 3 cases:
>
>Namely the routine designed for 32-bit byte swap had a nominal integer
>argument
>
> SUBROUTINE SWAPI4(DATA,N)
> INTEGER N
> INTEGER*4 DATA(N)
>
>but I freely called it interchangeably with integer or float
>arguments, as e.g. CALL SWAPI4(I4(1),1) or CALL SWAPI4(R4(1),1)
>
>The routine for 64-bit byte swap had nominally a float argument (full
>code attached below). Since at the time the only 64-bit quantities used
>were double precision float, I had no problems.
>
>However recently I had the need of byteswapping 64-bit integers,
>therefore I called it passing an INTEGER*8 argument (equivalenced to a
>REAL*8)


Having mis-matched types in a CALL is asking for trouble.


From: robin on
LC's No-Spam Newsreading account wrote in message ...

>It is at least 18 years I've been using a set of byteswapping routines
>of mine. Since when I first wrote them, there were only REAL*8 but
>REAL*4 and INTEGER*4, I wrote two routines but called them in 3 cases:
>
>Namely the routine designed for 32-bit byte swap had a nominal integer
>argument
>
> SUBROUTINE SWAPI4(DATA,N)
> INTEGER N
> INTEGER*4 DATA(N)
>
>but I freely called it interchangeably with integer or float
>arguments, as e.g. CALL SWAPI4(I4(1),1) or CALL SWAPI4(R4(1),1)
>
>The routine for 64-bit byte swap had nominally a float argument (full
>code attached below). Since at the time the only 64-bit quantities used
>were double precision float, I had no problems.
>
>However recently I had the need of byteswapping 64-bit integers,
>therefore I called it passing an INTEGER*8 argument (equivalenced to a
>REAL*8)

If you are byteswapping 64-bit integers, why are you equivalencing it to
a REAL? To byteswap 64-bit integers, you need to equivalence
it to something that will allow you to access the bytes.

>I found that in some rare cases (for me this was 5 out 10,000 values !)
>the result was incorrect. I was able to pinpoint it to the case when the
>bit pattern of the integer correspond to that of a signalling NAN,
>which, in the argument passage, is silently converted to a quiet NAN.
>
>As a result, the byteswapped returned (integer) value is wrong, e.g.
>
>FFF0150068000000 is swapped into 000000680015F8FF
>
>So if somebody has the need of using similar legacy routines, beware !
>
> SUBROUTINE SWAPR8(DATA,N)
> INTEGER N
> REAL*8 DATA(N)
> REAL*8 WORK
> CHARACTER C(8),W
> EQUIVALENCE (WORK,C)
> INTEGER I
>C
> IF(N.LE.0)RETURN
> DO 1 I=1,N
> WORK=DATA(I)
> W=C(1)
> C(1)=C(8)
> C(8)=W
> W=C(2)
> C(2)=C(7)
> C(7)=W
> W=C(3)
> C(3)=C(6)
> C(6)=W
> W=C(4)
> C(4)=C(5)
> C(5)=W
> DATA(I)=WORK
> 1 CONTINUE
> RETURN
> END




From: LC's No-Spam Newsreading account on
On Tue, 2 Mar 2010, robin wrote:

> If you are byteswapping 64-bit integers, why are you equivalencing it
> to a REAL? To byteswap 64-bit integers, you need to equivalence it to
> something that will allow you to access the bytes.

I said explicity this was legacy code.

Since a subroutine call passes the address, it should be irrelevant
to match argument type, provided the subroutine uses the data
consistently (it does).

And a routine doing byte swap on an n-byte item (n=2,4,8) does not need
to know the semantics of the data (whether it is integer or real). So
one can have ONE routine, not two. I like these little savings.

In the past I was using a SWAPI4 (with nominally integer argument) to
swap both INTEGER*4 and REAL*4. I was using SWAPR8 (with nominally real
argument) for REAL*8 because at the time INTEGER*8 did not even exist
(and if it did, I was not using it).

In fact I am now using a SWAPI8 which is identical to the one I posted,
but for the fact the argument and work variables are INTEGER*8. And this
works for both integer or real. So I had my Minimum Necessary Change :-)

The reason was neatly explained by Steve Lionel, whose answer is greatly
appreciated (and very helpful, as usual, thanks Steve !)


--
----------------------------------------------------------------------
nospam(a)mi.iasf.cnr.it is a newsreading account used by more persons to
avoid unwanted spam. Any mail returning to this address will be rejected.
Users can disclose their e-mail address in the article if they wish so.
From: robin on
LC's No-Spam Newsreading account wrote in message ...
>On Tue, 2 Mar 2010, robin wrote:
>
>> If you are byteswapping 64-bit integers, why are you equivalencing it
>> to a REAL? To byteswap 64-bit integers, you need to equivalence it to
>> something that will allow you to access the bytes.
>
>I said explicity this was legacy code.

That's irrelevant.
Even legacy code is expected to obey the rules.

>Since a subroutine call passes the address, it should be irrelevant
>to match argument type, provided the subroutine uses the data
>consistently (it does).

You have proven that it is not irrelevant.

>And a routine doing byte swap on an n-byte item (n=2,4,8) does not need
>to know the semantics of the data (whether it is integer or real). So
>one can have ONE routine, not two. I like these little savings.

No, as others have already exxplained, that leads to trouble.

>In the past I was using a SWAPI4 (with nominally integer argument) to
>swap both INTEGER*4 and REAL*4. I was using SWAPR8 (with nominally real
>argument) for REAL*8 because at the time INTEGER*8 did not even exist
>(and if it did, I was not using it).
>
>In fact I am now using a SWAPI8 which is identical to the one I posted,
>but for the fact the argument and work variables are INTEGER*8. And this
>works for both integer or real. So I had my Minimum Necessary Change :-)
>
>The reason was neatly explained by Steve Lionel, whose answer is greatly
>appreciated (and very helpful, as usual, thanks Steve !)

Then why are you arguing the contrary above?


From: LC's No-Spam Newsreading account on
On Wed, 3 Mar 2010, robin wrote:

>> Since a subroutine call passes the address, it should be irrelevant
>> to match argument type, provided the subroutine uses the data
>> consistently (it does).
>
> You have proven that it is not irrelevant.

The non-irrelevance occurs AT SUBROUTINE CALL, not INSIDE the
subroutine. And the effect (change of signalling to quiet NaN) occurs
only when calling an R routine with an I argument (not when calling an I
routine with an R argument).

>> The reason was neatly explained by Steve Lionel, whose answer is greatly
>> appreciated (and very helpful, as usual, thanks Steve !)
>
> Then why are you arguing the contrary above?

He said "You are correct to alert others to this issue - never use REALs
as a proxy for arbitrary datatypes."

.... which means INTEGERs could be used as proxy.

My SWAPI4 (with INTEGERs as proxy) has been happily in use for 18 years
on different operating systems (at least VMS, various Unixes with
different endianness and Linux).

My present SWAPI8 is working for both integer and reals. And the
(minimum necessary) change from my older SWAPR8 was just in two lines of
code. Not adding a second routine.

The fact I had SWAPR8 was historical (at the time it was written REAL*8
was the only widespread 8-byte elementary datatype)

For me the issue is settled.

--
----------------------------------------------------------------------
nospam(a)mi.iasf.cnr.it is a newsreading account used by more persons to
avoid unwanted spam. Any mail returning to this address will be rejected.
Users can disclose their e-mail address in the article if they wish so.