How can I switch the certain bits of a number? For example, given bit representation (just an example, the syntax is surely wrong!):
someNumber = 00110111
changeNumber = 11100110
Then how can I change the far right bit of someNumber with the far right bit of the changeNumber without changing the rest bits of the someNumber? So the result would be:
00110111 //someNumber
11100110 //changeNumber
________
00110110
Extract the far right bit of changeNumber:
changeNumber & 1
Remove the far right bit of someNumber:
someNumber & ~1
And OR them together:
(changeNumber & 1) | (someNumber & ~1)
To set bit n, change 1 to 2n.
One a similar line as Martin,
Test the last bit of someNumber, and use the result to select the operation to change some number ('bitwise and' or 'bitwise or')
#DEFINE SWITCH_MASK_OR 0b00000001
#DEFINE SWITCH_MASK_AND (~SWITCH_MASK_OR)
...
result = changeNumber & SWITCH_MASK_OR ? \
someNumber | SWITCH_MASK_OR : someNumber & SWITCH_MASK_AND;
I suggest the following steps:
Clear the last bit of someNumber.
someNumber &= ~1
Extract the last bit of changeNumber
int lastBit = changeNumber & 1;
Set the last bit of someNumber:
someNumber |= lastBit;
AND the changenumber with a mask of 00000001, so extracting the state of the lowest bit, all others set to 0: 00000000
AND the somenumber with a mask of 11111110, so setting the lowest bit to 0 while leaving the rest unchanged: 00110110
OR the two results together, so : 00110110
Related
I have seen something like this in some of my coworkers code today :
I2C1ADB1= (slave_read_address | 0x01);
What does this | 0x01 part do? Does it end 1 at the end of the bits?
Let's say I2C1ADB1=0b00000000. If I use above line, will the new I2C1ADB1 be 0b000000001? Will it also increase the bit count from 8 to 9?
'|' is bit-wise OR operator in C. It does bit-wise OR between two values and return the final value.
I2C1ADB1= (slave_read_address | 0x01);
Assume slave_read_address in binary is 0bxxxxxxxx where each x is bit value 1 or 0. Similarly, 0x01 in binary is 0x00000001.
As you know OR will return true (1) if at least one of the value is true (1). Otherwise returns false (0).
So After the above C line, I2C1ADB1 will have 0bxxxxxxx1.
The operator will not ADD bits. Usually '|' (OR) operator is used to set a particular set of bits without altering other bits.
The statement I2C1ADB1 = (slave_read_address | 0x01); stores the value of slave_read_address into I2C1ADB1, forcing the low order bit to 1.
Your interpretation is incorrect, the value is not shifted, no extra bit is appended. The lowest bit is set to 1:
0 becomes 1,
1 is unchanged,
2 becomes 3,
3 does not change,
4 becomes 5,
etc.
Because on the left you have a variable and on the right a constant the result is to set all the corresponding 1 bits from the constant in the variable. In this case you’re right: it sets the last bit. No bit count increase occur!
Suppose I have a variable inst which holds an encoded MIPS instruction. I want to set the rt field to 0 without changing the other fields. The rt field is a 5-bit field indexed from 16-20. I first tried:
inst = inst & ~(1 << 16);
which sets the rt field to 0. Then I want to put the value of a new variable new_reg into the rt field. I tried:
inst = inst | (new_reg << 16);
Could anyone confirm whether these two lines of code are correct?
I believe the problem is with your first bitmask. The command (1 << 16) only masks the first bit, where you want to mask all of the bits from 16-20. Try:
inst = inst & ~(0x3f << 16)
Then:
inst = inst | (new_reg << 16);
I have a little issue trying to combine 4 digits together to give me the correct decimal value. First let me start with my code.
long firsttwo, secondtwo, combined;
firsttwo = 0x0C;
secondtwo = 0x6C;
The Decimal value of 0C: 12
The Decimal value of 6C: 108
But the Decimal value of all 0C6C: 3180
Now how do I get all the digits into one variable to be able to convert it to decimal correctely? Because if I just convert firsttwo by itself then secondtwo by itself I don't get the same final total. Thanks!
You need to shift the most significant byte when combining:
combined = (firsttwo << 8) | secondtwo;
this sets combined to 0x0c6c.
I have a probably simple question, which I just cant seem to understand.
I am creating a serial parser for a datalogger which sends a serial stream. Under the documentation for the product a calculation is stated, which I don't understand.
Lateral = Data1 And 0x7F + Data2 / 0x100
If (Data1 And 0x80)=0 Then Lateral = -Lateral
What does Data1 And 0x7f means? I know that 7F is 127, but besides that I don't understand the combination with the And statement.
What would the real formula look like?
Bitwise AND -- a bit in the output is set if and only if the corresponding bit is set in both inputs.
Since your tags indicate that you're working in C, you can perform bitwise AND with the & operator.
(Note that 0x7F is 01111111 and 0x80 is 10000000 in binary, so ANDing with these correspond respectively to extracting the lower seven bits and extracting the upper bit of a byte.)
1st sentence
Lateral = Data1 And(&) 0x7f + Data2/ 0x100
means take the magnitude of Data1(Data and 0x7f) and add to it the value of Data2/256
2nd sentence
check the sign od Data1 and assign the same to Lateral.
Sorry for the very basic question. What does the & operator do in this SQL
WHERE (sc.Attributes & 1) = 0
sc is an alias for a table which contains a column attributes.
I'm trying to understand some SQL in a report and that line is making it return 0 entries. If I comment it out it works. I have limited SQL knowledge and I'm not sure what the & 1 is doing.
& is the bitwise logical and operator - It performs the operation on 2 integer values.
WHERE (sc.Attributes & 1) = 0
The above code checks to see if sc.Attributes is an even number. Which is the same as saying that the first bit is not set.
Because of the name of the column though: "Attributes", then the "1" value is probably just some flag that has some external meaning.
It is common to use 1 binary digit for each flag stored in a number for attributes. So to test for the first bit you use sc.Attributes&1, to test for the second you use sc.Attributes&2, to test for the third you use sc.Attributes&4, to test for the fourth you use sc.Attributes&8, ...
The = 0 part is testing to see if the first bit is NOT set.
Some binary examples: (== to show the result of the operation)
//Check if the first bit is set, same as sc.Attributes&1
11111111 & 00000001 == 1
11111110 & 00000001 == 0
00000001 & 00000001 == 1
//Check if the third bit is set, same as sc.Attributes&4
11111111 & 00000100 == 1
11111011 & 00000100 == 0
00000100 & 00000100 == 1
It is a bitwise logical AND operator.
It's a bitwise and.
Seeing as you tagged this as sql server, I thought I'd add something from a different angle as also ran into one of these this week.
These can hurt the performance of your queries if used in the predicate. Very easy to manufacture an example of your own. Here is the snippet from my query
WHERE
advertiserid = #advertiserid
AND (is_deleted & #dirty > 0)
WHERE
advertiserid = #advertiserid
AND (is_deleted > 0 AND #dirty > 0)
by simply defining each column with a proper value this allowed the optimizer to remove a bookmark lookup and performance stats showed a X10 performance increase.