I want to take the first 4 bits of one byte and all bits of another bit and append them to eachother.
This is the result I need to achieve:
This is what I have now:
private void ParseLocation(int UpperLogicalLocation, int UnderLogicalLocation)
{
int LogicalLocation = UpperLogicalLocation & 0x0F; // Take bit 0-3
LogicalLocation += UnderLogicalLocation;
}
But this is not giving the right results.
int UpperLogicalLocation_Offset = 0x51;
int UnderLogicalLocation = 0x23;
int LogicalLocation = UpperLogicalLocation & 0x0F; // Take bit 0-3
LogicalLocation += UnderLogicalLocation;
Console.Write(LogicalLocation);
This should give 0x51(01010001) + 0x23 (00100011),
So the result I want to achieve is 0001 + 00100011 = 000100100011 (0x123)
You will need to left-shift the UpperLogicalLocation bits by 8 before combining the bits:
int UpperLogicalLocation = 0x51;
int UnderLogicalLocation = 0x23;
int LogicalLocation = (UpperLogicalLocation & 0x0F) << 8; // Take bit 0-3 and shift
LogicalLocation |= UnderLogicalLocation;
Console.WriteLine(LogicalLocation.ToString("x"));
Note that I also changed += to |= to better express what is happening.
The problem is that you're storing the upper bits into bits 0-3 of LogicalLocation instead of bits 8-11. You need to shift the bits into the right place. The following change should fix the problem:
int LogicalLocation = (UpperLogicalLocation & 0x0F) << 8;
Also note that the bits are more idiomatically combined using the logical-or operator. So your second line becomes:
LogicalLocation |= UnderLogicalLocation;
You can do this:
int LogicalLocation = (UpperLogicalLocation & 0x0F) << 8; // Take bit 0-3
LogicalLocation |= (UnderLogicalLocation & 0xFF);
...but be careful about endianness! Your documentation says UpperLogicalLocation should be stored in Byte 3, the next 8 bits in Byte 4. Do achieve this, the resulting int LogicalLocation needs to be split into these two bytes correctly.
Related
So I've come across a strange need to 'merge' two numbers:
byte one;
byte two;
into an int three; with the first bit being the first bit of one, the second bit being the first bit of two, the third being the second bit of one and so on.
So with these two numbers:
01001000
00010001
would result in
0001001001000010
A more didatic illustration of the interlacing operation:
byte one = 0 1 0 0 1 0 0 0
byte two = 0 0 0 1 0 0 0 1
result = 00 01 00 10 01 00 00 10
UPDATE: Sorry misread your question completely.
The following code should do:
public static int InterlacedMerge(byte low, byte high)
{
var result = 0;
for (var offset = 0; offset < 8; offset++)
{
var mask = 1 << offset;
result |= ((low & mask) | ((high & mask)) << 1) << offset;
}
return result;
}
I am not, by any means, very smart when it comes to bit twiddling so there probably is a more efficient way to do this. That said, I think this will do the job but I haven't tested it, so make sure you do.
P.D: There are some unnecessary parenthesis in the code but I'm never sure about bitwise operators precedence so I find it easier to read the way its written.
UPDATE2: Here is the same code a little more verbose to make it easier to follow:
public static int InterlacedMerge(byte low, byte high)
{
var result = 0;
for (var offset = 0; offset < 8; offset++)
{
//Creates a mask with the current bit set to one: 00000001,
//00000010, 00000100, and so on...
var mask = 1 << offset;
//Creates a number with the current bit set to low's bit value.
//All other bits are 0
var lowAndMask = low & mask;
//Creates a number with the current bit set to high's bit value.
//All other bits are 0
var highAndMask = high & mask;
//Create a merged pair where the lowest bit is the low 's bit value
//and the highest bit is high's bit value.
var mergedPair = lowAndMask | (highAndMask << 1);
//Ors the mergedPair into the result shifted left offset times
//Because we are merging two bits at a time, we need to
//shift 1 additional time for each preceding bit.
result |= mergedPair << offset;
}
return result;
}
#inbetween answered while I was writing this; similar solution, different phrasing.
You'll have to write a loop. You'll test one bit in each of the two inputs. You'll set a bit in an output for each input. You'll shift all three values one place. Maybe something like this (untested):
#define TOPBIT 32768
for /* 16 times */
if ( value1 & 1 ) out |= TOPBIT;
out >>= 1;
if ( value2 & 1 ) out |= TOPBIT;
out >>= 1;
b1 >>= 1;
b2 >>= 1;
I am trying to find a way to remove a bit from an integer. The solution must not use string operations.
For example, I have the number 27, which is 11011 in binary.
I want to remove the third bit so it leaves me with 1011.
Or we have 182 (10110110), remove the 6th bit so the result is 1110110 (which is 118). I am trying to think of the algorithm how to do that, but so far no luck, and I can't find useful information on the internet.
I know how to use bitwise operators and how to extract or manipulate bits in integers (change values, exchange values etc), but I don't know how to 'remove' a certain bit.
I am not looking for code, just the logic of the operation. If anyone could help me, that would be awesome!
Regards,
Toni
No problem, just decompose the number into the "upper part" and the "lower part", and put them together without the middle bit that now disappeared.
Not tested:
uint upper = x & 0xFFFFFFF0;
uint lower = x & 7;
return (upper >> 1) | lower;
More generally: (also not tested)
uint upper = x & (0xFFFFFFFE << n);
uint lower = x & ((1u << n) - 1);
return (upper >> 1) | lower;
In order to do this you need two bit masks and a shift.
The first bit mask gives you the portion of the number above bit n, exclusive of the n-th bit. The mask is constructed as follows:
var top = ~((1U<<(n+1))-1); // 1111 1111 1000 000, 0xFF80
The second bit mask gives you the portion of the number below bit n, exclusive of the n-th bit:
var bottom = (1U<<n)-1; // 0000 0000 0011 1111, 0x003F
Comments above show the values for your second example (i.e. n == 6)
With the two masks in hand, you can construct the result as follows:
var res = ((original & top)>>1) | (original & bottom);
Demo.
You could use the following approach:
int value = 27;
string binary = Convert.ToString(value, 2);
binary = binary.Remove(binary.Length-3-1,1); //Remove the exact bit, 3rd in this case
int newValue = Convert.ToInt32(binary, 2);
Console.WriteLine(newValue);
Hope it helps!
int Place = 7;
int TheInt = 182;
string binary = Convert.ToString(TheInt, 2);
MessageBox.Show(binary.Remove(binary.Length - Place, 1));
Here is a version that needs slightly fewer operations than the solution by harold:
x ^ (((x >> 1) ^ x) & (0xffffffff << n));
The idea is that below n, bits are xored with zero, leaving them unchanged, while from n and above the two x xored cancel each other out, leaving x >> 1.
int a = 27;//int= 4byte equal to 32 bit
string binary = "";
for (int i = 0; i < 32; i++)
{
if ((a&1)==0)//if a's least significant bit is 0 ,add 0 to str
{
binary = "0" + binary;
}
else//if a's least significant bit is 1 ,add 1 to str
{
binary = "1" + binary;
}
a = a >> 1;//shift the bits left to right and delete lsb
//we are doing it for 32 times because integer have 32 bit.
}
Console.WriteLine("Integer to Binary= "+binary);
//Now you can operate the string(binary) however you want.
binary = binary.Remove(binary.Length-4,1);//remove 4st bit from str
I am trying to write a swap function in C# to mimic the one in Delphi. According to the documentation the one in Delphi will do the following:
If the number is two bytes, bytes 1 and 2 are swapped
if the number is four bytes, bytes 1 and 4 are swapped, bytes 2 and 3 remain where they are
Below is the code I have.
int number = 17665024;
var hi = (byte)(number >> 24);
var lo = (byte)(number & 0xff);
return (number & 0x00FFFF00) + (lo & 0xFF000000) + (hi & 0x000000FF);
Some numbers seem to return what I expect, but most do not.
// Value in // Expected // Actual
17665024 887809 887809
5376 21 5376
-30720 136 16746751
3328 13 3328
It's probably a fairly obvious mistake to most, but I haven't dealt with bitwise shift operators much and I cannot seem to work out what I have done wrong.
Thanks in advance.
In C#, the data types short and int correspond to integral data types of 2 bytes and 4 bytes, respectively. The algorithm above applies to int (4 bytes).
This algorithm contains an error: (lo & 0xFF000000) will always return 0 because lo is a byte. What you probably intended was lo << 24, which shifts lo 24 bytes to the left.
For an int data type, the proper function then becomes:
int SwapInt(int number)
{
var hi = (byte)(number >> 24);
var lo = (byte)(number & 0xff);
return ((number & 0xffff00) | (lo << 24) | hi);
}
For a short data type, the middle term disappears and we are left with simply:
short SwapShort(short number)
{
var hi = (byte)(number >> 8);
var lo = (byte)(number & 0xff);
return (short)((lo << 8) | hi);
}
Then Swap((short)5376) returns the expected value of 21. Note that Swap(5376) will use the default int datatype for 5376, which returns 5376. To treat integers that can be wholly expressed in two bytes as short, you can run:
int Swap(int n)
{
if (n >= Short.MinValue && n <= Short.MaxValue)
return SwapShort((short)n);
else
return SwapInt(n);
}
I'm trying to debug some bit shifting operations and I need to visualize the bits as they exist before and after a Bit-Shifting operation.
I read from this answer that I may need to handle backfill from the shifting, but I'm not sure what that means.
I think that by asking this question (how do I print the bits in a int) I can figure out what the backfill is, and perhaps some other questions I have.
Here is my sample code so far.
static string GetBits(int num)
{
StringBuilder sb = new StringBuilder();
uint bits = (uint)num;
while (bits!=0)
{
bits >>= 1;
isBitSet = // somehow do an | operation on the first bit.
// I'm unsure if it's possible to handle different data types here
// or if unsafe code and a PTR is needed
if (isBitSet)
sb.Append("1");
else
sb.Append("0");
}
}
Convert.ToString(56,2).PadLeft(8,'0') returns "00111000"
This is for a byte, works for int also, just increase the numbers
To test if the last bit is set you could use:
isBitSet = ((bits & 1) == 1);
But you should do so before shifting right (not after), otherwise you's missing the first bit:
isBitSet = ((bits & 1) == 1);
bits = bits >> 1;
But a better option would be to use the static methods of the BitConverter class to get the actual bytes used to represent the number in memory into a byte array. The advantage (or disadvantage depending on your needs) of this method is that this reflects the endianness of the machine running the code.
byte[] bytes = BitConverter.GetBytes(num);
int bitPos = 0;
while(bitPos < 8 * bytes.Length)
{
int byteIndex = bitPos / 8;
int offset = bitPos % 8;
bool isSet = (bytes[byteIndex] & (1 << offset)) != 0;
// isSet = [True] if the bit at bitPos is set, false otherwise
bitPos++;
}
I have a devious little problem to which I think I've come up with a solution far more difficult than needs to be.
The problem is that I have two bytes. The first two bits of the first byte are to be removed (as the value is little endian, these bits are effectively in the middle of the 16 bit value). Then the least significant two bits of the second byte are to be moved to the most significant bit locations of the first byte, in place of the removed bits.
My solution is as follows:
byte firstByte = (byte)stream.ReadByte(); // 01000100
byte secondByte = (byte)stream.ReadByte(); // 00010010
// the first and second byte equal the decimal 4676 in this little endian example
byte remainderOfFirstByte = (byte)(firstByte & 63); // 01000100 & 00111111 = 00000100
byte transferredBits = (byte)(secondByte << 6); // 00010010 << 6 = 10000000
byte remainderOfSecondByte = (byte)(secondByte >> 2); // 00010010 >> 2 = 00000100
byte newFirstByte = (byte)(transferredBits | remainderOfFirstByte); // 10000000 | 00000100 = 10000100
int result = BitConverter.ToInt32(new byte[]{newFirstByte, remainderOfSecondByte, 0, 0}, 0); //10000100 00010000 (the result is decimal 1156)
Is there an easier way* to achieve this?
*less verbose, perhaps an inbuilt function or trick I'm missing? (with the exception of doing both the & and << on the same line)
You don't have to mask out bits that a shift would throw away anyway. And you don't have to transfer those bits manually. So it becomes this: (not tested)
int result = (secondByte << 6) | (firstByte & 0x3F);