I am writing a program which I found on a coding competition website, I have sort of figured out how to solve the problem but, I am stuck on a math part of it, I am completely diluting the problem and showing what I need.
first I need to check if a number is part of a sequence, my sequence is 2*a+1 where a is the previous element in the sequence or 2^n-1 to get nth item in the sequence. so it is 1,3,7,15,31,63...
I don't really want to create the whole sequence and check if a number is present, but I am not sure what a quicker method to do this would be.
Second if I am given a number lets say 25, I want to figure out the next highest number in my sequence to this number. So for 25 it would be 31 and for 47 it would be 63, for 8 it would be 13.
How can i do these things without creating the whole sequence.
I have seen similar questions here with different sequences but I am still not sure how to solve this
Start by finding the explicit formula for any term in your sequence. I'm too lazy to write out a proof, so just add 1 to each term in your sequence:
1 + 1 = 2
3 + 1 = 4
7 + 1 = 8
15 + 1 = 16
31 + 1 = 32
63 + 1 = 64
...
You can clearly see that a_n = 2^n - 1.
To check if a particular number is in your sequence, assume that it is:
x = 2^n - 1
x + 1 = 2^n
From Wikipedia:
The binary representation of integers makes it possible to apply a
very fast test to determine whether a given positive integer x is a
power of two:
positive x is a power of two ⇔ (x & (x − 1)) equals to zero.
So to check, just do:
bool in_sequence(int n) {
return ((n + 1) & n) == 0;
}
As #Blender already pointed out your sequence is essentially 2^n - 1, you can use this trick if you use integer format to store it:
boolean inSequence(int value) {
for (int i = 0x7FFF; i != 0; i >>>= 1) {
if (value == i) {
return true;
}
}
return false;
}
Note that for every elements in your sequence, its binary representation will be lots of 0s and then lots of 1s.
For example, 7 in binary is 0000000000000000000000000000111 and 63 in binary is 0000000000000000000000000111111.
This solution starts from 01111111111111111111111111111111 and use an unsigned bitshift, then compare if it is equal to your value.
Nice and simple.
How to find the next higher number :
For example, we get 19 ( 10011 ) , should return 31 (11111)
int findNext(int n){
if(n == 0) return 1;
int ret = 2; // start from 10
while( (n>>1) > 0){ // end with 100000
ret<<1;
}
return ret-1;
}
Related
You are given two strings S and T. An infinitely long string is formed in the following manner:
Take an empty string,
Append S one time,
Append T two times,
Append S three times,
Append T four times,
and so on, appending the strings alternately and increasing the number of repetitions by 1 each time.
You will also be given an integer K.
You need to tell the Kth Character of this infinitely long string.
Sample Input (S, T, K):
a
bc
4
Sample Output:
b
Sample Explanation:
The string formed will be "abcbcaaabcbcbcbcaaaaa...". So the 4th character is "b".
My attempt:
public class FindKthCharacter {
public char find(String S, String T, int K) {
// lengths of S and T
int s = S.length();
int t = T.length();
// Counters for S and T
int sCounter = 1;
int tCounter = 2;
// To store final chunks of string
StringBuilder sb = new StringBuilder();
// Loop until K is greater than zero
while (K > 0) {
if (K > sCounter * s) {
K -= sCounter * s;
sCounter += 2;
if (K > tCounter * t) {
K -= tCounter * t;
tCounter += 2;
} else {
return sb.append(T.repeat(tCounter)).charAt(K - 1);
}
} else {
return sb.append(S.repeat(sCounter)).charAt(K - 1);
}
}
return '\u0000';
}
}
But is there any better way to reduce its time complexity?
I've tried to give a guide here, rather than just give the solution.
If s and t are the lengths of the strings S and T, then you need to find the largest odd n such that
(1+3+5+...+n)s + (2+4+6+...+(n+1))t < K.
You can simplify these expressions to get a quadratic equation in n.
Let N be (1+3+..+n)s + (2+4+6+...+(n+1))t. You know that K will lie either in the next (n+2) copies of S, or the (n+3) copies of T that follow. Compare K to N+(n+2)s, and take the appropriate letter of either S or T using a modulo.
The only difficult step here is solving the large quadratic, but you can do it in O(log K) arithmetic operations easily enough by doubling n until it's too large, and then using a binary search on the remaining range. (If K is not too large so that floating point is viable, you can do it in O(1) time using the well-known quadratic formula).
Here my quick attempt, there probably is a better solution. Runtime is still O(sqrt n), but memory is O(1).
public static char find(String a, String b, int k) {
int lenA = a.length();
int lenB = b.length();
int rep = 0;
boolean isA = false;
while (k >= 0) {
++rep;
isA = !isA;
k -= (isA ? lenA : lenB) * rep;
}
int len = (isA ? lenA : lenB);
int idx = (len * rep + k) % len;
return (isA ? a : b).charAt(idx);
}
Here's a O(1) solution that took me some time to come up with (read I would have failed an interview on time). Hopefully the process is clear and you can implement it in code.
Our Goal is to return the char that maps to the kth index.
But How? Just 4 easy steps, actually.
Step 1: Find out how many iterations of our two patterns it would take to represent at least k characters.
Step 2: Using this above number of iterations i, return how many characters are present in the previous i-1 iterations.
Step 3: Get the number of characters n into iteration i that our kth character is. (k - result of step 2)
Step 4: Mod n by the length of the pattern to get index into pattern for the specific char. If i is odd, look into s, else look into t.
For step 1, we need to find a formula to give us the iteration i that character k is in. To derive this formula, it may be easier to first derive the formula needed for step 2.
Step 2's formula is basically given an iteration i, return how many characters are present in that iteration. We are solving for 'k' in this equation and are given i, while it's the opposite for step 1 where were are solving for i given k. If we can derive the equation of find k given i, then we can surely reverse it to find i given k.
Now, let's try to derive the formula for step 2 and find k given i. Here it's best to start with the most basic example to see the pattern.
s = "a", t = "b"
i=1 a
i=2 abb
i=3 abbaaa
i=4 abbaaabbbb
i=5 abbaaabbbbaaaaa
i=6 abbaaabbbbaaaaabbbbbb
Counting the total number of combined chars for each pattern during its next iteration gives us:
#iterations of pattern: 1 2 3 4 5 6 7 8 9 10
every new s iteration: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100
every new t iteration: 2, 6, 12, 20, 30, 42, 56, 72, 90, 110
You might notice some nice patterns here. For example, s has a really nice formula to find out how many combined characters it has at any given iteration. It's simply (# of s iterations^2)*s.length. t also has a simple formula. It is (# of t iterations * (# of t iterations + 1))*t.length. You may have noticed that these formulas are the formulas for sum of odd and even numbers (if you did you get a kudos). This makes sense because each pattern's sum for an iteration i is the sum of all of its previous iterations.
Using s,t as length of their respective patterns, we now have the following formula to find the total number of chars at a given iteration.
#chars = s*(# of s iterations)^2 + t * (# of t iterations * (# of t iterations + 1))
Now we just need to do some math to get the number of iterations for each pattern given i.
# of s iterations given i = ceil(i/2.0)
# of t iterations given i = floor(i/2) which / operation gives us by default
Plugging these back into our formula we get:
total # of chars = s*(ceil(i/2.0)^2) + t*((i/2)*((i/2)+1))
We have just completed step 2, and we now know at any given iteration how many total chars there are. We could stop here and start picking random iterations and adjusting accordingly until we get near k, but we can do better than that. Let's use the above formula now to complete step 1 which we skipped. We just need to reorganize our equation to solve for i now.
Doing some simplyfying we get:
// 2
// i i i
// s (-) + t - ( - + 1 ) = k
// 2 2 2
// ----------------------------
// 2
// i t i
// s - + - ( - + 1 )i = k
// 4 2 2
// ----------------------------
// 2 2
// si ti ti
// ---- + ---- + ---- - k = 0
// 4 4 2
// ----------------------------
//
// 2 2
// si + ti + 2ti - 4k = 0
// ----------------------------
// 2
// (s + t)i + 2ti - 4k = 0
// ----------------------------
This looks like a polynomial. Wow! You're right! That means we can solve it using the quadratic formula.
A=(s+t), B=2t, C=-4k
quadratic formula = (-2t + sqrt(2t^2 + 16(s+t)k)) / 2(s+t)
This is our formula for step 1, and it will give us the iteration that the kth character is on. We just need to ceil it. I'm actually not smart enough to know why this works. It just does. Here is a desmos graph that graphs our two polynomials from step 2: s(Siterations)^2 and t(Titerations (Titerations + 1)).
The area under both curves is our total number of chars at an iteration (the vertical line). The formula from step 1 is also graphed, and we can see that for any s, t, k that the x intercept (which represents our xth iteration) is always: previous iteration < x <= current iteration, which is why the ceil works.
We have now completed steps 1 and 2. We have a formula to get the ith iteration that the kth character is on and a formula that gives us how many characters are in an ith iteration. Steps 3 and 4 should follow and we get our answer. This is constant time.
So this was a question on one of the challenges I came across in an online competition, a few days ago.
Question:
Accept two inputs.
A big number of N digits,
The number of questions Q to be asked.
In each of the question, you have to find if the number formed by the string between indices Li and Ri is divisible by 7 or not.
Input:
First line contains the number consisting on N digits. Next line contains Q, denoting the number of questions. Each of the next Q lines contains 2 integers Li and Ri.
Output:
For each question, print "YES" or "NO", if the number formed by the string between indices Li and Ri is divisible by 7.
Constraints:
1 ≤ N ≤ 105
1 ≤ Q ≤ 105
1 ≤ Li, Ri ≤ N
Sample Input:
357753
3
1 2
2 3
4 4
Sample Output:
YES
NO
YES
Explanation:
For the first query, number will be 35 which is clearly divisible by 7.
Time Limit: 1.0 sec for each input file.
Memory Limit: 256 MB
Source Limit: 1024 KB
My Approach:
Now according to the constraints, the maximum length of the number i.e. N can be upto 105. This big a number cannot be fitted into a numeric data structure and I am pretty sure thats not the efficient way to go about it.
First Try:
I thought of this algorithm to apply the generic rules of division to each individual digit of the number. This would work to check divisibility amongst any two numbers, in linear time, i.e. O(N).
static String isDivisibleBy(String theIndexedNumber, int divisiblityNo){
int moduloValue = 0;
for(int i = 0; i < theIndexedNumber.length(); i++){
moduloValue = moduloValue * 10;
moduloValue += Character.getNumericValue(theIndexedNumber.charAt(i));
moduloValue %= divisiblityNo;
}
if(moduloValue == 0){
return "YES";
} else{
return "NO";
}
}
But in this case, the algorithm has to also loop through all the values of Q, which can also be upto 105.
Therefore, the time taken to solve the problem becomes O(Q.N) which can also be considered as Quadratic time. Hence, this crossed the given time limit and was not efficient.
Second Try:
After that didn't work, I tried searching for a divisibility rule of 7. All the ones I found, involved calculations based on each individual digit of the number. Hence, that would again result in a Linear time algorithm. And hence, combined with the number of Questions, it would amount to Quadratic Time, i.e. O(Q.N)
I did find one algorithm named Pohlman–Mass method of divisibility by 7, which suggested
Using quick alternating additions and subtractions: 42,341,530
-> 530 − 341 = 189 + 42 = 231 -> 23 − (1×2) = 21 YES
But all that did was, make the time 1/3rd Q.N, which didn't help much.
Am I missing something here? Can anyone help me find a way to solve this efficiently?
Also, is there a chance this is a Dynamic Programming problem?
There are two ways to go through this problem.
1: Dynamic Programming Approach
Let the input be array of digits A[N].
Let N[L,R] be number formed by digits L to R.
Let another array be M[N] where M[i] = N[1,i] mod 7.
So M[i+1] = ((M[i] * 10) mod 7 + A[i+1] mod 7) mod 7
Pre-calculate array M.
Now consider the expression.
N[1,R] = N[1,L-1] * 10R-L+1 + N[L,R]
implies (N[1,R] mod 7) = (N[1,L-1] mod 7 * (10R-L+1mod 7)) + (N[L,R] mod 7)
implies N[L,R] mod 7 = (M[R] - M[L-1] * (10R-L+1 mod 7)) mod 7
N[L,R] mod 7 gives your answer and can be calculated in O(1) as all values on right of expression are already there.
For 10R-L+1 mod 7, you can pre-calculate modulo 7 for all powers of 10.
Time Complexity :
Precalculation O(N)
Overall O(Q) + O(N)
2: Divide and Conquer Approach
Its a segment tree solution.
On each tree node you store the mod 7 for the number formed by digits in that node.
And the expression given in first approach can be used to find the mod 7 of parent by combining the mod 7 values of two children.
The time complexity of this solution will be O(Q log N) + O(N log N)
Basically you want to be able to to calculate the mod 7 of any digits given the mod of the number at any point.
What you can do is to;
record the modulo at each point O(N) for time and space. Uses up to 100 KB of memory.
take the modulo at the two points and determine how much subtracting the digits before the start would make e.g. O(N) time and space (once not per loop)
e.g. between 2 and 3 inclusive
357 % 7 = 0
3 % 7 = 3 and 300 % 7 = 6 (the distance between the start and end)
and 0 != 6 so the number is not a multiple of 7.
between 4 and 4 inclusive
3577 % 7 == 0
357 % 7 = 0 and 0 * 10 % 7 = 0
as 0 == 0 it is a multiple of 7.
You first build a list of digits modulo 7 for each number starting with 0 offset (like in your case, 0%7, 3%7, 35%7, 357%7...) then for each case of (a,b) grab digits[a-1] and digits[b], then multiply digits[b] by 1-3-2-6-4-5 sequence of 10^X modulo 7 defined by (1+b-a)%6 and compare. If these are equal, return YES, otherwise return NO. A pseudocode:
readString(big);
Array a=[0]; // initial value
Array tens=[1,3,2,6,4,5]; // quick multiplier lookup table
int d=0;
int l=big.length;
for (int i=0;i<l;i++) {
int c=((int)big[i])-48; // '0' -> 0, and "big" has characters
d=(3*d+c)%7;
a.push(d); // add to tail
}
readInt(q);
for (i=0;i<q;i++) {
readInt(li);
readInt(ri); // get question
int left=(a[li-1]*tens[(1+ri-li)%6])%7;
if (left==a[ri]) print("YES"); else print("NO");
}
A test example:
247761901
1
5 9
61901 % 7=0. Calculating:
a = [0 2 3 2 6 3 3 4 5 2]
li = 5
ri = 9
left=(a[5-1]*tens[(1+9-5)%6])%7 = (6*5)%7 = 30%7 = 2
a[ri]=2
Answer: YES
I am trying to write a program that accepts an array of five four digit numbers and sorts the array based off the least significant digit. For example if the numbers were 1234, 5432, 4567, and 8978, the array would be sorted first by the last digit so the nest sort would be 5432, 1224, 4597, 8978. Then after it would be 1224, 5432, 8978, 4597. And so on until it is fully sorted.
I have wrote the code for displaying the array and part of it for sorting. I am not sure how to write the equations I need to compare each digit. This is my code for sorting by each digit so far:
public static void sortByDigit(int[] array, int size)
{
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
{
}
for(i = 0; i < size; i++)
{
System.out.println(array[i]);
}
}
}
I am not sure what to put in the nested for loop. I think I need to use the modulus.
I just wrote this to separate the digits but I don't know how to swap the numbers or compare them.
int first = array[i]%10;
int second = (array[i]%100)/10;
int third = (array[i]%1000)/10;
int fourth = (array[i]%10000)/10;
Would this would go in the for loop?
It seems like your problem is mainly just getting the value of a digit at a certain index. Once you can do that, you should be able to formulate a solution.
Your hunch that you need modulus is absolutely correct. The modulo operator (%) returns the remainder on a given division operation. This means that saying 10 % 2 would equal 0, as there is no remainder. 10 % 3, however, would yield 1, as the remainder is one.
Given that quick background on modulus, we just need to figure out how to make a method that can grab a digit. Let's start with a general signature:
public int getValueAtIdx(int value, int idx){
}
So, if we call getValueAtIdx(145, 2), it should return 1 (assuming that the index starts at the least significant digit). If we call getValueAtIdx(562354, 3), it should return 2. You get the idea.
Alright, so let's start by using figuring out how to do this on a simple case. Let's say we call getValueAtIdx(27, 0). Using modulus, we should be able to grab that 7. Our equation is 27 % x = 7, and we just need to determine x. So 27 divided by what will give us a remainder of 7? 10, of course! That makes our equation 27 % 10 = 7.
Now that's all find and dandy, but how does 10 relate to 0? Well, let's try and grab the value at index 1 this time (2), and see if we can't figure it out. With what we did last time, we should have something like 27 % x = 27 (WARNING: There is a rabbit-hole here where you could think x should be 5, but upon further examination it can be found that only works in this case). What if we take the 10 we used earlier, but square it (index+1)? That would give us 27 % 100 = 27. Then all we have to do is divide by 10 and we're good.
So what would that look like in the function we are making?
public int getValueAtIdx(int value, int idx){
int modDivisor = (int) Math.pow(10, (idx+1));
int remainder = value % modDivisor;
int digit = remainder / (modDivisor / 10);
return digit;
}
Ok, so let's to back to the more complicated example: getValueAtIdx(562354, 3).
In the first step, modDivisor becomes 10^4, which equals 10000.
In the second step, remainder is set to 562354 % 10000, which equals 2354.
In the third and final step, digit is set to remainder / (10000 / 10). Breaking that down, we get remainder / 1000, which (using integer division) is equal to 2.
Our final step is return the digit we have acquired.
EDIT: As for the sort logic itself, you may want to look here for a good idea.
The general process is to compare the two digits, and if they are equal move on to their next digit. If they are not equal, put them in the bucket and move on.
I somehow have to keep my program running until the output of the exponent function exceeds the input value, and then compare that to the previous output of the exponent function. How would I do something like that, even if in just pseudocode?
Find logarithm to base 2 from given number => x := log (2, input)
Round the value acquired in step 1 both up and down => y := round(x), z := round(x) + 1
Find 2^y, 2^z, compare them both with input and choose the one that suits better
Depending on which language you're using, you can do this easily using bitwise operations. You want either the value with a single 1 bit set greater than the highest one bit set in the input value, or the value with the highest one bit set in the input value.
If you do set all of the bits below the highest set bit to 1, then add one you end up with the next greater power of two. You can right shift this to get the next lower power of two and choose the closer of the two.
unsigned closest_power_of_two(unsigned value)
{
unsigned above = (value - 1); // handle case where input is a power of two
above |= above >> 1; // set all of the bits below the highest bit
above |= above >> 2;
above |= above >> 4;
above |= above >> 8;
above |= above >> 16;
++above; // add one, carrying all the way through
// leaving only one bit set.
unsigned below = above >> 1; // find the next lower power of two.
return (above - value) < (value - below) ? above : below;
}
See Bit Twiddling Hacks for other similar tricks.
Apart from the looping there's also one solution that may be faster depending on how the compiler maps the nlz instruction:
public int nextPowerOfTwo(int val) {
return 1 << (32 - Integer.numberOfLeadingZeros(val - 1));
}
No explicit looping and certainly more efficient than the solutions using Math.pow. Hard to say more without looking what code the compiler generates for numberOfLeadingZeros.
With that we can then easily get the lower power of 2 and then compare which one is nearer - the last part has to be done for each solution it seems to me.
set x to 1.
while x < target, set x = 2 * x
then just return x or x / 2, whichever is closer to the target.
public static int neareastPower2(int in) {
if (in <= 1) {
return 1;
}
int result = 2;
while (in > 3) {
in = in >> 1;
result = result << 1;
}
if (in == 3) {
return result << 1;
} else {
return result;
}
}
I will use 5 as input for an easy example instead of 50.
Convert the input to bits/bytes, in this case 101
Since you are looking for powers of two, your answer will all be of the form 10000...00 (a one with a certain amount of zeros). You take the input value (3 bits) and calculate the integer value of 100 (3 bits) and 1000 (4 bits). The integer 100 will be smaller then the input, the integer 1000 will be larger.
You calculate the difference between the input and the two possible values and use the smallest one. In this case 100 = 4 (difference of 1) while 1000 = 8 (difference of 3), so the searched answer is 4
public static int neareastPower2(int in) {
return (int) Math.pow(2, Math.round(Math.log(in) / Math.log(2)));
}
Here's the pseudo code for a function that takes the input number and returns your answer.
int findit( int x) {
int a = int(log(x)/log(2));
if(x >= 2^a + 2^(a-1))
return 2^(a+1)
else
return 2^a
}
Here's a bitwise solution--it will return the lessor of 2^N and 2^(N+1) in case of a tie. This should be very fast compare to invoking the log() function
let mask = (~0 >> 1) + 1
while ( mask > value )
mask >> 1
return ( mask & value == 0 ) ? mask : mask << 1
I have the methods that do both the multiplication and addition, but I'm just not able to get my head around them. Both of them are from external websites and not my own:
public static void bitwiseMultiply(int n1, int n2) {
int a = n1, b = n2, result=0;
while (b != 0) // Iterate the loop till b==0
{
if ((b & 01) != 0) // Logical ANDing of the value of b with 01
{
result = result + a; // Update the result with the new value of a.
}
a <<= 1; // Left shifting the value contained in 'a' by 1.
b >>= 1; // Right shifting the value contained in 'b' by 1.
}
System.out.println(result);
}
public static void bitwiseAdd(int n1, int n2) {
int x = n1, y = n2;
int xor, and, temp;
and = x & y;
xor = x ^ y;
while (and != 0) {
and <<= 1;
temp = xor ^ and;
and &= xor;
xor = temp;
}
System.out.println(xor);
}
I tried doing a step-by-step debug, but it really didn't make much sense to me, though it works.
What I'm possibly looking for is to try and understand how this works (the mathematical basis perhaps?).
Edit: This is not homework, I'm just trying to learn bitwise operations in Java.
Let's begin by looking the multiplication code. The idea is actually pretty clever. Suppose that you have n1 and n2 written in binary. Then you can think of n1 as a sum of powers of two: n2 = c30 230 + c29 229 + ... + c1 21 + c0 20, where each ci is either 0 or 1. Then you can think of the product n1 n2 as
n1 n2 =
n1 (c30 230 + c29 229 + ... + c1 21 + c0 20) =
n1 c30 230 + n1 c29 229 + ... + n1 c1 21 + n1 c0 20
This is a bit dense, but the idea is that the product of the two numbers is given by the first number multiplied by the powers of two making up the second number, times the value of the binary digits of the second number.
The question now is whether we can compute the terms of this sum without doing any actual multiplications. In order to do so, we're going to need to be able to read the binary digits of n2. Fortunately, we can do this using shifts. In particular, suppose we start off with n2 and then just look at the last bit. That's c0. If we then shift the value down one position, then the last bit is c0, etc. More generally, after shifting the value of n2 down by i positions, the lowest bit will be ci. To read the very last bit, we can just bitwise AND the value with the number 1. This has a binary representation that's zero everywhere except the last digit. Since 0 AND n = 0 for any n, this clears all the topmost bits. Moreover, since 0 AND 1 = 0 and 1 AND 1 = 1, this operation preserves the last bit of the number.
Okay - we now know that we can read the values of ci; so what? Well, the good news is that we also can compute the values of the series n1 2i in a similar fashion. In particular, consider the sequence of values n1 << 0, n1 << 1, etc. Any time you do a left bit-shift, it's equivalent to multiplying by a power of two. This means that we now have all the components we need to compute the above sum. Here's your original source code, commented with what's going on:
public static void bitwiseMultiply(int n1, int n2) {
/* This value will hold n1 * 2^i for varying values of i. It will
* start off holding n1 * 2^0 = n1, and after each iteration will
* be updated to hold the next term in the sequence.
*/
int a = n1;
/* This value will be used to read the individual bits out of n2.
* We'll use the shifting trick to read the bits and will maintain
* the invariant that after i iterations, b is equal to n2 >> i.
*/
int b = n2;
/* This value will hold the sum of the terms so far. */
int result = 0;
/* Continuously loop over more and more bits of n2 until we've
* consumed the last of them. Since after i iterations of the
* loop b = n2 >> i, this only reaches zero once we've used up
* all the bits of the original value of n2.
*/
while (b != 0)
{
/* Using the bitwise AND trick, determine whether the ith
* bit of b is a zero or one. If it's a zero, then the
* current term in our sum is zero and we don't do anything.
* Otherwise, then we should add n1 * 2^i.
*/
if ((b & 1) != 0)
{
/* Recall that a = n1 * 2^i at this point, so we're adding
* in the next term in the sum.
*/
result = result + a;
}
/* To maintain that a = n1 * 2^i after i iterations, scale it
* by a factor of two by left shifting one position.
*/
a <<= 1;
/* To maintain that b = n2 >> i after i iterations, shift it
* one spot over.
*/
b >>>= 1;
}
System.out.println(result);
}
Hope this helps!
It looks like your problem is not java, but just calculating with binary numbers. Start of simple:
(all numbers binary:)
0 + 0 = 0 # 0 xor 0 = 0
0 + 1 = 1 # 0 xor 1 = 1
1 + 0 = 1 # 1 xor 0 = 1
1 + 1 = 10 # 1 xor 1 = 0 ( read 1 + 1 = 10 as 1 + 1 = 0 and 1 carry)
Ok... You see that you can add two one digit numbers using the xor operation. With an and you can now find out whether you have a "carry" bit, which is very similar to adding numbers with pen&paper. (Up to this point you have something called a Half-Adder). When you add the next two bits, then you also need to add the carry bit to those two digits. Taking this into account you can get a Full-Adder. You can read about the concepts of Half-Adders and Full-Adders on Wikipedia:
http://en.wikipedia.org/wiki/Adder_(electronics)
And many more places on the web.
I hope that gives you a start.
With multiplication it is very similar by the way. Just remember how you did multiplying with pen&paper in elementary school. Thats what is happening here. Just that it's happening with binary numbers and not with decimal numbers.
EXPLANATION OF THE bitwiseAdd METHOD:
I know this question was asked a while back but since no complete answer has been given regarding how the bitwiseAdd method works here is one.
The key to understanding the logic encapsulated in bitwiseAdd is found in the relationship between addition operations and xor and and bitwise operations. That relationship is defined by the following equation (see appendix 1 for a numeric example of this equation):
x + y = 2 * (x&y)+(x^y) (1.1)
Or more simply:
x + y = 2 * and + xor (1.2)
with
and = x & y
xor = x ^ y
You might have noticed something familiar in this equation: the and and xor variables are the same as those defined at the beginning of bitwiseAdd. There is also a multiplication by two, which in bitwiseAdd is done at the beginning of the while loop. But I will come back to that later.
Let me also make a quick side note about the '&' bitwise operator before we proceed further. This operator basically "captures" the intersection of the bit sequences against which it is applied. For example, 9 & 13 = 1001 & 1101 = 1001 (=9). You can see from this result that only those bits common to both bit sequences are copied to the result. It derives from this that when two bit sequences have no common bit, the result of applying '&' on them yields 0. This has an important consequence on the addition-bitwise relationship which shall become clear soon
Now the problem we have is that equation 1.2 uses the '+' operator whereas bitwiseAdd doesn't (it only uses '^', '&' and '<<'). So how do we make the '+' in equation 1.2 somehow disappear? Answer: by 'forcing' the and expression to return 0. And the way we do that is by using recursion.
To demonstrate this I am going to recurse equation 1.2 one time (this step might be a bit challenging at first but if needed there's a detailed step by step result in appendix 2):
x + y = 2*(2*and & xor) + (2*and ^ xor) (1.3)
Or more simply:
x + y = 2 * and[1] + xor[1] (1.4)
with
and[1] = 2*and & xor,
xor[1] = 2*and ^ xor,
[1] meaning 'recursed one time'
There's a couple of interesting things to note here. First you noticed how the concept of recursion sounds close to that of a loop, like the one found in bitwiseAdd in fact. This connection becomes even more obvious when you consider what and[1] and xor[1] are: they are the same expressions as the and and xor expressions defined INSIDE the while loop in bitwiseAdd. We also note that a pattern emerges: equation 1.4 looks exactly like equation 1.2!
As a result of this, doing further recursions is a breeze, if one keeps the recursive notation. Here we recurse equation 1.2 two more times:
x + y = 2 * and[2] + xor[2]
x + y = 2 * and[3] + xor[3]
This should now highlight the role of the 'temp' variable found in bitwiseAdd: temp allows to pass from one recursion level to the next.
We also notice the multiplication by two in all those equations. As mentioned earlier this multiplication is done at the begin of the while loop in bitwiseAdd using the and <<= 1 statement. This multiplication has a consequence on the next recursion stage since the bits in and[i] are different from those in the and[i] of the previous stage (and if you recall the little side note I made earlier about the '&' operator you probably see where this is going now).
The general form of equation 1.4 now becomes:
x + y = 2 * and[x] + xor[x] (1.5)
with x the nth recursion
FINALY:
So when does this recursion business end exactly?
Answer: it ends when the intersection between the two bit sequences in the and[x] expression of equation 1.5 returns 0. The equivalent of this in bitwiseAdd happens when the while loop condition becomes false. At this point equation 1.5 becomes:
x + y = xor[x] (1.6)
And that explains why in bitwiseAdd we only return xor at the end!
And we are done! A pretty clever piece of code this bitwiseAdd I must say :)
I hope this helped
APPENDIX:
1) A numeric example of equation 1.1
equation 1.1 says:
x + y = 2(x&y)+(x^y) (1.1)
To verify this statement one can take a simple example, say adding 9 and 13 together. The steps are shown below (the bitwise representations are in parenthesis):
We have
x = 9 (1001)
y = 13 (1101)
And
x + y = 9 + 13 = 22
x & y = 9 & 13 = 9 (1001 & 1101 = 1001)
x ^ y = 9^13 = 4 (1001 ^ 1101 = 0100)
pluging that back into equation 1.1 we find:
9 + 13 = 2 * 9 + 4 = 22 et voila!
2) Demonstrating the first recursion step
The first recursion equation in the presentation (equation 1.3) says that
if
x + y = 2 * and + xor (equation 1.2)
then
x + y = 2*(2*and & xor) + (2*and ^ xor) (equation 1.3)
To get to this result, we simply took the 2* and + xor part of equation 1.2 above and applied the addition/bitwise operands relationship given by equation 1.1 to it. This is demonstrated as follow:
if
x + y = 2(x&y) + (x^y) (equation 1.1)
then
[2(x&y)] + (x^y) = 2 ([2(x&y)] & (x^y)) + ([2(x&y)] ^ (x^y))
(left side of equation 1.1) (after applying the addition/bitwise operands relationship)
Simplifying this with the definitions of the and and xor variables of equation 1.2 gives equation 1.3's result:
[2(x&y)] + (x^y) = 2*(2*and & xor) + (2*and ^ xor)
with
and = x&y
xor = x^y
And using that same simplification gives equation 1.4's result:
2*(2*and & xor) + (2*and ^ xor) = 2*and[1] + xor[1]
with
and[1] = 2*and & xor
xor[1] = 2*and ^ xor
[1] meaning 'recursed one time'
Here is another approach for Multiplication
/**
* Multiplication of binary numbers without using '*' operator
* uses bitwise Shifting/Anding
*
* #param n1
* #param n2
*/
public static void multiply(int n1, int n2) {
int temp, i = 0, result = 0;
while (n2 != 0) {
if ((n2 & 1) == 1) {
temp = n1;
// result += (temp>>=(1/i)); // To do it only using Right shift
result += (temp<<=i); // Left shift (temp * 2^i)
}
n2 >>= 1; // Right shift n2 by 1.
i++;
}
System.out.println(result);
}