I am coding something to decompose a number in binary on a training site. I have test it a hundred of times on my local compiler, it works just fine, but the training site tells me there are errors.
(My code is nor elegant nor efficient, especially the loop but I decomposed the code to understand where the error could be). Could anybody tell me if there is an error ?
#include <stdio.h>
#include <stdlib.h>
//function that displays the greatest power of 2 less than a fixed number N
int residu(int N)
{
int i;
int M=2;
for(i=0;i<N;i++){
if(M>N){break;}else{M=2*M;i++;}
}
return M/2;
}
int main()
{
int i;
//N is the input to decompose
int N;
scanf("%d",&N);
//We will search for the greatest power of 2 less than a fixed number N,
//than repeating the some process with the residue of N with the greatest power of 2 //less than N, so we have to store the value of N for the loop (see below) we will use to work //correctly
int M;
M=N;
//D displays the diffrence betwenn two successive powers of 2 that appears in the //binary decomposition, (we will then print "O")
int D;
D=log(residu(N))/log(2);
for(i=0;i<M;i++){
//If N==residu(N), the decomposition is finished
if(N==residu(N)){printf("1");int k;
for(k=0;k<D;k++){printf("0");}break;}
else{
// N is a the residue of the former value of N and the greatest power of 2 //less than N
N=N-residu(N);
D=D-log(residu(N))/log(2);
printf("1");
int k;
for(k=0;k<D-1;k++){printf("0");
}
D=log(residu(N))/log(2);
}
}
}
This is a typical problem of floating point calculations. The function
logworks with floats.log(8) / log(2)is being calculated as2.999...which is then truncated to2when being converted toint.That’s why you are getting wrong results. And the exact behavior is compiler/machine dependent. For further reading see e.g. Goldberg.
It is in general a bad idea to mix integer and floating point calculations that way. Your function
residushould report back the exact binary logarithm. Or you implement a dedicated function for calculating the log in integer, something like