|
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 EThat 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 EYou 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 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.