I have two input integer numbers and an output list< int> myoutputlist. My inputs are lets say
A=0x110101
B=0x101100
then I have calculated a C integer number depending on A and B numbers.I already coded its algorithm, I can calculate C integer. C integer shows which bits should be changed. 1 value represents changing bits, 0 values represents unchanging bits. Only one bit should be changed in each time. As C integer depends on A and B inputs, sometimes 1 bit, sometimes 3 bits, sometimes 8 bits needs to be changed. In this given A and B values, I have C integer as follows
C=0x 010010 (1 represents changing values; second and fifth bits should be changed in this case)
As C integer has value "1" for two times; there should be 2 results in this case
result 1-Changing only second bit, other bits are same as A(0x110101) :
Change second bit of A => D1=1101 1 1
result 2-Changing only fifth bit, other bits are same as A(0x110101) :
Change fifth bit of A => D2=1 1 0101
What I am thinking is using a for loop, shifting A and C step by step, and using &1 mask to C? And check if it is equal to "1"
for(i=0;i<32;i++)
{int D=(C>>i)&1; //I tried to check if i.th value is equal to 1 or not
if(D==1)
{ int E=(A&(~(2^i))) | ((2^i)&(~B)) //in first brackets, I removed i.th bit of A, then replaced it with "not B" value.
myoutputlist.add(E);
}
}
I need to do lots of calculations but disturbing issue is that I need to check (D==1) for 32 times. I will use it many million times, some calculations take about 2 mins. I am looking for a faster way. Is there any idea, trick?
I hope I understood your question right.
You are looking for the XOR operator.
C = A ^ B
A 110101
B 101100
--------
C 011001
XOR will always be 1 if the two inputs are "different". See:
| A | B | XOR |
|---+---+-----|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
Then you will be able to loop through the bits of C like this:
for (int i = 0; i < 32; i++)
{
bool bit = (C & (1 << i)) != 0;
}
How can I merge first n bits of a byte with last 8-n bits of another byte?
I know something like below for picking 3 bits from first and 5 from second (Which I have observed in DES encryption algorithm)
zByte=(xByte & 0xE0) | (yByte & 0x1F); But I don't know maths behind why we need to use 0XE0 and 0X1F in this case. So I am trying to understand the details with regards to each bit.
In C#, that would be something like:
int mask = ~((-1) << n);
var result = (x & ~mask) | (y & mask);
i.e. we build a mask that is (for n = 5) : 000....0011111, then we combine (&) one operand with that mask, the other operand with the inverse (~) of the mask, and compose them (|).
You could also probably do something more quickly just using shift operations (avoiding a mask completely) - but only if the data can be treated as unsigned (so Java might struggle here).
It just sounds like you don't understand how boolean arithmetic works? If this is your question it works like this:
0xEO and 0x1F are hexidecimal representations of numbers. If we convert these numbers to binary they would be:
0xE0 = 11100000
0x1F = 00011111
Additionally & (and) and | (or) are bitwise logical operators. To understand logical operators, first remember the 1 = true and 0 = false.
The truth table for & is:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
The truth table for | is:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
So let's breakdown your equation piece by piece. First we will evaluate the code in parenthesis first. We will walk through each number in binary and for the & operator if each operand has a 1 in the same bit position we will return 1. If either number has a 0 then we will return 0. After we finish the evaluation of the operands in the parenthesis we will then take the 2 resulting numbers and apply the | operator bit by bit. If either number has a 1 in the same bit position we will return 1. If both numbers have a 0 in the same bit position we will return 0.
For the sake of discussion, let's say that
xByte = 255 or (FF in hex and 11111111 in binary)
yByte = 0 or (00 in hex and 00000000 in binary)
When you apply the & and | operators we are going to compare each bit one at a time:
zByte = (xByte & 0xEO) | (yByte & 0x1F)
becomes:
zByte = (11111111 & 11100000) | (00000000 & 00011111)
zByte = 111000000 | 00000000
zByte = 11100000
If you understand this and how boolean logic works then you can use Marc Gravell's answer.
The math behind those numbers (0xE0 and 0x1F) is quite simple. First we are exploiting the fact that 0 & <bit> always equals 0 and 1 & <bit> always equals <bit>.
0x1F is 00011111 binary, which means that the first 3 bits will always be 0 after an & operation with another byte - and the last 5 bits will be the same they were in the other byte. Remember that every 1 in a binary number represents a power of 2, so if you want to find the mask mathematically it would be the sum of 2^x from x = 0 to n-1. Then you can find the opposite mask (the one that is 11100000) to extract the first 3 bit, you simply need to subtract the mask from 11111111, and you will get 11100000 (0xE0).
In java,
By using the following function we can get the first n bits of the first Byte and last 8 n bits of the second byte.
public class BitExample {
public static void main(String[] args) {
Byte a = 15;
Byte b = 16;
String mergedValue=merge(4, a, b);
System.out.println(mergedValue);
}
public static String merge(int n, Byte a, Byte b) {
String mergedString = "";
String sa = Integer.toBinaryString(a);
String sb = Integer.toBinaryString(b);
if(n>sa.length()) {
for(int i=0; i<(n-sa.length()); i++) {
mergedString+="0";
}
mergedString+=sa;
}else{
mergedString+=sa.substring(0, n);
}
if(8*n>sb.length()) {
for(int i=0; i<(8*n-sb.length()); i++) {
mergedString+="0";
}
mergedString+=sb;
}
return mergedString;
}
}
How to remove the leftmost bit?
I have a hexadecimal value BF
Its binary representation is 1011 1111
How can I remove the first bit, which is 1, and then it will become 0111 1110?
How to add "0" also to its last part?
To set bit N of variable x to 0
x &= ~(1 << N);
How it works: The expression 1 << N is one bit shifted N times to the left. For N = 7, this would be
1000 0000
The bitwise NOT operator ~ inverts this to
0111 1111
Then the result is bitwise ANDed with x, giving:
xxxx xxxx
0111 1111
--------- [AND]
0xxx xxxx
Result: bit 7 (zero-based count starting from the LSB) is turned off, all others retain their previous values.
To set bit N of variable x to 1
x |= 1 << N;
How it works: this time we take the shifted bit and bitwise OR it with x, giving:
xxxx xxxx
1000 0000
--------- [OR]
1xxx xxxx
Result: Bit 7 is turned on, all others retain their previous values.
Finding highest order bit set to 1:
If you don't know which is the highest bit set to 1 you can find out on the fly. There are many ways of doing this; a reasonable approach is
int x = 0xbf;
int highestSetBit = -1; // assume that to begin with, x is all zeroes
while (x != 0) {
++highestSetBit;
x >>= 1;
}
At the end of the loop, highestSetBit will be 7 as expected.
See it in action.
int i=0xbf;
int j=(i<<1) & 0xff;
or you could do:
(i*2) && 0xff
if you'd rather not do bit twiddling. >>1 is the equivalent of /2, and <<1 is the equivalent of *2.
I saw this code snippet that was used to solve the ol' "Find the one number in an array that does not have a duplicate." question. I have been looking at this for a while this morning, but can not nail down exactly how it is doing it.
I don't understand how k always ends up holding the value of the non-duplicate. Can anyone explain how this works?
static void Main(string[] args)
{
int[] list = { 3,6,9,12,3,6,9 };
int k = 0;
for (int i = 0; i < list.Length; i++)
{
k = k ^ list[i];
}
Console.WriteLine(k);
}
It only works if only one number is non-duplicated (or occurs any odd number of times) and all the other numbers occur an even number of times.
When you xor a number to another number twice (or any other even number of times) it cancels itself out leaving the original number.
It's slightly similar to the "Nerds, Jocks and Lockers" problem, in terms of the "bit-flipping" going on leaving certain bits set and others not.
The basic behavior is that A XOR B works like "(A OR B) AND NOT (A AND B)". So, 0^0=0, 1^0 = 1, but 1^1 = 0 (unlike OR). Now, you start with zero (no bits set) on K. You then XOR it with the literal 3, which (as a byte) has the bits 00000011, and assign the result to K. You end up with 00000011 for K, because the bits that are set on the literal 3 are all not set on K when it's 0. Now, if you were to XOR K with the literal 3 again, you'd end up with 0, because all the bits match between the two values, so the XOR would return 0 on each bit.
This process is commutative, so ((((0 XOR 3) XOR 6) XOR 3) XOR 6) would give the same result (0) as ((((0 XOR 6) XOR 6) XOR 3) XOR 3), or pretty much any other combination of XORing 0 with 3 twice and 6 twice.
The net result is that, given a list of these numbers, any number that occurs twice (or an even number of times) is "XORed in" to K the first time, and then "XORed out" the second, leaving K with its bits set to the one value that only occurred once; 12.
Here's the binary demonstration of the full problem (using "nibbles" because we don't have any values over 16):
0000 0
^^^^ XOR
0011 3
---- =
0011 3
^^^^ XOR
0110 6
---- =
0101 5
^^^^ XOR
1001 9
---- =
1100 12
^^^^ XOR
1100 12
---- =
0000 0 <-this is coincidence; it'd work the same regardless of the unduped value
^^^^ XOR
0011 3
---- =
0011 3
^^^^ XOR
0110 6
---- =
0101 5
^^^^ XOR
1001 9
---- =
1100 12 <- QED
EDIT FROM COMMENTS: While this answer functions for the specific question asked, even the smallest change to the problem would "break" this implementation, such as:
The algorithm is completely unresponsive to the number zero; the algorithm is thus unable to tell the difference between having zero as a single unpaired value and having no unpaired values at all.
The algorithm only works for pairs, not triplets. If 3 occurred three times and was still a "dupe", and 12 was still the right answer, this algorithm would actually return 15 (1100 ^ 0011 == 1111) which isn't even in the list.
The algorithm only works if there is only one non-duplicated value in the list; if 8 and 12 were both unpaired values expected to be returned, the algorithm would return the XOR of the two (1100 ^ 1000 == 0100 == 4)
An efficient algorithm could be developed that would return the correct answer in all these cases in addition to the original case, but it would likely not involve XOR.
Any number can be expressed as a bit sequence:
3 == 0...00011
6 == 0...00110
9 == 0...01001
If you XOR them twice, the bit switching will cancel each other.
Therefore, if a single number appears once (or an odd number of times) in the list, then it will be the only one with the bits left "uncancelled".
keithS is spot on, but this might be a bit easier to follow.
The simplest explanation I can think of has to do with four properties of XOR:
0 XOR x = x, for any number x
x XOR x = 0, for any number x
XOR is commutative: x XOR y = y XOR x (this allows you to rearrange a series of XOR operations however you see fit)
XOR is associative: (x XOR y) XOR z = x XOR (y XOR z) (this allows you to evaluate XOR's in any order you see fit)
By properties 2 and 3, you can rearrange your input list so that all duplicates are next to each other:
{ 3,6,9,12,3,6,9 } -> { 3, 3, 6, 6, 9, 9, 12 };
By properties 1 and 4, we can XOR these numbers pairwise in any order, and all pairs of identical numbers become 0. After this, only the unduplicated number remains non-zero:
{ 0, 0, 0, 12 };
Also by property 1, because k is 0 to begin with, and all duplicate numbers have XOR'ed to become zero, all that's left is 12
This works because the XOR operator is both commutative and associative. This means you can rearrange the terms in any order:
a ^ b ^ c == a ^ c ^ b == c ^ a ^ b == ... (etc.)
This works for sequences of any length. Therefore:
3 ^ 6 ^ 9 ^ 12 ^ 3 ^ 6 ^ 9 == (3 ^ 3) ^ (6 ^ 6) ^ (9 ^ 9) ^ 12
Since x ^ x == 0 for any integer, which means you can eliminate all the pairs until you get 0 ^ 12, which is just equal to 12.
a ^ a = 0
a ^ 0 = a
0 ^ a = a ^ 0
a = b ^ c
a = c ^ b
int[] list = { 3,6,9,12,3,6,9 };
k ^ 3
k ^ 6
k ^ 9
k ^ 12
k ^ 3
k ^ 6
k ^ 9
=
k ^ 3 // dupe
k ^ 3
k ^ 6
k ^ 6
k ^ 9
k ^ 9
k ^ 12 // non-dupe
=
k ^ 12
=
0 ^ 12
=
12
When using XOR, you have to put in mind that you will be working with bits. In other words, you will only have 0 and 1 to deal with.
The definition of XOR is so simple:
0 XOR 0 -> 0
0 XOR 1 -> 1
1 XOR 1 -> 0
So if you apply this to your code and transform the 3 to 0011, the 6 to 0110, the 9 to 1001 and the 12 to 1100, and invoke the XOR method on them like in the example below, you will end up with 1100 that will represent the value 12.
Example:
0011
XOR
0110
=
0101 -> 5
This is not an algorithm to eliminate duplicate values. This happened by coincidence that you obtained the 12.
The code you reference does NOT actually solve the problem. For instance, put three 12s in the list and you will get 12, even though 12 is duplicated twice.
The result of XOR is essentially whether there is an odd or even number of that bit combination. So if the list contains an odd number of 12s (whether that be one 12 or a hundred-and-one 12s) and an even number of each other number, the result will always be 12.
Even worse, if the list contained an odd number of multiple different numbers, the result value may not be any of the numbers in the list. E.g., one 3 and one 14 would result in 13. This is because the XOR really operates on bits, not integers. The XOR of 14 (1110b) and 3 (0011b) results in 13 (1101b), since XOR sets any bits that are common between the numbers to zero.
Code that actually solves the problem:
using System.Linq;
using System.Collections.Generic;
...
static void Main ( string[] args)
{
int[] list = { 3,6,9,12,3,6,9 };
int[] nonDupes = list
.GroupBy(x => x)
.Where(x => x.Count() == 1)
.Select(x => x.Key)
.ToArray();
string output = string.Join(",", nonDupes);
Console.WriteLine(output);
}
Given that i have a uint value of 2402914, and i would like to grab the leftmost 17 bits, where is the fault in my logic by doing this code:
int testop = 0;
byte[] myArray = BitConverter.GetBytes(2402914);
fixed (byte* p = &myArray[0])
{
testop = *p >> 15;
}
my expected output is
50516.
You might want to get your expectations to match reality. A right-shift is equivalent to dividing by 2. You are effectively dividing by 2 fifteen times, which is the same as saying you are dividing by 2^15 = 32768. Note that 2402914 / 32768 = 73 (truncating the remainder).
Therefore, I would expect the result to be 73, not 50516.
In fact,
2402914_10 = 0000 0000 0010 0100 1010 1010 0110 0010_2
So that the left-most seventeen bits are
0000 0000 0010 0100 1
Note that
0000 0000 0010 0100 1 = 1 * 1 + 0 * 2 + 0 * 4 + 1 * 8 + 0 * 16 + 0 * 32 + 1 * 64
= 73
Note that you can obtain this result more simply with
int testop = 2402914 >> 15;
*p just gives you the first byte; it is equivalent to p[0]. You'll have to use shifting and ORing to combine bits from the first three bytes (or the last three bytes, depending on endianness...)
If this code is not a simplified version of something more complicated and you're actually trying to just extract the leftmost 17 bits from an int, this should do:
int testop = (someInt >> 15) & 0x1ffff;
(Edit: Added & 0x1ffff to make it work for negative integers too; thanks to #James.)
Wow, this has been a really fun puzzle to figure out. Not the programming part, but trying to figure out where you got the number 50516 and what you are trying to do with your code. It looks like you are taking the 16 least significant bits and ROTATING them LEFT 9 bits.
2402914: 0000 0000 0010 0100 1010 1010 0110 0010
left 9: 0100 1001 0101 0100 1100 010
match: ^^^^ ^^^
>>50516: 1100 0101 0101 0100
match: ^ ^^^^ ^^^^
right 7: 1 0101 0100 110 0010
int value2 = value & 0xffff;
int rotate9left = ((value2 << 9) & 0xffff) | ((value2) >> (16 - 9));
I don't know why you are using a byte array, but it seems like you think your fixed() statement is looping through the array, which it is not. Your statement in the fixed block is taking the byte value at myArray[0] and SHIFTing it right 15 bits (shifting fills with 0s as opposed to rotating which wraps the front bits around to the back). Any thing over 8 would give you zero.
From what I understand, you can apply the bit-shift operator directly to the int datatype, rather than going through the trouble of the unsafe code.
For example:
2402914 >> 15 = 73
This ties to the result predicted by Jason.
Further, I note that
2402914 >> 5 = 75091
and 2402914 >> 6 = 37545
This suggests that your required result cannot be achieved by any similar right shift.