C# Convert Int To Two Hex Bytes? - c#

I have an integer that I need to convert to a four digit hex value.
For example, lets say the int value is 16. What I am looking for is a way to go from 16 to
0x00 0x10.
Any suggestions would be greatly appreciated!!!

Try this:
var input = 16;
var bytes = new byte[2];
bytes[0] = (byte)(input >> 8); // 0x00
bytes[1] = (byte)input; // 0x10
var result = (bytes[0] << 8)
| bytes[1];
// result == 16

Here's one with regular expressions, just for fun:
Regex.Replace(number.ToString("X4"), "..", "0x$0 ").TrimEnd();

Alternately, a little more general solution is to do it by byte array (then you can use this for strings or other data types)
public static string ByteArrayToString(byte[] ba)
{
string hex = BitConverter.ToString(ba);
return hex.Replace("-","");
}
int i = 39;
string str = "ssifm";
long l = 93823;
string hexi = ByteArrayToString(BitConverter.GetBytes(i));
string hexstr = ByteArrayToString(Encoding.Ascii.GetBytes(str));
string hexl = ByteArrayToString(BitConverter.GetBytes(l));
This returns them in a 'FF' format, you can add the '0x' yourself by adding this after the ToString() instead:
return "0x"+hex.Replace("-", " 0x");

Shift it! Mask it! Mask it! string.Format it!
int n = 16;
string.Format("0x{0:x2} 0x{1:x2}", (n & 0xff00) >> 8, n & 0xff); // 0x00 0x10
Here's a demo.
The x2 format specifier means a 2-digit hexadecimal value.
Okay, apparently you just want two bytes. Hexadecimal is not relevant here.
byte lowByte = (byte)(n & 0xff);
byte highByte = (byte)(n >> 8 & 0xff);

Related

Convert byte[3] to byte[2] in C#

I currently have a list of byte arrays with 3 bytes in it. This array needs to be converted to a byte array with 2 bytes, and the range should be scaled so the values fit inside 2 bytes.
It is okay to loose some precision as long as the values are all scaled with the same amount.
In general, you could go about converting bytes to integers and back to bytes as follows:
var input = new byte [] { 0x45, 0x67, 0x89 };
// Depending on byte order, use either the first or second conversion
var converted1 = ((int)input[0] << 16) | ((int)input[1] << 8) |
(int)input[2];
var converted2 = ((int)input[2] << 16) | ((int)input[1] << 8) |
(int)input[0];
// Not sure what kind of scaling you want, here I just shift right
var scaled1 = converted1 >> 8;
var scaled2 = converted2 >> 8;
// Convert back to a byte array
var output1 = new byte [] { (byte)(scaled1 >> 8), (byte)(scaled1 & 0xff) };
var output2 = new byte [] { (byte)(scaled2 & 0xff), (byte)(scaled2 >> 8) };
Hope it helps!
EDIT: changed bitwise AND to OR in converted1 and converted2. Thanks to #AleksAndreev for pointing out my error!

Convert int to byte as HEX in C#

I need to send a Hex string over the serial to a device, I do that now like this:
byte[] c = new byte[3];
c[0] = 0x57;
c[1] = 0x30;
ComPort.Write(c,0,c.Length );
Now I need to convert a value of int like 30 to c[1] = 0x30 or a int value of 34 gives c[1] = 0x34.
I hope you see what I mean.
So how can I mange this?
This format is called binary-coded decimal. For two-digit numbers, integer-divide by ten and multiply by sixteen, then add back the remainder of the division by ten:
int num = 45;
int bcdNum = 16*(num/10)+(num%10);
Another way to do this could be
c[1] = Convert.ToByte(num.ToString(), 16);
suppose int Data=2821; was to send over COM Port:
c[0]= Convert.ToByte(data & 0x00FF);
c[0]= Convert.ToByte(data & 0xFF00) >> 8);
ComPort.Write(c,0,c.Length );
int num = 1366;
string bcdNum = num.ToString("X");
if (bcdNum.Length < 2)
bcdNum = "0" + bcdNum;
byte[] bytes_str=Enumerable.Range(0, bcdNum.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(bcdNum.Substring(x, 2), 16)).ToArray();

Converting 3 bytes into signed integer in C#

