From: LC's No-Spam Newsreading account on 1 Mar 2010 05:38 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) 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 -- ---------------------------------------------------------------------- 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: glen herrmannsfeldt on 1 Mar 2010 07:17 LC's No-Spam Newsreading account <nospam(a)mi.iasf.cnr.it> wrote: > 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) That will usually work, but the standard doesn't require it to work. It is more likely to work if the called routine uses INTEGER instead of REAL. > 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 rewrite the routine to use INTEGER*8 then it wouldn't even try to do floating point operations. It might, for example, load the value into a floating point register and then store it. > 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 (snip of routine that exchanges through an EQUIVALENCEd CHARACTER*8 variable.) Many now have INTEGER*1, but CHARACTER should work on most machines. (Watch out for ones with 16 bit unicode characters.) Also, many processors have a hardware byte swap instruction, at least for 16 bit and 32 bit swaps. That is likely much faster than doing it in any high-level language. -- glen
From: Steve Lionel on 1 Mar 2010 16:52 On 3/1/2010 5:38 AM, LC's No-Spam Newsreading account wrote: > 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. This is a feature of the IA-32 architecture. On a floating load of a signaling NaN, it is converted to a quiet NaN. I've seen customers run into this before. Depending on compiler options, an integer value corresponding to an IEEE denormal might be changed to zero. You are correct to alert others to this issue - never use REALs as a proxy for arbitrary datatypes. -- Steve Lionel Developer Products Division Intel Corporation Nashua, NH For email address, replace "invalid" with "com" User communities for Intel Software Development Products http://software.intel.com/en-us/forums/ Intel Software Development Products Support http://software.intel.com/sites/support/ My Fortran blog http://www.intel.com/software/drfortran
From: glen herrmannsfeldt on 1 Mar 2010 17:20 Steve Lionel <steve.lionel(a)intel.invalid> wrote: (snip on converting SNaN to QNan) > This is a feature of the IA-32 architecture. On a floating load of a > signaling NaN, it is converted to a quiet NaN. I've seen customers run > into this before. Depending on compiler options, an integer value > corresponding to an IEEE denormal might be changed to zero. In the OS/360 days, I sometimes used REAL*8 for Hollerith data. Fortunately S/360 doesn't change the bit patterns on load or store to floating point registers. Specifically, it doesn't normalize values. (It will if you add zero, so don't do that.) > You are correct to alert others to this issue - never use REALs as a > proxy for arbitrary datatypes. This is, in general, a good idea. (Especially with the popularity of IA32.) Though as not all systems supported INTEGER*8 until somewhat recently, there wasn't always an alternative. -- glen
From: robin on 2 Mar 2010 07:41 glen herrmannsfeldt wrote in message ... >LC's No-Spam Newsreading account <nospam(a)mi.iasf.cnr.it> wrote: >(snip of routine that exchanges through an EQUIVALENCEd >CHARACTER*8 variable.) No, he didn't equivalence to CHARACTER*8. He equivalenced to an array of Character*1.
|
Next
|
Last
Pages: 1 2 3 Prev: Overriding assignment and array slicing Next: breakpoint in multiple file source code |