× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



If you're on V5R4 or later, you can modify Scott's example at, as follows:

     D  Big            ds                  Qualified
     D  Int                          10I 0
     D  Byte1                         1A   overlay(Int)
     D  Byte2                         1A   overlay(Int:*NEXT)
     D  Byte3                         1A   overlay(Int:*NEXT)
     D  Byte4                         1A   overlay(Int:*NEXT)

     D Little          DS                  Qualified
     D  Int                          10I 0
     D  Byte4                         1A   overlay(Int)
     D  Byte3                         1A   overlay(Int:*NEXT)
     D  Byte2                         1A   overlay(Int:*NEXT)
     D  Byte1                         1A   overlay(Int:*NEXT)

     C                   eval-corr Little = Big


-Bob Cozzi
www.RPGxTools.com
RPG xTools - Enjoy programming again.


-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx] On
Behalf Of Scott Klement
Sent: Thursday, April 06, 2006 12:17 PM
To: RPG programming on the AS400 / iSeries
Subject: Re: Handling little-endian numbers in RPG



> I am writing some code to import data from a stream file. The numeric data
> is held in little-endian byte order. Is there an easy way to handle/convert
> this data to big-endian byte order?

It's simply a matter of reversing the order of the bytes in the integer. 
There's no need to use multiplication or anything like that, just flip the 
bytes.  For example:

       *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       *  Flip the bytes in a 32-bit integer.  If the original was
       *      in little-endian format, this converts to big-endian,
       *      and vice-versa.
       *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      P flipInt         B
      D flipInt         PI            10I 0
      D   peInt                       10I 0 value

      D                 ds
      D  Int                          10I 0
      D  Byte1                         1A   overlay(Int:1)
      D  Byte2                         1A   overlay(Int:2)
      D  Byte3                         1A   overlay(Int:3)
      D  Byte4                         1A   overlay(Int:4)

      D save            s              1A

       /free
          Int   = peInt;
          Save  = Byte4;
          Byte4 = Byte1;
          Byte1 = Save;
          Save  = Byte3;
          Byte3 = Byte2;
          Byte2 = Save;
          return Int;
       /end-free
      P                 E

That code is from a program I'm using in production, so I know that it 
works. I suspect that simply copying these bytes like that is much faster 
than the multiplying and exponent code that you're using.

I also wrote a proof of concept program that would do this with any field 
(character or numeric) and in any size (so it'd work with 2, 4, or 8 byte 
integers, among other things).  This one is not used in production 
anywhere, but I believe that it works correctly.  It's probably not as 
fast as the "flipInt" example, though.

      H DFTACTGRP(*NO)

      D Reverse         PR
      D   Input                         *   value
      D   Output                        *   value
      D   Size                        10I 0 value

      D Test1           s              5I 0
      D Test2           s              5I 0

      D Test3           s             26A
      D Test4           s             26A

      D Test5           s             10I 0
      D Test6           s             10I 0

       *
       * test1 = 16384 (x'4000')
       * test2 will be 64 (x'0040')
       *
      c                   eval      test1 = 16384

      c                   callp     Reverse( %addr(test1)
      c                                    : %addr(test2)
      c                                    : %size(test1) )

      c                   dsply                   test2

       *
       * test3 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
       * test4 will be 'ZYXWVUTSRQPONMLKJIHGFEDCBA'
       *
      c                   eval      test3 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

      c                   callp     Reverse( %addr(test3)
      c                                    : %addr(test4)
      c                                    : %size(test3) )

      c                   dsply                   test4

       *
       * Test5 = 2130772483 (x'7F010203')
       * Test6 will be 50463103 (x'0302017F')
       *
      c                   eval      Test5 = 2130772483

      c                   callp     Reverse( %addr(test5)
      c                                    : %addr(test6)
      c                                    : %size(test5) )

      c                   dsply                   test6

      c                   eval      *inlr = *on




       *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       * Reverse():  This routine copies the bytes from a input buffer
       *              to an output buffer in reverse order.
       *
       *         Input = pointer to start of input buffer
       *        Output = pointer to start of output buffer
       *          Size = size of input buffer.  (output buffer must
       *                     be at least this large as well)
       *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      P Reverse         B
      D Reverse         PI
      D   Input                         *   value
      D   Output                        *   value
      D   Size                        10I 0 value

      D x               s             10I 0
      D InByte          s              1A   based(input)
      D OutByte         s              1A   based(output)

      c                   eval      Output = Output + (Size - 1)

      c                   for       x = 1 to Size
      c                   eval      OutByte = InByte
      c                   eval      Input = Input + 1
      c                   eval      Output = Output - 1
      c                   endfor
      P                 E

You don't need to worry about the sign.  The sign bit stays with the most 
significant byte of the integer.  So on a big-endian system, it'd be the 
leftmost byte, and on a little-endian system it'd be the rightmost byte. 
No special checking has to be done because it gets moved with the rest of 
the byte.

Good luck


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.