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)
Related
Problem: Given an integer led as input, create a bitset (16 bits) with led bits set to 1. Then, create the following sequence (assume in this case led = 7):
0000000001111111
0000000000111111
0000000001011111
0000000001101111
0000000001110111
0000000001111011
0000000001111101
0000000001111110
Note that it is a "zero" that is moving to the right. The code I wrote is:
void create_mask(int led){
string bitString;
for (int i = 0; i < led; i++){
bitString += "1";
}
bitset<16> bitMap(bitString);
for (int i = led; i >= 0; i--){
bitMap[i] = false;
cout << bitMap << endl;
bitString = "";
for (int j = 0; j < led; j++){
bitString += "1";
}
bitMap = bitset<16> (bitString);
}
}
I don't like the nested loop where I set each bit to 0. I think that could be made better with less complexity.
This is what I came up with:
void createMask(int len) {
std::bitset<16> bitMap;
for (int i = 1; i < len; i++)
{
bitMap.set();
bitMap >>= 16 - len;
bitMap[len - i] = false;
std::cout << bitMap << std::endl;
}
}
bitMap.set() sets all bits in the bitset to 1 (or true)
bitMap >>= 16 - len shifts all the bits to the right but it does it 16 - 7 (if len was 7) so there are 9 zeros and seven ones.
bitMap[len - i] = false sets the bit at 7 - i to 0 (or false). len - i is a way of specifying the inverse number (basically it starts setting the zeros on the left and works towards the right depending on the value of i)
The loop starts at 1 because you're setting the bit to 0 anyways and prevents program from crashing when len is 16 –
If you want to use a std::bitset, you can take advantage of the bit functions like shifting and XOR'ing. In this solution I have a base bitset of all ones, a mask that shifts right, and I output the XOR of the two on each iteration.
Untested.
void output_masks(int bits, std::ostream& os){
std::bitset<16> all_ones((1 << bits) - 1);
std::bitset<16> bit_mask(1 << (bits - 1));
while (bit_mask.any()) {
os << (all_ones ^ bit_mask);
bit_mask >>= 1;
}
}
At first I just wanted to know how many 8 bit numbers contained either 111 or 000, but I couldn't find any math based answer but couldn't find any. Probably because I couldn't word it right.
Now I just want to know how to check with an algorithm, I tried in c++ because I recently learned it.
Here's where I've got so far:
int count = 0;
unsigned char base = 0;
//for every permutation of origin
for (unsigned short i = 0; i < 0b100000000; i++)
{
bool hasPattern = false;
unsigned char pattern = 0b1110000;
unsigned char temp = base;
//for as many times as (length of base)-(length of pattern)
for (char j = 0; j < 5; j++)
{
//get rid of the bits we aren't checking
temp >>= j;
temp <<= 5;
//check if what remains matches our pattern
if ((pattern & temp) == pattern || (~pattern & temp) == ~pattern)
{
hasPattern = true;
}
}
//if the pattern matches, increment count
count += hasPattern;
base++;
}
std::cout << count << std::endl;
Running this returns 0, while it definitely should return >0
In your code, 5 low-order bits in temp are always 0, while only 4 low-order bits of pattern are.
But actually, you should separate mask and pattern, like
unsigned char mask = 0b0000'0111; // (1 << pattern length) - 1
unsigned char pattern1 = 0b0000'0111;
unsigned char pattern2 = 0b0000'0000;
temp >>= j;
if ((mask & temp) == pattern1 || (mask & temp) == pattern2)
This way, you can check for any subsequences.
Also the loop should be to 5 inclusive: the pattern can appear at bits (0, 1, 2), (1, 2, 3), ..., (5, 6, 7).
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
while(i < length)
{
pow = 1;
for(int j = 0; j < 8; j++, pow *=2)
{
ch += (str[j] - 48) * pow;
}
str = str.substr(8);
i+=8;
cout << ch;
ch = 0;
}
This seems to be slowing my program down a lot. Is it because of the string functions I'm using in there, or is this approach wrong in general. I know there's the way where you implement long division, but I wanted to see if that was actually more efficient than this method. I can't think of another way that doesn't use the same general algorithm, so maybe it's just my implementation that is the problem.
Perhaps you want might to look into using the standard library functions. They're probably at least as optimised as anything you run through the compiler:
#include <iostream>
#include <iomanip>
#include <cstdlib>
int main (void) {
const char *str = "10100101";
// Use str.c_str() if it's a real C++ string.
long int li = std::strtol (str, 0, 2);
std::cout
<< "binary string = " << str
<< ", decimal = " << li
<< ", hex = " << std::setbase (16) << li
<< '\n';
return 0;
}
The output is:
binary string = 10100101, decimal = 165, hex = a5
You are doing some things unnecessarily, like creating a new substring for each each loop. You could just use str[i + j] instead.
It is also not necessary to multiply 0 or 1 with the power. Just use an if-statement.
while(i < length)
{
pow = 1;
for(int j = 0; j < 8; j++, pow *=2)
{
if (str[i + j] == '1')
ch += pow;
}
i+=8;
cout << ch;
ch = 0;
}
This will at least run a bit faster.
short answer could be:
long int x = strtol(your_binary_c++_string.c_str(),(char **)NULL,2)
Probably you can use int or long int like below:
Just traverse the binary number step by step, starting from 0 to n-1, where n is the most significant bit(MSB) ,
multiply them with 2 with raising powers and add the sum together. E.g to convert 1000(which is binary equivalent of 8), just do the following
1 0 0 0 ==> going from right to left
0 x 2^0 = 0
0 x 2^1 = 0;
0 x 2^2 = 0;
1 x 2^3 = 8;
now add them together i.e 0+0+0+8 = 8; this the decimal equivalent of 1000. Please read the program below to have a better understanding how the concept
work. Note : The program works only for 16-bit binary numbers(non-floating) or less. Leave a comment if anything is not clear. You are bound to receive a reply.
// Program to convert binary to its decimal equivalent
#include <iostream>
#include <math.h>
int main()
{
int x;
int i=0,sum = 0;
// prompts the user to input a 16-bit binary number
std::cout<<" Enter the binary number (16-bit) : ";
std::cin>>x;
while ( i != 16 ) // runs 16 times
{
sum += (x%10) * pow(2,i);
x = x/10;
i++;
}
std::cout<<"\n The decimal equivalent is : "<<sum;
return 0;
}
How about something like:
int binstring_to_int(const std::string &str)
{
// 16 bits are 16 characters, but -1 since bits are numbered 0 to 15
std::string::size_type bitnum = str.length() - 1;
int value = 0;
for (auto ch : str)
{
value |= (ch == '1') << bitnum--;
}
return value;
}
It's the simplest I can think of. Note that this uses the new C++11 for-each loop construct, if your compiler can't handle it you can use
for (std::string::const_iterator i = str.begin(); i != str.end(); i++)
{
char ch = *i;
// ...
}
Minimize the number of operations and don't compute things more than once. Just multiply and move up:
unsigned int result = 0;
for (char * p = str; *p != 0; ++p)
{
result *= 2;
result += (*p - '0'); // this is either 0 or 1
}
The scheme is readily generalized to any base < 10.
what I want to do is check an array of bools to see if 3 or more of them have been set to true. The only way I can think to do this is using a if statement for each possible combination of which there is lots because there are ten bools. Dose anybody have any suggestions on how best to do this.
This would be the easiest way:
std::count(bool_array, std::end(bool_array), true) >= 3
Only problem is it keeps counting even after it has found 3. If that is a problem, then I would use sharptooth's method.
side note
I've decided to fashion an algorithm in the style of std::all_of/any_of/none_of for my personal library, perhaps you will find it useful:
template<typename InIt, typename P>
bool n_or_more_of(InIt first, InIt last, P p, unsigned n)
{
while (n && first != last)
{
if (p(*first)) --n;
++first;
}
return n == 0;
}
For your purpose, you would use it like this:
n_or_more_of(bool_array, std::end(bool_array), [](bool b) { return b; }, 3);
The much easier way would be to loop through the array:
int numberOfSet = 0;
for( int i = 0; i < sizeOfArray; i++ ) {
if( array[i] ) {
numberOfSet++;
//early cut-off so that you don't loop further without need
// whether you need it depends on how typical it is to have
// long arrays that have three or more elements set in the beginning
if( numberOfSet >= 3 ) {
break;
}
}
}
bool result = numberOfSet >= 3;
Whenever you are setting an array element into TRUE value, you can increment a global counter. This will be the simplest way. At any point in your code, the global array will tell you the number of TRUE elements in the Array.
Another thing - if you are keeping upto 32 bool values, you can use a single int variable. int is 32 bits (in Win32) and you can store 32 bool.
char x = 0; // 00000000 // char is 8 bits
// TO SET TRUE
x = x | (1 << 4); // 00010000
x = x | (1 << 7); // 10010000
// TO SET FALSE
x = x & ~(1 << 4); // 10010000 & 11101111 => 10000000
// TO CHECK True/False
if( x & ~(1 << 4) )
If it's an array, what you do is loop over it and count the number of trues. But I'm afraid you mean a bitpattern of some kind, right?
Why not just count the number of trues and then do something if the number is 3 or higher:
int sum = 0;
for (int i = 0; i < length; i++){
if (arr[i]){
sum++;
}
}
if (sum >= 3){
// do something...
}
You can loop through and build a bit-mask representation of the array, then you can compare against up to CHAR_BIT * sizeof (unsigned long) in parallel:
unsigned long mask = 0;
for (std::vector<bool>::const_iterator it = flags.begin(), end_it = flags.end();
it != end_it;
++it)
{
if (*it)
mask |= (1 << (it - flags.begin()));
}
if (mask & (0xaa3)) // or whatever mask you want to check
{
}
This assumes that you're looking for patterns, not just want to count the number of true flags in the array.
Just loop through the array counting the number of bools set to true.
/**
* #param arr The array of booleans to check.
* #param n How many must be true for this function to return true.
* #param len The length of arr.
*/
bool hasNTrue(bool *arr, int n, int len) {
int boolCounter;
for(int i=0; i<len; i++) {
if (arr[i]) boolCounter++;
}
return boolCounter>=n;
}
Then call it like so
hasNTrue(myArray, 3, myArrayLength);
Store the bools as bits in an integer. Then apply one of the bit twiddling hacks.