Converting 2 bytes to signed int - c#

Is their any way to convert 2 bytes to signed int? I know we can convert a byte to signed int in following way
byte B1= 0xFF;
int r = Convert.ToSbyte((sbyte)B1);
but what about 2 bytes to signed int? For example -260 is 0xFC, 0xFE

Assuming the first byte is the msb:
byte b1 = 0xff;
byte b2 = 0xff;
var test = BitConverter.ToInt16(new byte[] { b1, b2 }, 0);
Otherwise:
byte b1 = 0xff;
byte b2 = 0xff;
var test = BitConverter.ToInt16(new byte[] { b2, b1 }, 0);
Edit: "signed"

In case of one byte, just assign:
byte B1 = 0xFF;
int r = B1;
In case of two bytes - add shift and assign:
byte B1 = 0xFE;
byte B2 = 0xFC;
int r = (B1 << 8) | B2;
in case Int16 is wanted then cast:
// -260
short s = unchecked((short) ((B1 << 8) | B2));

Take a look at BitConverter class and its ToInt32() method.

Related

How do I add 3 bytes and return an integer number?

Lets assume that I have a hex string of
00 00 04 01 11 00 08 00 06 C2 C1 BC
With this the 7th, 8th, and 9th octet are a number I need to generate. The hex is
00 06 C2
This number turns out to be 1730. With the following, how can I simplify this?
byte b1 = 0x00;
byte b2 = 0x06;
byte b3 = 0xC2;
Console.WriteLine(Convert.ToInt32((Convert.ToString(b1, 16)) + (Convert.ToString(b2, 16)) + (Convert.ToString(b3, 16)), 16));
I know there has to be a simpler way. I tried Console.WriteLine((b1 + b2 + b3).ToString()); but it doesn't work.
Try:
int result = b3 | (b2 << 8) | (b1 << 16);
Assuming that b1, b2 and b3 are the byte values that you need to convert.
The << operator shifts its operand left by the specified number of bits.
You can use the BitConverter class to convert an array of bytes to an int.
// Add the bytes to an array, starting with b3, then b2, b1 and 0 to
// make it 4 bytes in total.
byte[] b = new byte[] { 0xC2, 0x06, 0x00, 0x00 };
int i = BitConverter.ToInt32(b, 0);
i will now have the value 1730.
You can try this:
byte b1 = (byte)0x00;
byte b2 = (byte)0x06;
byte b3 = (byte)0xC2;
int i = ((b1 & 0xFF) << 16) | ((b2 & 0xFF) << 8) | (b3 & 0xFF);
EDIT:
byte b1 = (byte)0x00;
byte b2 = (byte)0x06;
byte b3 = (byte)0xC2;
int i = (b1 << 16) | (b2 << 8) | b3;

Convert a signed int to two unsigned short for purpose of reconstruction

