×

Good News Everybody!

The new search engine is LIVE!

Please report any problems to david (at) midrange.com.






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


This thread ...

Follow-Ups:
Replies:

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

This mailing list archive is Copyright 1997-2026 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.