I'm trying to convert 3 bytes to signed integer (Big-endian) in C#.
I've tried to use BitConverter.ToInt32 method, but my problem is what value should have the lats byte.
Can anybody suggest me how can I do it in different way?
I also need to convert 5 (or 6 or 7) bytes to signed long, is there any general rule how to do it?
Thanks in advance for any help.
As a last resort you could always shift+add yourself:
byte b1, b2, b3;
int r = b1 << 16 | b2 << 8 | b3;
Just swap b1/b2/b3 until you have the desired result.
On second thought, this will never produce negative values.
What result do you want when the msb >= 0x80 ?
Part 2, brute force sign extension:
private static int Bytes2Int(byte b1, byte b2, byte b3)
{
int r = 0;
byte b0 = 0xff;
if ((b1 & 0x80) != 0) r |= b0 << 24;
r |= b1 << 16;
r |= b2 << 8;
r |= b3;
return r;
}
I've tested this with:
byte[] bytes = BitConverter.GetBytes(p);
int r = Bytes2Int(bytes[2], bytes[1], bytes[0]);
Console.WriteLine("{0} == {1}", p, r);
for several p.
The last value should be 0 if it isn't set for a positive number, 256 for a negative.
To know what you should pass in, you can try converting it the other way:
var bytes = BitConverter.GetBytes(i);
int x = BitConverter.ToInt32(bytes, 0);
To add to the existing answers here, there's a bit of a gotcha in that Bitconverter.ToInt32() will throw an ArgumentException if the array is less than sizseof(int) (4) bytes in size;
Destination array is not long enough to copy all the items in the collection. Check array index and length.
Given an array less than sizeof(int) (4) bytes in size, you can compensate for left/right padding like so;
Right-pad
Results in positive Int32 numbers
int intByteSize = sizeof(int);
byte[] padded = new byte[intByteSize];
Array.Copy(sourceBytes, 0, padded, 0, sourceBytes.Length);
sourceBytes = padded;
Left-pad
Results in negative Int32 numbers, assuming non-zero value at byte index sourceBytes.Length - 1.
int intByteSize = sizeof(int);
byte[] padded = new byte[intByteSize];
Array.Copy(sourceBytes, 0, padded, intByteSize - sourceBytes.Length, sourceBytes.Length);
sourceBytes = padded;
Once padded, you can safely call int myValue = BitConverter.ToInt32(sourceBytes, 0);.

Perform signed arithmetic on numbers defined as bit ranges of unsigned bytes

I have two bytes. I need to turn them into two integers where the first 12 bits make one int and the last 4 make the other. I figure i can && the 2nd byte with 0x0f to get the 4 bits, but I'm not sure how to make that into a byte with the correct sign.
update:
just to clarify I have 2 bytes
byte1 = 0xab
byte2 = 0xcd
and I need to do something like this with it
var value = 0xabc * 10 ^ 0xd;
sorry for the confusion.
thanks for all of the help.
int a = 10;
int a1 = a&0x000F;
int a2 = a&0xFFF0;
try to use this code
For kicks:
public static partial class Levitate
{
public static Tuple<int, int> UnPack(this int value)
{
uint sign = (uint)value & 0x80000000;
int small = ((int)sign >> 28) | (value & 0x0F);
int big = value & 0xFFF0;
return new Tuple<int, int>(small, big);
}
}
int a = 10;
a.UnPack();
Ok, let's try this again knowing what we're shooting for. I tried the following out in VS2008 and it seems to work fine, that is, both outOne and outTwo = -1 at the end. Is that what you're looking for?
byte b1 = 0xff;
byte b2 = 0xff;
ushort total = (ushort)((b1 << 8) + b2);
short outOne = (short)((short)(total & 0xFFF0) >> 4);
sbyte outTwo = (sbyte)((sbyte)((total & 0xF) << 4) >> 4);
Assuming you have the following to bytes:
byte a = 0xab;
byte b = 0xcd;
and consider 0xab the first 8 bits and 0xcd the second 8 bits, or 0xabc the first 12 bits and 0xd the last four bits. Then you can get the these bits as follows;
int x = (a << 4) | (b >> 4); // x == 0x0abc
int y = b & 0x0f; // y == 0x000d
edited to take into account clarification of "signing" rules:
public void unpack( byte[] octets , out int hiNibbles , out int loNibble )
{
if ( octets == null ) throw new ArgumentNullException("octets");
if ( octets.Length != 2 ) throw new ArgumentException("octets") ;
int value = (int) BitConverter.ToInt16( octets , 0 ) ;
// since the value is signed, right shifts sign-extend
hiNibbles = value >> 4 ;
loNibble = ( value << 28 ) >> 28 ;
return ;
}

How do I convert hex string into signed integer?

I'm getting a hex string that needs to be converted to a signed 8-bit integer. Currently I'm converting using Int16/Int32, which will obviously not give me a negative value for an 8-bit integer. If I get the value 255 in Hex, how do I convert that to -1 in decimal? I assume I want to use an sbyte, but I'm not sure how to get that value in there properly.
You can use Convert.ToSByte
For example:
string x = "aa";
sbyte v = Convert.ToSByte(x, 16);
// result: v = 0xAA or -86
You can also use sbyte.Parse
For example:
string y = "bb";
sbyte w = sbyte.Parse(y, System.Globalization.NumberStyles.HexNumber);
// result: w = 0xBB or -69
To answer your question about the upper or lower byte of an Int16:
string signed_short = "feff";
// Truncate 16 bit value down to 8 bit
sbyte b1 = (sbyte)Convert.ToInt16(signed_short, 16);
sbyte b2 = (sbyte)short.Parse(signed_short, System.Globalization.NumberStyles.HexNumber);
// result: b1 = 0xFF or -1
// result: b2 = 0xFF or -1
// Use upper 8 bit of 16 bit
sbyte b3 = (sbyte)(Convert.ToInt16(signed_short, 16) >> 8);
sbyte b4 = (sbyte)(short.Parse(signed_short, System.Globalization.NumberStyles.HexNumber) >> 8);
// result: b3 = 0xFE or -2
// result: b4 = 0xFE or -2
You need to perform an unchecked cast, like this:
sbyte negativeOne = unchecked((sbyte)255);
My solution was to put the first take the first 8 bits of the 16 bit integer and store them in an sbyte.

Categories

Resources