I am currently using BitConverter to package two unsigned shorts inside a signed int. This code executes millions of times for different values and I am thinking the code could be optimized further. Here is what I am currently doing -- you can assume the code is C#/NET.
// to two unsigned shorts from one signed int:
int xy = 343423;
byte[] bytes = BitConverter.GetBytes(xy);
ushort m_X = BitConverter.ToUInt16(bytes, 0);
ushort m_Y = BitConverter.ToUInt16(bytes, 2);
// convet two unsigned shorts to one signed int
byte[] xBytes = BitConverter.GetBytes(m_X);
byte[] yBytes = BitConverter.GetBytes(m_Y);
byte[] bytes = new byte[] {
xBytes[0],
xBytes[1],
yBytes[0],
yBytes[1],
};
return BitConverter.ToInt32(bytes, 0);
So it occurs to me that I can avoid the overhead of constructing arrays if I bitshift. But for the life of me I can't figure out what the correct shift operation is. My first pathetic attempt involved the following code:
int xy = 343423;
const int mask = 0x00000000;
byte b1, b2, b3, b4;
b1 = (byte)((xy >> 24));
b2 = (byte)((xy >> 16));
b3 = (byte)((xy >> 8) & mask);
b4 = (byte)(xy & mask);
ushort m_X = (ushort)((xy << b4) | (xy << b3));
ushort m_Y = (ushort)((xy << b2) | (xy << b1));
Could someone help me? I am thinking I need to mask the upper and lower bytes before shifting. Some of the examples I see include subtraction with type.MaxValue or an arbitrary number, like negative twelve, which is pretty confusing.
** Update **
Thank you for the great answers. Here are the results of a benchmark test:
// 34ms for bit shift with 10M operations
// 959ms for BitConverter with 10M operations
static void Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
for (int i = 0; i < 10000000; i++)
{
ushort x = (ushort)i;
ushort y = (ushort)(i >> 16);
int result = (y << 16) | x;
}
stopWatch.Stop();
Console.WriteLine((int)stopWatch.Elapsed.TotalMilliseconds + "ms");
stopWatch.Start();
for (int i = 0; i < 10000000; i++)
{
byte[] bytes = BitConverter.GetBytes(i);
ushort x = BitConverter.ToUInt16(bytes, 0);
ushort y = BitConverter.ToUInt16(bytes, 2);
byte[] xBytes = BitConverter.GetBytes(x);
byte[] yBytes = BitConverter.GetBytes(y);
bytes = new byte[] {
xBytes[0],
xBytes[1],
yBytes[0],
yBytes[1],
};
int result = BitConverter.ToInt32(bytes, 0);
}
stopWatch.Stop();
Console.WriteLine((int)stopWatch.Elapsed.TotalMilliseconds + "ms");
Console.ReadKey();
}
The simplest way is to do it using two shifts:
int xy = -123456;
// Split...
ushort m_X = (ushort) xy;
ushort m_Y = (ushort)(xy>>16);
// Convert back...
int back = (m_Y << 16) | m_X;
Demo on ideone: link.
int xy = 343423;
ushort low = (ushort)(xy & 0x0000ffff);
ushort high = (ushort)((xy & 0xffff0000) >> 16);
int xxyy = low + (((int)high) << 16);

How do I use C# to convert int to bytes that only use the low 4 bits?

I have a conversion problem in C#. Basically, I'm trying to convert an integer to bytes so that we only use the low 4 bits. Example 255 = 0F 0F or:
0xpqrs = 0p 0q 0r 0s
5*16*16*16 + 1*16*16 + 15*16 + 1 = 05 01 0f 01
How do I implement this in C#?
int => bytes:
int value = 0x51f1;
byte s = (byte)(value & 0xf);
byte r = (byte)(value>>4 & 0xf);
byte q = (byte)(value>>8 & 0xf);
byte p = (byte)(value>>12 & 0xf);
bytes => int:
int value = p<<12 | q<<8 | r<<4 | s;
Lucero's answer modified to work in a loop with longer integers.
public static byte[] intToBytesV2(ulong l)
{
byte[] theBytes = new byte[8];
for (int i = 0; i < 8; i++) {
theBytes[i] = (byte)(l >> (i * 4) & 0xf);
}
return theBytes;
}
pom =)
byte[] bArray=System.BitConverter.GetBytes(i);

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);.

Alternative to BitConverter.ToInt32

I'm using BitConverter.ToInt32 to pack 3 byte values into an int, like so:
byte R = 0;
byte G = 0;
byte B = 0;
int i = BitConverter.ToInt32(new byte[] { R, G, B, 0 }, 0);
Is there a faster way to do this that doesn't involve the creation of a new int each time? Getting the bytes out of an int is easy:
int i = 34234;
byte B = (byte)(i >> 0);
byte G = (byte)(i >> 8);
byte R = (byte)(i >> 16);
Is there a simple way to reverse this process and use bit-shifting to write the RGB bytes back over an existing int?
int i = (B << 0) | (G << 8) | (R << 16);
You ought to consider the Color structure. It has R, G and B properties and FromArgb() and ToArgb() methods.

Categories

Resources