07-10-2013 08:51 AM
I need to check the value of the first byte from a HEX4 format field.
The value of the first observation is: 6EA0.
I've tried assiging the field to a defined character field in a data step and checking the substr(*,1,1) and various other ways with no success.
07-10-2013 09:28 AM
Thanks for the example. I can reference the first byte of the HEX field, but I need to check the first character. I know how to accomplish this in COBOL or Assembler, just don't know how to do it in SAS. Sorry, should have made myself a little clearer.
I need to check the first character to see if it's a numeric 6 to assign another field a value:
IF X1 =: '06'X THEN X2 = 'A';
I'm not 100% clear on how SAS is storing this value. I see the format in the storing pdb is HEX4, but it seems SAS is treating the value as character (which is baffling me).
07-10-2013 09:52 AM
SAS lets you store hex strings as either character or numeric. The way you refer to them depends on how they are stored. Either of these is permissible:
hex_num = 6EA0x;
hex_char = '6EA0'x;
HEX_NUM would be stored in SAS's usual numeric format, so you could check it with:
if put(hex_num, hex4.) =: '06' then X2='A';
HEX_CHAR would be stored as the two-byte character equivalent of 6E A0, so you could check it with:
if put(hex_char, $hex4.) =: '06' then X2='A';
07-10-2013 11:22 AM
I totally agree with you and I believe that your numeric example should be working, but it doesn't.
This is my exact code (latest I've tried). DEVNR is type=num len=5 format=HEX4:
IF PUT(DEVNR,HEX4.) = 06X THEN DEVTYPE='V';
My education/training tells me that the actual DEVNR field should look like '06EA0F', a 3 byte length field. When I list the variable, it shows a 4 numeric ( I assume) length field in the listing. Is SAS maybe padding this field with zeros? Is it NOT storing it as a true HEX compressed field? Or am I totally way off base here?
07-10-2013 11:42 AM
A couple of factors are at work here.
First, there is no special storage format in SAS for numeric hex values. All numerics get stored in the same floating point format, and all can be expressed in hex format. For example, you could try:
value = 255;
put value hex2.;
put value hex3.;
put value hex4.;
Second, the PUT function always returns a character string. It doesn't matter whether the first argument is character or numeric, the result is always an expression of a value in a format which means a character string. You could try (and then run PROC PRINT / PROC CONTENTS):
result = put(year, z4.);
So if DEVNR is a numeric, how it was created doesn't really matter. It gets stored in the same format internally no matter what. If it was generated by reading in a character string from hex, you could test it this way:
*devnr = 06AAx;
if put(devnr, hex4.) =: '06' then devtype='V';
I think I've answered your questions, but feel free to ask again if this needs more detail.
07-10-2013 10:36 AM
Sounds like you are talking about a number and not a character string. Otherwise SAS would have complained if you tried to use the numeric format HEX. instead of the character format $HEX.
You want to test the digit in a specific place then you could apply some arithmetic to the problem. For example to test the digit in the 100ths place :
if mod(int(x/100),10) = 6 then ...
If instead you want to test the most significant digit irrespective of magnitude it might be easiest to convert it to a character string using put functions.
if left(put(x,10)) =: '6' then ...