Convert a variable size hex string to signed number (variable size bytes) in C#


Convert a variable size hex string to signed number (variable size bytes) in C#



C# provides the method Convert.ToUInt16("FFFF", 16)/Convert.ToInt16("FFFF", 16) to convert hex strings into unsigned and signed 16 bit integer. These methods works fine for 16/32 bit values but not so for 12 bit values.


Convert.ToUInt16("FFFF", 16)


Convert.ToInt16("FFFF", 16)



I would like to convert 3 char long hex string to signed integer. How could I do it? I would prefer a solution that could take the number of character as parameter to decide signed values.



Convert(string hexString, int fromBase, int size)


Convert(string hexString, int fromBase, int size)



Convert("FFF", 16, 12) return -1.


Convert("FFF", 16, 12)


-1



Convert("FFFF", 16, 16) return -1.


Convert("FFFF", 16, 16)


-1



Convert("FFF", 16, 16) return 4095.


Convert("FFF", 16, 16)


4095





One of the examples here might help: docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/…
– Jeremy Thompson
2 days ago





That parameter 16 is not the number of bits in the result, but the base in the supplied string. When you use 12 there, "F" is not a valid base-12 number
– Hans Kesting
2 days ago





@HansKesting: Look at the function signature in the question, OP clearly knows the differences between the base and the number of result bits, because he made two separate parameters.
– Ben Voigt
2 days ago




2 Answers
2



The easiest way I can think of converting 12 bit signed hex to a signed integer is as follows:


string value = "FFF";
int convertedValue = (Convert.ToInt32(value, 16) << 20) >> 20; // -1



The idea is to shift the result as far left as possible so that the negative bits line up, then shift right again to the original position. This works because a "signed shift right" operation keeps the negative bit in place.



You can generalize this into a method as follows:


int Convert(string value, int fromBase, int bits)
{
int bitsToShift = 32 - bits;
return (Convert.ToInt32(value, fromBase) << bitsToShift) >> bitsToShift;
}



You can cast the result to a short if you want a 16 bit value when working with 12 bit hex strings. Performance of this method will be the same as a 16 bit version because bit shift operators on short cast the values to int anyway and this gives you more flexibility to specify more than 16 bits if needed without writing another method.


short


short


int





Rather than string concatenation (which only works for integral hex digits / multiples of 4 bits anyway), it's far more efficient to left-shift, cast, then right-shift.
– Ben Voigt
2 days ago





Not sure what you mean by the first part (integral digits / multiples of 4) but good point about string, answer updated.
– Mike Marynowski
2 days ago





I just meant that if you happened to have an input that represented a 21 bit number (0x000000 - 0x1FFFFF), there would be no way to line up the sign bit using string manipulation. With bitwise shift operators, it's easy to move the sign 11 bits.
– Ben Voigt
2 days ago


0x000000


0x1FFFFF



Ah, you'd like to calculate the Two's Complement for a certain number of bits (12 in your case, but really it should work with anything).



Here's the code in C#, blatantly stolen from the Python example in the wiki article:


int Convert(string hexString, int fromBase, int num_bits)
{
var i = System.Convert.ToUInt16(hexString, fromBase);
var mask = 1 << (num_bits - 1);
return (-(i & mask) + (i & ~mask));
}


Convert("FFF", 16, 12)


-1


Convert("4095", 10, 12)


-1





both solution works, up-voting both answers.
– resp78
2 days ago







By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

how to run turtle graphics in Colaboratory

Export result set on Dbeaver to CSV