How can I interleave a section of two binary numbers? [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am trying to "merge" two binary integers into one but I can't seem to get it right.
The operation I am trying to do is:
Number of bits to merge = 3 (precomputed parameter)
Int 1 : 10010
Int 2 : 11011
Given these two numbers, append 3 bit of each to the result (left to right):
Result : 11 01 00.
Meaning the first bit of the first integer
and the first bit of the second integer. Then the second bit of
the first integer and the second bit of the secod integer... and so on
"Number of bits to merge" times.
Another example with letters would be:
Number of bits to merge = 4
Int1: abcde
Int2: xyzwt
Result: ax by cz dw
My idea is to use a for loop with the ammount of bits I have to set and there append to the result number, but I don't know how to do that "appending".

You can set each bit in a loop:
std::uint32_t merge(std::size_t start, std::size_t numberOfBits, int i1, int i2) {
if (start == 0 || start > sizeof(int) * 8) return 0;
if (numberOfBits == 0 || numberOfBits > 16) return 0;
if (start < numberOfBits) return 0;
int result = 0;
for (std::size_t i = 0; i < numberOfBits; ++i) {
std::size_t srcPos = start - 1 - i;
std::size_t destPos = 2 * (numberOfBits - i) - 1;
result |= (i1 & (1 << srcPos)) >> srcPos << destPos;
result |= (i2 & (1 << srcPos)) >> srcPos << (destPos - 1);
}
return result;
}
int main() {
std::size_t start = 5;
std::size_t numberOfBits = 3;
int i1 = 0b10010;
int i2 = 0b11011;
return merge(start, numberOfBits, i1, i2);
}
i1 & (1 << (start - 1 - i)) reads the i-th bit from left. >> (start - 1 - i) shifts it to the right. << (2 * (numberOfBits - i) - 1) resp. << (2 * (numberOfBits - i) - 2) shifts it to the correct position in the result.
Tested with input:
Start : 5
Number of bits : 3
Int 1 : 0b10010
Int 2 : 0b11011
output:
52 // == 0b110100
and input:
Start : 4
Number of bits : 2
Int 1 : 0b1010
Int 2 : 0b0101
output:
9 // == 0b1001

Create a bit mask, used to select which and how many bits to keep:
int mask = (1 << 3) - 1; // results in 0000 0000 0000 0111
Next you have to think about which bit locations you want from each input integer, I will call them i1 and i2:
// i1 = 0000 0000 0001 0010
// i2 = 0000 0000 0001 1011
int mask_shifted = mask << 3; // results in 0000 0000 0011 1000
Now you can apply the masks to the ints and merge the result with bit operations:
int applied_i1 = i1 & mask_i1; // results in 0000 0000 0001 0000
int applied_i2 = i2 & mask_i2; // results in 0000 0000 0001 1000
int result = (applied_i2 << 1) | (applied_i1 >> 3); // results in 0000 0000 0011 0100

Related

Elements switch places on compilation? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I've been running into this really odd bug where a element of my array will swap places with another. I can solve the issue by manually changing the elements before compiling but for ease of access I want to keep it the way it is. My goal was to compare bits and store the result in an array. There is no function I actively call after I call that function so it doesn't change the array itself. It does the exact same thing when I declare the array as constants.
Here's my array:
int myconsts[8][8] = {
{ 6, 10, 0, 9, 14, 6, 6, 7 }
};
My issue as that number 14 (myconsts[4]) and 7 (myconsts[7]) would randomly swap places. Here's how I compare bits in my function
std::array<std::array<int, 4>, 8> myfunct(int arr[][8]) {
std::array<std::array<int, 4>, 8> arr2;
int i = 0;
do {
std::bitset<4> num1(arr[0][i]);
std::bitset<4> num2(arr[1][i]);
std::bitset<4> num3(arr[2][i]);
int no;
int no2;
int no3;
for (int x = 0; x < 4; x++) {
int sum = 0;
std::cout << num1[x] << " Num: " << num1[0] << num1[1] << num1[2] << num1[3] << std::endl;
}
std::cout << " " << std::endl;
i++;
} while (i < 8);
//just testing the logic
arr2 = { 0 };
return arr2;
}
Output:
[0]
0 Num: 0110
1 Num : 0110
1 Num : 0110
0 Num : 0110
[1]
0 Num : 0101
1 Num : 0101
0 Num : 0101
1 Num : 0101
[2]
0 Num : 0000
0 Num : 0000
0 Num : 0000
0 Num : 0000
[3]
1 Num : 1001
0 Num : 1001
0 Num : 1001
1 Num : 1001
Here is where it swaps positions with the original element[7]!
[4]
0 Num : 0111
1 Num : 0111
1 Num : 0111
1 Num : 0111
[5]
0 Num : 0110
1 Num : 0110
1 Num : 0110
0 Num : 0110
[6]
0 Num : 0110
1 Num : 0110
1 Num : 0110
0 Num : 0110
[7]
1 Num : 1110
1 Num : 1110
1 Num : 1110
0 Num : 1110
It's elements[0..7], every space in between represents a new element. I'm not sure if it's the same on all compilers.
I do not see what you are describing.
Here is my annotations on your output:
0 Num : 0111 // This is 2 + 4 + 8 = 14
1 Num : 0111
1 Num : 0111
1 Num : 0111
0 Num : 0110 // This is 2 + 4 = 6
1 Num : 0110
1 Num : 0110
0 Num : 0110
0 Num : 0110 // This is 2 + 4 = 6
1 Num : 0110
1 Num : 0110
0 Num : 0110
1 Num : 1110 // This is 1 + 2 + 4 = 7
1 Num : 1110
1 Num : 1110
0 Num : 1110
It looks like you just dumped: ..., 14, 6, 6, 7 };
which are the final 4 elements of your array.
I'd say everything looks correct.
Perhaps you are reading your bits backwards on screen, since LSB (least significant bit) is typically put on the far right, and you've put it on the far left.
But your code is working fine.

