From: robin on 2 Mar 2010 07:41 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 2 Mar 2010 07:41 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 3 Mar 2010 05:06 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 3 Mar 2010 07:20 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 3 Mar 2010 09:53 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.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Overriding assignment and array slicing Next: breakpoint in multiple file source code |