BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
k_shide
Obsidian | Level 7

Hi I have a SAS character column called Hexchar contains hexadecimal character "0x1ba0c56c966ee8b0000" This is actually 8154350000000000000000 in decimal number. And I want to convert "0x1ba0c56c966ee8b0000" to 8154350000000000000000. If the hexadecimal is less than 16 bytes then the following function does the job.

 

 

DexNumber=input(substr(Hexchar,3), hex16.); 
/* The reason why substr() function is to skip "0x" in the front */

However hex format is limited only to 16 bytes and not handle more bytes. Do you know any good logic to convert this?

1 ACCEPTED SOLUTION

Accepted Solutions
k_shide
Obsidian | Level 7

Hi Kurt,

 

Thank you very much. I do understand what you mean by 8byte and so as IEEE754. Been there done that too.

Just wanted to achieve exactly what I wrote with minimum code. Mine logic is as follows.  I think the approach is exactly equal but bit of code required so may wanted to have better answer from someone already been through same issues. pibbed it to 24bit (filled with zeros in front) by using do while and decimaling it by 8 bits each. It's actually decoded data from major Crypt blockchain and now so many bytes of hexadecimals everywhere. Found tough even for SAS or other DB experts to handle it.

 

length dum_s $24.;
dum_s=substr(s_value,3);

    do while(length(dum_s)<24);
	    dum_s="0"||dum_s;
    end;
		dum_dec1=input(substr(dum_s,1,8),hex8.);
		dum_dec2=input(substr(dum_s,9,8),hex8.);
		dum_dec3=input(substr(dum_s,17,8),hex8.);

		dum1=dum_dec1*16**16;
		dum2=dum_dec2*16**8;
		dum3=dum_dec3*16**0;
value_wei=sum(dum1,dum2,dum3);
value_ether=value_wei/(10**18);

View solution in original post

6 REPLIES 6
Kurt_Bremser
Super User

You can't input more than 16 hex characters to a number because numbers are stored in 8 bytes in SAS.

Note that SAS numbers are stored as 8-byte real, which is considerably different from int or longint.

I also noted that your hex string is 21 bytes long; an odd number of bytes for the hexadecimal representation of integers is quite unusual. Typically, the int should be stored in 8 or 16 bytes, meaning 64-bit or 128-bit processing.

One method to use:

  • remove the 0x
  • pad in front with 0's so you get a string of even length
  • input to a hex string
  • input the first 8 bytes of that string to a number with the pib. or pibr. informat
  • do the same with the remaining bytes
  • multiply the first number with a power of 2 according to the length of the second part
  • add the second number to the first

Note that you will lose precision when inputting more than 7 bytes, as that is the size of the mantissa in 8-byte real.

k_shide
Obsidian | Level 7

Hi Kurt,

 

Thank you very much. I do understand what you mean by 8byte and so as IEEE754. Been there done that too.

Just wanted to achieve exactly what I wrote with minimum code. Mine logic is as follows.  I think the approach is exactly equal but bit of code required so may wanted to have better answer from someone already been through same issues. pibbed it to 24bit (filled with zeros in front) by using do while and decimaling it by 8 bits each. It's actually decoded data from major Crypt blockchain and now so many bytes of hexadecimals everywhere. Found tough even for SAS or other DB experts to handle it.

 

length dum_s $24.;
dum_s=substr(s_value,3);

    do while(length(dum_s)<24);
	    dum_s="0"||dum_s;
    end;
		dum_dec1=input(substr(dum_s,1,8),hex8.);
		dum_dec2=input(substr(dum_s,9,8),hex8.);
		dum_dec3=input(substr(dum_s,17,8),hex8.);

		dum1=dum_dec1*16**16;
		dum2=dum_dec2*16**8;
		dum3=dum_dec3*16**0;
value_wei=sum(dum1,dum2,dum3);
value_ether=value_wei/(10**18);
Kurt_Bremser
Super User

Note that this will not give you anything usable. As soon as you have more than ~15 decimal digits, you will run out of precision, and different values will end up as the same from the 16th digit down. Which means that roughly 17 of your 24 bytes are for naught.

If you need to work with such values, keep them as hex strings (just like you do with UUID's).

k_shide
Obsidian | Level 7

Kart,

I know what you mean but when you are asked the transaction of Ethereum, I sent you "0x1ba0c56c966ee8b0000 wei to you" not meaning anything to humans. I am using WorldProgramming 64bit version. Checked 18 to 21 bytes hexas comparing with Ethereum transaction site which gives you "reasonably" close. 

 

Ethereum transaction hash 0x57662d92cb24943079dec7d83d3c39fc7a1ae958b22de58ba62c8c4cb425cab3

and it's value is in hexa basis "0x1ba0c56c966ee8b0000" and my logic above gives me 8154.35 ethereum (10**18 times to wei) which is same as the site.

https://etherscan.io/tx/0x57662d92cb24943079dec7d83d3c39fc7a1ae958b22de58ba62c8c4cb425cab3

I know it's good enough for the moment for the analysis. Luckily I am not a banker any more so it's good enough for me!

 

I want to use SAS or identical tool for transaction analysis as it's my favorite in terms of data management but if you have better solution for this, I am open for the suggestion so please help me.

 

Kurt_Bremser
Super User

If all X (for X > 16 hex) digits of an object are (or can be) significant, then you can't cram them into 8 bytes without losing information.

If the first 64 bits are everything you need, you can store them in a SAS number, but don't expect the number to be readable, as part of the information will end up in the exponent.

Putting any information into a SAS number only makes sense if you need to do arithmetic with it; if it's just an identification value, strings are the tool of choice.

k_shide
Obsidian | Level 7

Yes. this is exactly for the arithmetic analysis like one address make how many transactions and average transaction values etc.

Blockchain does not need arithmetic so fine with hexadecimal characters to store those information. 

So what I have to compromise is the precision after 64bits.

I am not sure if there are another decimal emulator tools or machines which does exactly what I want without loosing any information but with my current favorite tools this is the maximum I can do. 

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 6188 views
  • 2 likes
  • 2 in conversation