Hi SAS Communities
I have a question. I have a hexidecimal value (for example 20 e9 ef 01), but I need to convert this to little endian format first (byte swapping) before I can get the decimal number. For this examples it would be that hexadecimal 20 e9 ef 01 is converted to little endian of 01 EF E9 20 which can then be converted to integer of 32500000 (UINT32). How do I do this process in SAS?
I have following
data test; set indata; format tab hex8.; lit_end=input(tab,$UCS2LEw.); run;
I assumed simply applying new informat of little endian would convert hexidecimal to little endian format. But it show:
ERROR 48-59: The informat UCS2LEW was not found or could not be loaded.
I wonder if other way to do?
Any help would be very great.
@linlin87 wrote:
Thanks mkeintz for explaining, very useful. How do I pass a character string to this process? For example I have the character variable
value
which takes values like80f8d501
. How do I pass this rather than the txt= example you gave above?
data input; set input; put value; z=input(value,ib4.); put value= value=hex8. z=; run;
and the log reads for the first row of data
80f8d501 value=80f8d501 value=38306638 z=946221112
I was expecting z to read 30800000.
Any help would be great!
Your value variable is apparently eight bytes long (value='80f8d501'). This is equivalent to 16 nibble's, which have a one-to-one correspondence with hexadecimal digits. Using the IB4 informat in the input function reads the first 4 bytes, i.e. the first 8 nibbles. So for your situation, it is converting hexadecimal 38306638 to an integer, not hexadecimal 80f8d501. For instance, the first character '8' is stored as '38'x, which is '00110110' binary.
806 data _null_;
807 value='80f8d501'; /* 8 bytes long */
808 put value=hex16.; /* Write 8 bytes as 16 nibbles */
809 run;
value=3830663864353031
So if you can't go back and read in VALUE as a 4-character (i.e. 4 bytes = 8 nibbles) variable, then you need to create an intermediate four-byte variable which is truly '80f8d501' hexadecimal:
860 data _null_;
861 value='80f8d501'; /* 8 bytes long */
862 put value= ' equivalent in hexadecimal to ' value hex16. ;
863
864 length hexvalue $4;
865 hexvalue=input(value,$hex8.);
866 z=input(hexvalue,ib4.);
867 put hexvalue=hex8. z=;
868 run;
value=80f8d501 equivalent in hexadecimal to 3830663864353031
hexvalue=80F8D501 z=30800000
@linlin87 wrote:
Hi SAS Communities
I have a question. I have a hexidecimal value (for example 20 e9 ef 01), but I need to convert this to little endian format first (byte swapping) before I can get the decimal number. For this examples it would be that hexadecimal 20 e9 ef 01 is converted to little endian of 01 EF E9 20 which can then be converted to integer of 32500000 (UINT32). How do I do this process in SAS?
Any big endian hexadecimal number that ends in "01" (such as 20e9ef01) cannot generate an even integer value (such as 32500000).
But on my little-Endian intel machine, the hexadecimal value 20E9Ef01 becomes 32500000 using the IB4. format.
708 data _null_;
709 length txt $4;
710 txt='20E9Ef01'x;
711 z=input(txt,ib4.);
712 put txt=$hex8. z=;
713 run;
txt=20E9EF01 z=32500000
In other words, your initial value appears to be little endian already.
Now if your data really does start out as big endian, and you are processing it on a little endian machine, then
778 data _null_;
779 length bigendian $4;
780 bigendian='01EFE920'x;
781 ZBIG=input(bigendian,s370fpib4.);
782 put bigendian=$hex8. ZBIG=;
783 run;
bigendian=01EFE920 ZBIG=32500000
Take a look at Byte Ordering for Integer Binary Data on Big Endian and Little Endian Platforms
As you can see, I assume you don't really need to reverse byte order, but you do need to know want informat to use to read the data given its "endian" attribute.
Thanks mkeintz for explaining, very useful. How do I pass a character string to this process? For example I have the character variable value
which takes values like 80f8d501
. How do I pass this rather than the txt= example you gave above?
data input;
set input;
put value;
z=input(value,ib4.);
put value= value=hex8. z=;
run;
and the log reads for the first row of data
80f8d501
value=80f8d501 value=38306638 z=946221112
I was expecting z to read 30800000.
Any help would be great!
@linlin87 wrote:
Thanks mkeintz for explaining, very useful. How do I pass a character string to this process? For example I have the character variable
value
which takes values like80f8d501
. How do I pass this rather than the txt= example you gave above?
data input; set input; put value; z=input(value,ib4.); put value= value=hex8. z=; run;
and the log reads for the first row of data
80f8d501 value=80f8d501 value=38306638 z=946221112
I was expecting z to read 30800000.
Any help would be great!
Your value variable is apparently eight bytes long (value='80f8d501'). This is equivalent to 16 nibble's, which have a one-to-one correspondence with hexadecimal digits. Using the IB4 informat in the input function reads the first 4 bytes, i.e. the first 8 nibbles. So for your situation, it is converting hexadecimal 38306638 to an integer, not hexadecimal 80f8d501. For instance, the first character '8' is stored as '38'x, which is '00110110' binary.
806 data _null_;
807 value='80f8d501'; /* 8 bytes long */
808 put value=hex16.; /* Write 8 bytes as 16 nibbles */
809 run;
value=3830663864353031
So if you can't go back and read in VALUE as a 4-character (i.e. 4 bytes = 8 nibbles) variable, then you need to create an intermediate four-byte variable which is truly '80f8d501' hexadecimal:
860 data _null_;
861 value='80f8d501'; /* 8 bytes long */
862 put value= ' equivalent in hexadecimal to ' value hex16. ;
863
864 length hexvalue $4;
865 hexvalue=input(value,$hex8.);
866 z=input(hexvalue,ib4.);
867 put hexvalue=hex8. z=;
868 run;
value=80f8d501 equivalent in hexadecimal to 3830663864353031
hexvalue=80F8D501 z=30800000
If the value is already encoded into a hex string then use the $HEX informat to convert the hex string back into an actual string.
55 data _null_; 56 txt='80f8d501'; 57 x=input(input(txt,$hex8.),ib4.); 58 put txt = x=comma20.; 59 run; txt=80f8d501 x=30,800,000 NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.