Inverting the bits of an even number in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
A girl writes N numbers on the board (odd and even numbers) and then, she modifies only even numbers and inverts its binary representation (from the left to the right ) and replaces each even number. Write a code for the same.
0 <= n <= 10^7
I made a code for this, where my partial code looks like this:
int a[100000];
while ( t != 0 ) // t is the number in which input is taken
{
k = t & 1;
if ( k == 1 )
a[i] = 0; // a is the array in which bits of new number will be stored
else
a[i] = 1;
i++;
t = t >> 1;
}
for ( j = i; j >= 0; j-- )
{
if (a[j] == 1)
{
num = num + pow(2,j)*a[j]; // num is the number to be formed
}
}
cout<<num<<"\n";
But my answer comes out to be wrong for some values, for example for 8, it outputs 7. What is wrong with this? Thanks!
Problem link:
http://www.spoj.com/problems/EC_CONB/
Edit: ( In response to Pete's answer )
while ( t != 0 )
{
k = t & 1;
if ( k == 1 )
a[i] = 0;
else
{
a[i] = 1;
num = num + pow(2,i);
}
i++;
t = t >> 1;
}
cout<<num<<"\n";
}
This still shows the same problem, outputs the value of 8 as 7.
The problem actually wants you to reverse the bits not invert them. So the part where you check if k == 1, and putting 0 instead is not correct, because that inverts the bits.
What you need to do is reverse the ordering of the bits as follows:
1000 (8) -> 0001 (1)
1010 (10) -> 0101 (5)
Sample code based on your code:
while (t != 0)
{
k = t & 1;
// push the output array to the left
num <<= 1;
// add the read bit to the beginning of the output array
num += k;
t = t >> 1;
}
Explanation:
The basic idea is that we read bits from the input number one-by-one, and push them to the beginning of the output number.
Below is a trace of reversing a number (1011) at each iteration:
iterations 0 1 2 3 4
input 1011 101 10 1 0
output 0 1 11 110 1101
You appear to be reading a[i] after incrementing i, so the behaviour is undefined.
Instead of creating an array, accumulate the result in the first loop.
Arrays? Loops? Not necessary.
Reversing the number like that is equivalent to completely reversing the integer and then right-justifying it, like this (not tested)
// reverse from http://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel
// swap odd and even bits
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
// swap consecutive pairs
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
// swap nibbles ...
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
// swap bytes
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
// swap 2-byte long pairs
v = ( v >> 16 ) | ( v << 16);
// right-justify
v /= v & -v;
v should be an uint32_t.

