here's the problem that's being solved
"You're given three integers, a, b and c. It is guaranteed that two of these integers are equal to each other. What is the value of the third integer? "
here's the code
int extraNumber(int a, int b, int c) {
return a^b^c;
}
I understand the caret " ^ " mean XOR, which means "this OR that, but not both" in simple terms but what I fail to understand is how this code determines which int is different from the others, or perhaps I don't understand XOR properly?
Look at it at bit-level:
A value x xor-ed with itself will always result in 0 (check: 1^1=0 and 0^0=0).
A value y xor-ed with 0 will always result in the same value y (check: 1^0=1 and 0^0=0).
Since it holds true for individual bits and int are just 32 bits, the same rules hold true for full int values.
Therefore the method doesn't need to figure out "which values are different" because a value xor-ed with itself with cancel out to 0 and xor-ing the "remaining" value with 0 will just return the same value.
Joachim's answer is correct, and to add bit more details with an example, let's say you pass three arguments (2, 3, 2) to your method, the bit level format usually ...16 8 4 2 1 starts from right side, as per truth table for XOR,
https://en.wikipedia.org/wiki/XOR_gate
private int extraNumber(int a, int b, int c) {
// 8421 -> this is bit level,
// let's compare a^b
// 0010 = 2 (a value)
// 0011 = 3 (b value, sum of 2nd + 1st bits)
// 0001 = 1 (after XOR with a^b)
// 0010 = 2 (c value)
// 0011 = 3 (the final output)
return a^b^c;
}
you can also check the intermediate results, by breaking up the code a^b^c into two statements.
for example
int a = 0b1010_1010;
int b = 0b1010_1010; //same value as b
int c = 0b1111_0000; //the remaining item
//CASE 1 (xor the different values first)
int d = a^c; // results in 0b0101_1010
int e = d^b; // results in 0b1111_0000 (the answer)
//CASE 2 (xor the same values first)
int d = a^b; // results in 0b0000_0000
int e = d^c; // results in 0b1111_0000 (the answer)
Related
I have used JAVA to create a linked list of 30 nodes. Each node is assigned a random Boolean value when instantiated.
I want each node assigned its own random boolean method/function/rule that takes three Boolean arguments and returns the result:
boolean assignedBolMethod(boolean a, boolean b, boolean c) {
boolean answer = conduct assigned ruled
return answer;
}
I understand there are 256 such rules to chose from (2^2^3); how could I generate all 256 possible rules without typing them out manually?
Let's say '0' when we mean false and '1' when we mean true, because that makes this a lot easier to read:
There are 8 different possible inputs (000, 001, 010, 011, 100, 101, 110, and 111), and for each input, there are 2 possible answers: 0 or 1.
Let's define a 'rule' as follows: We always list all the inputs in that exact order, and then we list the rule's answer to each input in terms of a 1 or a 0. Thus, 00001111 is the rule that says '000 = 0', '001 = 0, 010 = 0, 011 = 0, 100 = 1, ', etcetera - in other words, the rule is: return a;, if you were to put it in code.
It is then obvious that there are indeed 256 rules (2 ^ 8), and you can represent each rule as a single byte, as bytes consist of 8 bits. Every existing byte represents one rule. Thus 'a rule' and 'a byte' are completely interchangeable, thus, this boils down to: How do I generate an arbitrary byte.
And that's easy:
Random r = new Random(); // do this once someplace
byte rule = r.nextByte();
Alternatively if you want an ordered list of every possible rule:
byte[] rules = new byte[256];
for (int i = 0; i < rules.length; i++) rules[i] = (byte) i;
But this array is mostly meaningless; it effectively maps '100' to '100' - not very useful. There is no actual need to have a 'list' of all possible rules: Java already ships with it: byte - that is a data type that exactly matches. Thus, if you have some code and you want 'rule 100' to be applied, all you need to write is byte rule = 100; - no need for a list.
Given a byte that represents a rule, plus those 3 inputs, how do you determine the answer the rule indicates is correct?
Well, first you need to collapse those 3 booleans you have into which one of the 8 bits in your byte represents the answer.
int bitPos = (a ? 1 : 0) + (b ? 2 : 0) + (c ? 4 : 0);
This gives you the position of the bit (a number between 0 and 7) that determines the answer.
Then, given a bit position and a byte:
boolean answer = ((rule >> bitpos) & 1) != 0;
Breaking that down:
a >> b will take the bitstring of a (let's say it's rule 00110111), and shift it to the right by b spots. So if we want the bit at bitpos=2 (so, the third bit), 0b00110111 >> 2 is 0b00001101. This means the bit we are interested in is now at the very end.
a & b will take the bitstring of a, and the bitstring of b, and checks for all positions where both a and b have a 1. Then, it returns a new number represented by setting each bit to 1 where both a and b have a one. Therefore, a & 1 has the effect of zeroing out all bits, except the lowest bit (1 = 00000001 - all bits unset except the lowest bit). It gets rid of all bits, except the bit we care about.
!= 0 then just checks if that bit was set or not.
I have a decimal number which I need to convert to binary and then find the position of one's in that binary representation.
Input is 5 whose binary is 101 and Output should be
1
3
Below is my code which only provides output as 2 instead I want to provide the position of one's in binary representation. How can I also get position of set bits starting from 1?
public static void main(String args[]) throws Exception {
System.out.println(countBits(5));
}
private static int countBits(int number) {
boolean flag = false;
if (number < 0) {
flag = true;
number = ~number;
}
int result = 0;
while (number != 0) {
result += number & 1;
number = number >> 1;
}
return flag ? (32 - result) : result;
}
Your idea of having countBits return the result, instead of putting a System.out.println inside the method, is generally the best approach. If you want it to return a list of bit positions, the analogue would be to have your method return an array or some kind of List, like:
private static List<Integer> bitPositions(int number) {
As I mentioned in my comments, you will make life a lot easier for yourself if you use >>> and get rid of the special code to check for negatives. Doing this, and adapting the code you already have, gives you something like
private static List<Integer> bitPositions(int number) {
List<Integer> positions = new ArrayList<>();
int position = 1;
while (number != 0) {
if (number & 1 != 0) {
positions.add(position);
}
position++;
number = number >>> 1;
}
return positions;
}
Now the caller can do what it wants to print the positions out. If you use System.out.println on it, the output will be [1, 3]. If you want each output on a separate line:
for (Integer position : bitPositions(5)) {
System.out.println(position);
}
In any case, the decision about how to print the positions (or whatever else you want to do with them) is kept separate from the logic that computes the positions, because the method returns the whole list and doesn't have its own println.
(By the way, as Alex said, it's most common to think of the lower-order bit as "bit 0" instead of "bit 1", although I've seen hardware manuals that call the low-order bit "bit 31" and the high-order bit "bit 0". The advantage of calling it "bit 0" is that a 1 bit in position N represents the value 2N, making things simple. My code example calls it "bit 1" as you requested in your question; but if you want to change it to 0, just change the initial value of position.)
Binary representation: Your number, like anything on a modern day (non-quantum) computer, is already a binary representation in memory, as a sequence of bits of a given size.
Bit operations
You can use bit shifting, bit masking, 'AND', 'OR', 'NOT' and 'XOR' bitwise operations to manipulate them and get information about them on the level of individual bits.
Your example
For your example number of 5 (101) you mentioned that your expected output would be 1, 3. This is a bit odd, because generally speaking one would start counting at 0, e.g. for 5 as a byte (8 bit number):
76543210 <-- bit index
5 00000101
So I would expect the output to be 0 and 2 because the bits at those bit indexes are set (1).
Your sample implementation shows the code for the function
private static int countBits(int number)
Its name and signature imply the following behavior for any implementation:
It takes an integer value number and returns a single output value.
It is intended to count how many bits are set in the input number.
I.e. it does not match at all with what you described as your intended functionality.
A solution
You can solve your problem using a combination of a 'bit shift' (>>) and an AND (&) operation.
int index = 0; // start at bit index 0
while (inputNumber != 0) { // If the number is 0, no bits are set
// check if the bit at the current index 0 is set
if ((inputNumber & 1) == 1)
System.out.println(index); // it is, print its bit index.
// advance to the next bit position to check
inputNumber = inputNumber >> 1; // shift all bits one position to the right
index = index + 1; // so we are now looking at the next index.
}
If we were to run this for your example input number '5', we would see the following:
iteration input 76543210 index result
1 5 00000101 0 1 => bit set.
2 2 00000010 1 0 => bit not set.
3 1 00000001 2 1 => bit set.
4 0 00000000 3 Stop, because inputNumber is 0
You'll need to keep track of what position you're on, and when number & 1 results in 1, print out that position. It look something like:
...
int position = 1;
while (number != 0) {
if((number & 1)==1)
System.out.println(position);
result += number & 1;
position += 1;
number = number >> 1;
}
...
There is a way around working with bit-wise operations to solve your problem.
Integer.toBinaryString(int number) converts an integer to a String composed of zeros and ones. This is handy in your case because you could instead have:
public static void main(String args[]) throws Exception {
countBits(5);
}
public static void countBits(int x) {
String binaryStr = Integer.toBinaryString(x);
int length = binaryStr.length();
for(int i=0; i<length; i++) {
if(binaryStr.charAt(i)=='1')
System.out.println(length-1);
}
}
It bypasses what you might be trying to do (learn bitwise operations in Java), but makes the code look cleaner in my opinion.
The combination of Integer.lowestOneBit and Integer.numberOfTrailingZeros instantly gives the position of the lowest 1-Bit, and returns 32 iff the number is 0.
Therefore, the following code returns the positions of 1-Bits of the number number in ascending order:
public static List<Integer> BitOccurencesAscending(int number)
{
LinkedList<Integer> out = new LinkedList<>();
int x = number;
while(number>0)
{
x = Integer.lowestOneBit(number);
number -= x;
x = Integer.numberOfTrailingZeros(x);
out.add(x);
}
return out;
}
In the page Wikipedia - Shifts in Java:
In bit and shift operations, the type byte is implicitly converted to
int. If the byte value is negative, the highest bit is one, then ones
are used to fill up the extra bytes in the int. So
byte b1=-5; int i = b1 | 0x0200;
will give i == -5 as result.
I understand that 0x0200 is equal to 0b0000 0010 0000 0000. But what is the significance of 0x0200 in the passage shown above?
I mean—b1 | 0x0200 will always be equal to i (see "My Test" below), then in the passage above, why not simply write byte b1=-5; int i = b1?
My Test:
public static void main(final String args[]) {
final byte min_byte = Byte.MIN_VALUE; // -128
final byte limit = 0; // according to the bolded words in the passage
for (byte b = min_byte; b < limit; ++b) {
final int i1 = b;
final int i2 = b | 0x0200;
if (i1 != i2) { // this never happens!
System.out.println(b);
}
}
}
But what is the significance of 0x0200 in the passage shown above?
This is done for illustration purposes only: the value 0x200 ORs in a one in a position that is equal to 1 already. The idea is to show that the result is not 0x000002FB, but actually -5, i.e. 0xFFFFFFFB.
I understand that 0x0200 is equal to 0b1111 1110 0000 0000
No, it isn't. The correct value is given by,
int i = 0x0200; // <-- decimal 512
System.out.println(Integer.toBinaryString(i));
Which outputs
1000000000
If we examine your second value,
byte b1 = -5;
System.out.println(Integer.toBinaryString(b1));
We get
11111111111111111111111111111011
Lining up both numbers
11111111111111111111111111111011
00000000000000000000001000000000
It seems clear that the result will be the bit value of -5 (since the only 0 in -5 is also 0 in 0x0200). To determine the significance we can examine
int i = 0x0200; // <-- Decimal 512
System.out.println("Dec: " + Integer.toBinaryString(i).length());
Output
Dec: 10
So, the given bitwise OR will force the tenth bit to be true. It was true in your input byte, but if you used - Decimal 1535 (0b 101 1111 1111) then you would get,
System.out.println(1535 | 0x0200);
Output is
2047
Because if you perform a bitwise-or on the two numbers
01000000000
10111111111
you get
11111111111
I have the bits 101 and 110. I want to compare using some bitwise operator ignoring the first bit like 01 and 10.
Example:
I have:
101
110
===
01 & 10 <- How I want to consider
x00 <- The result I want
or
10110
11011
=====
0110 & 1011 <- How I want to consider
x0010 <- The result I want
How could I achieve this using bitwise operators in java?
Details:
The first bit will always be 1.
The other bits are variable. Both
sides of the comparison will have the same number of bits.
I want to detect just how to make the comparison considering the other bits and
ignoring the first.
Use case:
I have 2 permission values. The first is 5/101 (The permission required) and the second is 6/110 (The permission the user has).
Excluding the first block, which will always be 1, I want to compare the third block that represents a certain permission rule in the system (using bitwise).
"The permission required" bitmask means:
1 - An always fixed value I use to be able to consider the left padding zeroes (unless there is another way to achieve this);
0 - Another permission rule useless for this comparison (let's call permission 1);
1 - The needed permission for the current permission rule (let's call permission 2).
"The permission the user has" means:
1 - A fixed value to be striped out;
1 - Represents the value of the user for the permission 1;
0 - Represents the value of the user for the permission 2. The permission 2 has the value 1 but the user has 0 then he is NOT allowed to the required action. The opposite would be ALLOWED to execute the action.
Any better solution for this case will be considered a correct answer also.
If you know the number of useful bits (e.g numofbits = 5) then the bitmask for the expression is:
bitmask = (1 << numofbits) - 1
If you don't know the numofbits, just make a loop with num = num >> 1, and count the iteration until you got num == 0.
For the use case:
result = (req_roles & user_roles) & (bitmask >> 1)
This simply ands the role bits, ans cuts the upper bit (which is always 1)
Previous answer for previous question :) :
If you know the bitmask for the highest number (e.g. bitmask = 0x1f (11111 in bits)) then you want the result of the following expression:
result = (a ^ b) ^ (bitmask >> 1)
What does it do?
Compares all bits, the equal bits will be 0
Reverts all lower bits, so equal bits will be 1 (leaves the high bit out, so it will remain 0)
Just 'and' the arguments with a mask that has the first bit off, eg 011 & arg before you compare them.
Edit: after restated question.
The alternative is to use role based permissions, these are far more flexible and easier to understand than Boolean permission strings. They are also self documenting. Bit string based permissions are rarely used except where memory or disk space are at a premium, like when Unix was developed back in the early '80s or in embedded systems.
Try this:
// tester 1
int x, y, z, mask;
x = 0x05; // 101
y = 0x06; // 110
mask = getMask(x, y);
z = (mask & (x & y));
System.out.println(String.format("mask: %x result: %x", mask, z));
// tester 2
int x, y, z, mask;
x = 0x16; // 10110
y = 0x1B; // 11011
mask = getMask(x, y);
z = (mask & (x & y));
System.out.println(String.format("mask: %x result: %x", mask, z));
private int getMask(final int x, final int y) {
int mask = findHighOrderOnBit(x, 0);
mask = findHighOrderOnBit(y, mask) - 1;
return mask;
}
private int findHighOrderOnBit(final int target, final int otherMask) {
int result = 0x8000;
for (int x = 0; x != 16; x++) {
if ((result & target) > 0)
break;
result >>= 1;
}
if (otherMask > result)
result = otherMask;
return result;
}
I will explain first what I mean by "complementing integer value excluding the leading zero binary bits" (from now on, I will call it Non Leading Zero Bits complement or NLZ-Complement for brevity).
For example, there is integer number 92. the binary number is 1011100. If we perform normal bitwise-NOT or Complement, the result is: -93 (signed integer) or 11111111111111111111111110100011 (binary). That's because the leading zero bits are being complemented too.
So, for NLZ-Complement, the leading zero bits are not complemented, then the result of NLZ-complementing of 92 or 1011100 is: 35 or 100011 (binary). The operation is performed by XORing the input value with sequence of 1 bits as much as the non-leading zero value. The illustration:
92: 1011100
1111111 (xor)
--------
0100011 => 35
I had made the java algorithm like this:
public static int nonLeadingZeroComplement(int n) {
if (n == 0) {
return ~n;
}
if (n == 1) {
return 0;
}
//This line is to find how much the non-leading zero (NLZ) bits count.
//This operation is same like: ceil(log2(n))
int binaryBitsCount = Integer.SIZE - Integer.numberOfLeadingZeros(n - 1);
//We use the NLZ bits count to generate sequence of 1 bits as much as the NLZ bits count as complementer
//by using shift left trick that equivalent to: 2 raised to power of binaryBitsCount.
//1L is one value with Long literal that used here because there is possibility binaryBitsCount is 32
//(if the input is -1 for example), thus it will produce 2^32 result whom value can't be contained in
//java signed int type.
int oneBitsSequence = (int)((1L << binaryBitsCount) - 1);
//XORing the input value with the sequence of 1 bits
return n ^ oneBitsSequence;
}
I need an advice how to optimize above algorithm, especially the line for generating sequence of 1 bits complementer (oneBitsSequence), or if anyone can suggest better algorithm?
UPDATE: I also would like to know the known term of this non-leading zero complement?
You can get the highest one bit through the Integer.highestOneBit(i) method, shift this one step left, and then subtract 1. This gets you the correct length of 1s:
private static int nonLeadingZeroComplement(int i) {
int ones = (Integer.highestOneBit(i) << 1) - 1;
return i ^ ones;
}
For example,
System.out.println(nonLeadingZeroComplement(92));
prints
35
obviously #keppil has provided shortest solution. Another solution could be like.
private static int integerComplement(int n){
String binaryString = Integer.toBinaryString(n);
String temp = "";
for(char c: binaryString.toCharArray()){
if(c == '1'){
temp += "0";
}
else{
temp += "1";
}
}
int base = 2;
int complement = Integer.parseInt(temp, base);
return complement;
}
For example,
System.out.println(nonLeadingZeroComplement(92));
Prints answer as 35