I've got some code for you guys.
This is the first step of the splitting algorithm for the Fast Fourier Transform.
What the algorithm should do is reorder the array such that every element on the input will be displaced in the "binary mirrored" position of the output.
For example, the element X[4] will be in position X[1], since the mirrored representation of 100 is 001.
Till here, everything is clear. However, the algorithm that does such reordering is not. Atleast I have a hard time understanding.
What does the second, inner loop do?
// N is the length of the array
// p is the number of bits needed to represent the index
for(int n=0; n<N; n++) {
int j=0;
int m=n;
for(int i=0; i<p; i++) {
j = 2∗j + m%2; m = m/2;
}
if ( j>n) {
complex<double> h;
h = X[j];
X[j] = X[n];
X[n] = h;
}
}
Think of an integer as being a sequence of bits.
j = 2j this pops the bit on the left and pushes zero into the right
m % 2 this obtains the right bit
m = m / 2 pops the bit on the right and pushes a copy of the leftmost bit on the left
j + x sets the rightmost bit of j to x, assuming that bit is currently zero and that x is 0 or 1
so all this is doing is popping bits off of the right of m and pushing them onto the right of j.
Each iteration, we multiply j by 2 (which is the same as shifting left by 1), then add the parity of m. Then we do integer division of m by two (which is the same as shifting right by 1). m starts with the value of n. So we are essentially reversing the bits in n, and storing it in j.
Related
I am trying to learn some C programming, and to test my basic skills, I am making a simple program that computes factorials. However, instead of giving the correct answer of 120 for the factorial of 5, it gives -1899959296. What's wrong? Here's my code below:
#include <stdio.h>
int factorial(int x)
{
int i;
for(i=1; i < x; i++)
x *= i;
return x;
}
int main()
{
int a = 5, b;
b = factorial(a);
printf("The factorial of %d is %d \n", a, b);
return 0;
}
Thanks in advance!
Your problem is that the function factorial() is continually modifying x. For any of x which is initially 3 or more, x will keep increasing, so the loop will keep running.
Consider if you call fact(3).
The function is called with x = 3. First iteration of the loop with i = 1 will multiply x by 1. So x will still have the value of 3. i i will be incremented to 2, which is less than 3, so the next iteration starts.
The second iteration of the loop will multiply x by 2, giving the result of 6. i is incremented to 3, which is less than 6, so the next iteration starts.
The third iteration will multiply x by 3, giving the result of 18. i is incremented to 4, which is less than 18, so the next iteration starts.
Notice the pattern in the above ..... the end condition is i < x. i is incremented in each iteration. x is multiplied by i. This means that x increases substantially faster than i does .... which means i < x is always true.
Well almost ..... eventually the logic breaks down.
Eventually x will overflow - the result of multiplying it by i will produce a result that exceeds what can be stored in an int. The result of overflowing an int is undefined ..... anything can happen at that point.
Compare the description above with what YOU would do if asked to compute the factorial of 3. Would you do similar steps? Probably not.
int factorial(int x)
{
int i;
int count =x;
for(i=1; i < count ; i++)
x *= i;
return x;
}
Modify like this. your issue is with the loop count.. Since value of x is changing the loop may become infinite..
C) You're using x as an upperbound for your for loop i < x
B) You're also increasing x nearly exponentially on every loop x *= i, your loop won't work.
You might have noticed that you get a negative number back. The reason the loop exits at all is that you've chosen to type x as a 32 bit signed integer (the default int)- The processor works in binary: so once you go higher than is actually possible with just 32 bits, it still tries to do math but it loses data and loops back around to negative numbers. So once x loops back around and becomes negative, then i > x and the loop exits.
Here: http://tpcg.io/8sX5ls
The error is in the for, the factorial of a number is n * n-1 * ... * n-(n-1), so to solve this, just start the index in x - 1 and decrement it until it turns 1, sorry for my bad English, I hope you understood what I said.
here is the answer:
for ( i = x - 1; i > 1; --i )
x *= i;
Just to explain why the negative number, first we must understand what happens in the for which it was declared.
for(i=1; i < x; i++)
x *= i;
As we can see the condition for it to continue in the loop is i < x, but within it is assigned to x the value of x * i (x * = i or x = x * i), so x has no constant value and is always increasing, the i increases at a velocity smaller than that of x because the i is always added to 1 (i ++, i + = 1 or i = i + 1), which causes the x to be unreachable , then the for will be in an infinite loop.
But every type has its range, and int is 4 bytes, therefore 32 bit, what happens is that there comes a time when x exceeds this range having the famous integer overflow, this is why its value is negative, then the condition of the for becomes false and then the for stop.
We have to remember that a number is represented in memory in binary form, and the last binary number is what represents whether the number is positive or negative, 0 is positive, 1 is negative, when integer overflow happens the last number changes to 1 , making it so negative.
To better understand this here are some links that can help:
https://en.wikipedia.org/wiki/Two%27s_complement
https://en.wikipedia.org/wiki/Integer_overflow.
For an assignment we are required to write a division algorithm in order to complete a certain question using just addition and recursion. I found that, without using tail recursion, the naive repeated subtraction implementation can easily result in a stack overflow. So doing a quick analysis of this method, and correct me if I'm wrong, shows that if you divide A by B, with n and m binary digits respectively, it should be exponential in n-m. I actually get
O( (n-m)*2^(n-m) )
since you need to subtract an m binary digit number from an n binary digit number 2^(n-m) times in order to drop the n digit number to an n-1 digit number, and you need to do this n-m times to get a number with at most m digits in the repeated subtraction division, so the runtime should be as mentioned. Again, I very well may be wrong so someone please correct me if I am. This is assuming O(1) addition since I'm working with fixed size integers. I suppose with fixed size integers one could argue the algorithm is O(1).
Back to my main question. I developed a different method to perform integer division which works much better, even when using it recursively, based on the idea that for
P = 2^(k_i) + ... 2^(K_0)
we have
A/B = (A - B*P)/B + P
The algorithm goes as follows to caclulate A/B:
input:
A, B
i) Set Q = 0
ii) Find the largest K such that B * 2^K <= A < B * 2(K + 1)
iii) Q -> Q + 2^K
iv) A -> A - B * 2^k
v) Repeat steps ii) through iv) until A <= B
vi) Return Q (and A if you want the remainder)
with the restrictions of using only addition, I simply add B to itself on each recursive call, however here is my code without recursion and with the use of shifts instead of addition.
int div( unsigned int m, unsigned int n )
{
// q is a temporary n, sum is the quotient
unsigned int q, sum = 0;
int i;
while( m > n )
{
i = 0;
q = n;
// double q until it's larger than m and record the exponent
while( q <= m )
{
q <<= 1;
++i;
}
i--;
q >>= 1; // q is one factor of 2 too large
sum += (1<<i); // add one bit of the quotient
m -= q; // new numerator
}
return sum;
}
I feel that sum |= (1<<i) may be more appropriate in order to emphasize I'm dealing with a binary representation, but it didn't seem to give any performance boost and may make it harder to understand. So, if M and N are the number of bits in m and n respectively, an analysis suggests the inner loop is performed M - N times and each time the outer loop is completed that m looses one bit, and it must also be completed M - N times in order for the condition m <= n so I get that it's O( (M - N)^2 ).
So after all of that, I am asking if I am correct about the runtime of the algorithm and whether it can be improved upon?
Your algorithm is pretty good and your analysis of the running time is correct, but you don't need to do the inner loop every time:
unsigned div(unsigned num, unsigned den)
{
//TODO check for divide by zero
unsigned place=1;
unsigned ret=0;
while((num>>1) >= den) //overflow-safe check
{
place<<=1;
den<<=1;
}
for( ;place>0; place>>=1,den>>=1)
{
if (num>=den)
{
num-=den;
ret+=place;
}
}
return ret;
}
That makes it O(M-N)
Given an array with n+2 elements, all elements in the array are in the range 1 to n and all elements occur only once except two elements which occur twice.
Find those 2 repeating numbers. For example, if the array is [4, 2, 4, 5, 2, 3, 1], then n is 5, there are n+2 = 7 elements with all elements occurring only once except 2 and 4.
So my question is how to solve the above problem using XOR operation. I have seen the solution on other websites but I'm not able to understand it. Please consider the following example:
arr[] = {2, 4, 7, 9, 2, 4}
XOR every element. xor = 2^4^7^9^2^4 = 14 (1110)
Get a number which has only one set bit of the xor. Since we can easily get the rightmost set bit, let us use it.
set_bit_no = xor & ~(xor-1) = (1110) & ~(1101) = 0010. Now set_bit_no will have only set as rightmost set bit of xor.
Now divide the elements in two sets and do xor of elements in each set, and we get the non-repeating elements 7 and 9.
Yes, you can solve it with XORs. This answer expands on Paulo Almeida's great comment.
The algorithm works as follows:
Since we know that the array contains every element in the range [1 .. n], we start by XORing every element in the array together and then XOR the result with every element in the range [1 .. n]. Because of the XOR properties, the unique elements cancel out and the result is the XOR of the duplicated elements (because the duplicate elements have been XORed 3 times in total, whereas all the others were XORed twice and canceled out). This is stored in xor_dups.
Next, find a bit in xor_dups that is a 1. Again, due to XOR's properties, a bit set to 1 in xor_dups means that that bit is different in the binary representation of the duplicate numbers. Any bit that is a 1 can be picked for the next step, my implementation chooses the least significant. This is stored in diff_bit.
Now, split the array elements into two groups: one group contains the numbers that have a 0 bit on the position of the 1-bit that we picked from xor_dups. The other group contains the numbers that have a 1-bit instead. Since this bit is different in the numbers we're looking for, they can't both be in the same group. Furthermore, both occurrences of each number go to the same group.
So now we're almost done. Consider the group for the elements with the 0-bit. XOR them all together, then XOR the result with all the elements in the range [1..n] that have a 0-bit on that position, and the result is the duplicate number of that group (because there's only one number repeated inside each group, all the non-repeated numbers canceled out because each one was XORed twice except for the repeated number which was XORed three times).
Rinse, repeat: for the group with the 1-bit, XOR them all together, then XOR the result with all the elements in the range [1..n] that have a 1-bit on that position, and the result is the other duplicate number.
Here's an implementation in C:
#include <assert.h>
void find_two_repeating(int arr[], size_t arr_len, int *a, int *b) {
assert(arr_len > 3);
size_t n = arr_len-2;
int i;
int xor_dups = 0;
for (i = 0; i < arr_len; i++)
xor_dups ^= arr[i];
for (i = 1; i <= n; i++)
xor_dups ^= i;
int diff_bit = xor_dups & -xor_dups;
*a = 0;
*b = 0;
for (i = 0; i < arr_len; i++)
if (arr[i] & diff_bit)
*a ^= arr[i];
else
*b ^= arr[i];
for (i = 1; i <= n; i++)
if (i & diff_bit)
*a ^= i;
else
*b ^= i;
}
arr_len is the total length of the array arr (the value of n+2), and the repeated entries are stored in *a and *b (these are so-called output parameters).
How to find the repeated number and missing number as well using xor?
For eg: actual = [1,2,3] input_received = [3,2,3]. Here the missing number is 1 and the repeated number is 3. I found a quite interesting solution while surfing,
int missing_and_repeating(int a[], int n, int size){
int xor =0;
int i;
int x =0 , y =0;
for(i=0; i<size; i++)
xor = xor^a[i];
for(i=1; i<=n; i++)
xor = xor^i;
// Get the rightmost bit which is set
int set_bit_no = xor & ~(xor -1);
// XOR numbers in two buckets
for(i=0; i<size; i++){
if(a[i]& set_bit_no){
x = x^a[i];
}
else
y = y^ a[i];
}
for(i=1; i<=n; i++){
if(i & set_bit_no)
x = x^i;
else
y = y^i;
}
printf("\n %d %d ", x,y );
}
'actual' array is XORed and 'input_received' array is XORed
set_bit_no is assigned and both the arrays are split into two halves according to set_bit_no.
So again go back to our array and numbers from 1 to N-1 and 0 to size and XOR numbers in two buckets, one buckets contains XOR result of XORing all numbers with given bit set and other bucket contains XOR result of XORing all numbers with given bit reset.
I could not understand what set_bit_no is and why they are taking it, and how the array is split according to it. Someone please help me with a short example.
I assume that pre-condition is that exactly one array element is missing and instead replaced by a duplicate of another element. So, actual = {a1, a2, ..., an} and input_received = {a2, a2,..., an} (we can always rearrange elements so that a1 is missing and a2 is repeated).
So when you xor all elements from both arrays you get xored = a1 ^ a2.
Now we have to decompose that number to know a1 and a2. You take one of the non-zero bits (doesn't mater which one, the easiest way is to take the least significant like it's done in the code, and you always have one if a1 != a2). This bit is set in only one of numbers a1 or a2. So you xor all numbers which have this bit, and they'll annihilate each other, leaving only a1 or a2, and you xor all other numbers, so the result will be another number - a2 or a1 respectively.
It's important to note that this algorithm doesn't tell which of these numbers is missing and which is repeated. This is demonstrated by the following code:
int main() {
int arr1[] = {1, 1};
missing_and_repeating(arr1, 2, 2);
int arr2[] = {2, 2};
missing_and_repeating(arr2, 2, 2);
}
Output:
1 2
1 2
Confused as to what this code does
for (L=0; L < levels; L++, N_half>>=1){
func( y, N_half);
} // end: levels for loop
In particular this " N_half>>=1 "
Thanks
It advances the loop by dividing N_half by two at every iteration. It is equivalent to:
for (L=0; L<levels; ++L, N_half=N_half / 2) {
...
}
N_half>>=1 performs a 1-place bitwise shift-right on N_half, which (for non-negative numbers) divides it by 2.
>>= is to >> as += is to +.
>>= operator shifts number's digits k positions at right
examples:
binary form
N = 101010111 // 2-base arithmetic system
N >>= 1; // `division` by 2
N: 010101011
decimal form
N = 123456 // 10-base arithmetic system
N >>= 2; // `division` by 10^2
N: 001234
as usual, the numbers in memory are in binary form and >>=1 is equivalent to division by 2.
If N_half is a positive or unsigned integer, it halves it.
It right shifts N_half by 1 (i.e. divides it by two) and stores the result back in N_half
This seems to be the same as
for (L=0; L < levels; L++)
{
func(y, N_Half);
N_Half /= 2;
}
The question has been rephrased since I answered it, such that this is no longer valid, but added for completeness: If nothing else is done within the loop, it is equivalent to:
N_Half >>= levels;
Caveats:
if N_Half < 2^levels (0 for several iterations)
if N_Half < 0 (first rightshift will depending on the implementation make it a positive number)