need help for write a function that give me all the states of a number

I have a 192-bit number . and I want two write a function that give me all of the states of this number as follows :
1) all the states with one bit 1
2) all the states with two bits 1
3) all the states with three bits 1
.
.
.
and so on till all of the bits will be 1
also I want to write each of this part in a separate files.
I'v just wrote the states that all of the 1-bits are put together.
for example:(for 16-bits number)
0000000000000011----> then I shift the bits to the left. But I can't find a good way to give me all of states of two bits.
(I use miracle library in C for this big number)
do you have any idea?
thank you :)
You could use 6 for-loops (192/32bit) which loop across all the values of a uint32
inside every-for-loop you can multiply the uint32 by some value to get the right value something like this:
for(uint32_t i = 0; i < 0xFFFFFFFF; i++) {
for(uint32_t j = 0; j < 0xFFFFFFFF; j++) {
bignumber = j + 0xFFFFFFFF*i
print(bignumber)
}
}
or if you want to do it really bitwise you could do some bitmasking inside the for-loops
I do not know your functions. but, if you have num and shiftLeft and equals functions, it can be like this
for (int i=0;i<192;i+=2)
{
num->assing(0b11);
num->shiftLeft(i*2);
if (num->andOperand(victim)->equals(num))
{
//this is the number has two consecutive 11, and only
}
if (num->andOperand(victim)->biggerAndEqual(0b11))
{
//this is the number has at least one , two consecutive 11
}
}
As the problem was stated there are ((2 ^ 192) - 1) numbers to print, because all permutations are covered except 0 which contains no 1 bits. That is clearly impossible so the question must be asking for consecutive bits set. As #n.m. wrote, get it working with 4 bits first. Then extend it to 192 bits. To shift a number, you double it. This solution works without doing any bit shifting or multiplication - by addition only (apart from the bit mask in printbits().
#include<stdio.h>
#define BITS 4
unsigned printmask;
void printbits (unsigned num) {
int i;
for (i=0; i<BITS; i++) {
if (num & printmask)
printf ("1");
else
printf ("0");
num = num + num;
}
printf (" ");
}
int main() {
unsigned num, bits;
int m, n;
printmask = 1; // prepare bit mask for printing
for (n=1; n<BITS; n++)
printmask = printmask + printmask;
num = 1;
for (n=0; n<BITS; n++) {
bits = num;
for (m=n; m<BITS; m++) {
printbits (bits);
bits = bits + bits;
}
printf ("\n");
num = num + num + 1;
}
return 0;
}
Program output
0001 0010 0100 1000
0011 0110 1100
0111 1110
1111

What is unoptimized about this code? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I wrote a solution for a question on interviewstreet, here is the problem description:
https://www.interviewstreet.com/challenges/dashboard/#problem/4e91289c38bfd
Here is the solution they have given:
https://gist.github.com/1285119
Here is the solution that I coded:
#include<iostream>
#include <string.h>
using namespace std;
#define LOOKUPTABLESIZE 10000000
int popCount[2*LOOKUPTABLESIZE];
int main()
{
int numberOfTests = 0;
cin >> numberOfTests;
for(int test = 0;test<numberOfTests;test++)
{
int startingNumber = 0;
int endingNumber = 0;
cin >> startingNumber >> endingNumber;
int numberOf1s = 0;
for(int number=startingNumber;number<=endingNumber;number++)
{
if(number >-LOOKUPTABLESIZE && number < LOOKUPTABLESIZE)
{
if(popCount[number+LOOKUPTABLESIZE] != 0)
{
numberOf1s += popCount[number+LOOKUPTABLESIZE];
}
else
{
popCount[number+LOOKUPTABLESIZE] =__builtin_popcount (number);
numberOf1s += popCount[number+LOOKUPTABLESIZE];
}
}
else
{
numberOf1s += __builtin_popcount (number);
}
}
cout << numberOf1s << endl;
}
}
Can you please point me what is wrong with my code? It can only pass 3/10 of tests. The time limit is 3 seconds.
What is unoptimized about this code?
The algorithm. You are looping
for(int number=startingNumber;number<=endingNumber;number++)
computing or looking up the number of 1-bits in each. That can take a while.
A good algorithm counts the number of 1-bits in all numbers 0 <= k < n in O(log n) time using a bit of math.
Here is an implementation counting 0s in decimal expansions, the modification to make it count 1-bits shouldn't be hard.
When looking at such a question, you need to break it down in simple pieces.
For example, suppose that you know how many 1s there are in all numbers [0, N] (let's call this ones(N)), then we have:
size_t ones(size_t N) { /* magic ! */ }
size_t count(size_t A, size_t B) {
return ones(B) - (A ? ones(A - 1) : 0);
}
This approach has the advantage that one is probably simpler to program that count, for example using recursion. As such, a first naive attempt would be:
// Naive
size_t naive_ones(size_t N) {
if (N == 0) { return 0; }
return __builtin_popcount(N) + naive_ones(N-1);
}
But this is likely to be too slow. Even when simply computing the value of count(B, A) we will be computing naive_ones(A-1) twice!
Fortunately, there is always memoization to assist here, and the transformation is quite trivial:
size_t memo_ones(size_t N) {
static std::deque<size_t> Memo(1, 0);
for (size_t i = Memo.size(); i <= N; ++i) {
Memo.push_back(Memo[i-1] + __builtin_popcnt(i));
}
return Memo[N];
}
It's likely that this helps, however the cost in terms of memory might be... crippling. Ugh. Imagine that for computing ones(1,000,000) we will occupy 8MB of memory on a 64bits computer! A sparser memoization could help (for example, only memoizing every 8th or 16th count):
// count number of ones in (A, B]
static unoptimized_count(size_t A, size_t B) {
size_t result = 0;
for (size_t i = A + 1; i <= B; ++i) {
result += __builtin_popcount(i);
}
return result;
}
// something like this... be wary it's not tested.
size_t memo16_ones(size_t N) {
static std::vector<size_t> Memo(1, 0);
size_t const n16 = N - (N % 16);
for (size_t i = Memo.size(); i*16 <= n16; ++i) {
Memo.push_back(Memo[i-1] + unoptimized_count(16*(i-1), 16*i);
}
return Memo[n16/16] + unoptimized_count(n16, N);
}
However, while it does reduce the memory cost, it does not solve the main speed issue: we must at least use __builtin_popcount B times! And for large values of B this is a killer.
The above solutions are mechanical, they did not require one ounce of thought. It turns out that interviews are not so much about writing code than they are about thinking.
Can we solve this problem more efficiently than dumbly enumerating all integers until B ?
Let's see what our brains (quite the amazing pattern machine) picks up when considering the first few entries:
N bin 1s ones(N)
0 0000 0 0
1 0001 1 1
2 0010 1 2
3 0011 2 4
4 0100 1 5
5 0101 2 7
6 0110 2 9
7 0111 3 12
8 1000 1 13
9 1001 2 15
10 1010 2 17
11 1011 3 20
12 1100 2 22
13 1101 3 25
14 1110 3 28
15 1111 3 32
Notice a pattern ? I do ;) The range 8-15 is built exactly like 0-7 but with one more 1 per line => it's like a transposition. And it's quite logical too, isn't it ?
Therefore, ones(15) - ones(7) = 8 + ones(7), ones(7) - ones(3) = 4 + ones(3) and ones(1) - ones(0) = 1 + ones(0).
Well, let's make this a formula:
Reminder: ones(N) = popcount(N) + ones(N-1) (almost) by definition
We now know that ones(2**n - 1) - ones(2**(n-1) - 1) = 2**(n-1) + ones(2**(n-1) - 1)
Let's make isolate ones(2**n), it's easier to deal with, note that popcount(2**n) = 1:
regroup: ones(2**n - 1) = 2**(n-1) + 2*ones(2**(n-1) - 1)
use the definition: ones(2**n) - 1 = 2**(n-1) + 2*ones(2**(n-1)) - 2
simplify: ones(2**n) = 2**(n-1) - 1 + 2*ones(2**(n-1)), with ones(1) = 1.
Quick sanity check:
1 = 2**0 => 1 (bottom)
2 = 2**1 => 2 = 2**0 - 1 + 2 * ones(1)
4 = 2**2 => 5 = 2**1 - 1 + 2 * ones(2)
8 = 2**3 => 13 = 2**2 - 1 + 2 * ones(4)
16 = 2**4 => 33 = 2**3 - 1 + 2 * ones(8)
Looks like it works!
We are not quite done though. A and B might not necessarily be powers of 2, and if we have to count all the way from 2**n to 2**n + 2**(n-1) that's still O(N)!
On the other hand, if we manage to express a number in base 2, then we should be able to leverage our newly acquired formula. The main advantage being than there are only log2(N) bits in the representation.
Let's pick an example and understand how it works: 13 = 8 + 4 + 1
1 -> 0001
4 -> 0100
8 -> 1000
13 -> 1101
... however, the count is not just merely the sum:
ones(13) != ones(8) + ones(4) + ones(1)
Let's express it in terms of the "transposition" strategy instead:
ones(13) - ones(8) = ones(5) + (13 - 8)
ones(5) - ones(4) = ones(1) + (5 - 4)
Okay, easy to do with a bit of recursion.
#include <cmath>
#include <iostream>
static double const Log2 = log(2);
// store ones(2**n) at P2Count[n]
static size_t P2Count[64] = {};
// Unfortunately, the conversion to double might lose some precision
// static size_t log2(size_t n) { return log(double(n - 1))/Log2 + 1; }
// __builtin_clz* returns the number of leading 0s
static size_t log2(size_t n) {
if (n == 0) { return 0; }
return sizeof(n) - __builtin_clzl(n) - 1;
}
static size_t ones(size_t n) {
if (n == 0) { return 0; }
if (n == 1) { return 1; }
size_t const lg2 = log2(n);
size_t const np2 = 1ul << lg2; // "next" power of 2
if (np2 == n) { return P2Count[lg2]; }
size_t const pp2 = np2 / 2; // "previous" power of 2
return ones(pp2) + ones(n - pp2) + (n - pp2);
} // ones
// reminder: ones(2**n) = 2**(n-1) - 1 + 2*ones(2**(n-1))
void initP2Count() {
P2Count[0] = 1;
for (size_t i = 1; i != 64; ++i) {
P2Count[i] = (1ul << (i-1)) - 1 + 2 * P2Count[i-1];
}
} // initP2Count
size_t count(size_t const A, size_t const B) {
if (A == 0) { return ones(B); }
return ones(B) - ones(A - 1);
} // count
And a demonstration:
int main() {
// Init table
initP2Count();
std::cout << "0: " << P2Count[0] << ", 1: " << P2Count[1] << ", 2: " << P2Count[2] << ", 3: " << P2Count[3] << "\n";
for (size_t i = 0; i != 16; ++i) {
std::cout << i << ": " << ones(i) << "\n";
}
std::cout << "count(7, 14): " << count(7, 14) << "\n";
}
Victory!
Note: as Daniel Fisher noted, this fails to account for negative number (but assuming two-complement it can be inferred from their positive count).

Why is this code not doing its job?

I want to create a program that writes all the primes in a file (I know that there's a popular algorithm "Sieve of Eratosthenes", but I'm trying to make it by myself). I'm trying to eliminate all the complications for the bytes that still have the value 1 then write them in a file.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
void afficher_sur_un_ficher (FILE* ficher, int nb_bit);
char el_mask (int x);
int main()
{
FILE* p_fich;
char tab[4096], mask, eli_mask;
int nb_bit = 0, x, f;
for (int i = 0; i < 4096; i++)
{
tab[i] = 0xff;
}
for (int i = 0; i < 4096; i++)
{
for (mask = 0x01; mask != 0; mask <<= 1)
{
if ((tab[i] & mask) != 0)
{
x = nb_bit;
while ((x > 1) && (x < 16384))
{
eli_mask = el_mask (x);
f = x / 8;
tab[f] = tab[f] ^ eli_mask;
x = x + nb_bit;
}
afficher_sur_un_ficher (p_fich, nb_bit);
}
nb_bit++;
}
}
system ("PAUSE");
return 0;
}
void afficher_sur_un_ficher (FILE* ficher, int nb_bit)
{
ficher = fopen ("res.txt", "a+");
fprintf (ficher, "%d \t", nb_bit);
int static z;
z = z + 1;
if (z % 10 == 0)
fprintf (ficher, "\n");
fclose (ficher);
}
char el_mask (int x)
{
x = x % 8;
switch (x)
{
case 0:
x = 0b00000001;
break;
case 1:
x = 0b00000010;
break;
case 2:
x = 0b00000100;
break;
case 3:
x = 0b00001000;
break;
case 4:
x = 0b00010000;
break;
case 5 :
x = 0b00100000;
break;
case 6 :
x = 0b01000000;
break;
case 7:
x = 0b10000000;
break;
}
return x;
}
There appears to be a problem in the loop that's trying to clear bits indicating non-primes:
while (( x > 1 )&&(x < 16384))
{
tab[i] = tab[i] ^ mask ;
x = x * 2 ;
}
Since i doesn't change in this loop, you essentially toggling the same bit off and on while incrementing x. As well as fixing the index into tab[], you probably want to change the operation from xor (^) to something that will clear the bit unconditionally - once a bit is cleared, you don't want processing that bit again for a different factor to 'reset' the bit. Note that a simple incrementing of i wont do, as the multiples of x in other elements of tab might not be in the same bit offset (indeed, a single element of tab[] might contain several multiples of x).
Even if you fix that problem, I think the loop might not be doing what you expect, since x = x * 2; doesn't walk x through its multiples - you'll end up skipping some non-primes.
Some research on how the 'Sieve of Eratosthenes' works might help.
Maybe I"m missing something, but this just seems wonky. I don't remember common prime algorithms off-hand, but, for instance,
(excerpts)
tab[i] = 0xff ;
mask = 0x01 ;
for (int j = 0 ; j < 8 ; j++)
{
if ((tab[i] & mask) != 0 )
mask = mask<<1 ;
This means that you will always go 8 times - so why check with the '&'?
Another one,
x = nb_bit ;
while (( x > 1 )&&(x < 16384))
{
tab[i] = tab[i] ^ mask ;
x = x * 2 ;
}
This just flip flops the bits on every iteration. Is that what you want?
Finally, as I don't know what you mean to do, careful with bit length of your objects. You might flip flop
0000 0000 1111 1111 ^ 0000 0001
or
1111 1111 1111 1111 ^ 0000 00001
As I don't really understand what you're trying to do, not sure this might be related.
EDIT (after Hamza's comment):
Yes. What this loop does is the following - compare/'and'
1111 1111 1111 1111
with
0000 0001
0000 0010
0000 0100,
and that always will hold true. I don't know what you want to do here, but this seems fishy (changing location now with no internet for a while, but gl. :) ).
You can simplify your main function a bit:
int main (int argc, char** argv) {
FILE* p_fich;
char tab[4096] , mask;
int nb_bit = 0 , x;
memset(tab, 0xFF, 4096);
for (int i = 0; i < 4096; i++) {
for (mask = 0x01; mask != 0; mask <<= 1) {
if ((tab[i] & mask) != 0) {
for (x = nb_bit; (x > 1) && (x < 0x4000), x<<=1)
tab[i] ^= mask;
afficher_sur_un_ficher (p_fich, nb_bit);
}
nb_bit++;
}
}
system ("PAUSE");
return 0;
}
Now, to address your question:
Your afficher_sur_un_ficher function will print whatever you pass to it, and that function is called for every loop iteration where ((tab[i] & mask) != 0) is true. Since you initialize every tab[i] byte to 0xFF, masking off any given bit combination will always cause that if statement to evaluate true. You are altering the value of tab[i], but once you do, you no longer use that bit so it's not changing the fact that the if statement will always be taken. This is why you are seeing every entry being logged.
Edit:
If you simplify away all the code that does not affect the decision to output or the value to output, you end up with the following:
memset(tab, 0xFF, 4096);
for (int i = 0; i < 4096; i++) {
for (mask = 0x01; mask != 0; mask <<= 1) {
afficher_sur_un_ficher (p_fich, nb_bit);
nb_bit++;
}
}
As you can see, this code will print an incrementing sequence of integers (0 through (4096*8)-1) and is completely independent of the tab array and of the specific values of i and mask. I think there is something missing in your implementation of the algorithm. Do you have a link to a description of the algorithm you are trying to implement? Or is this an algorithm you developed? (Sorry, I didn't understand your description of your algorithm that you added to the question)