Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added deterministic version to miller rabin algorithm #1021

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
#include<iostream>
using namespace std;

int countSetBits(int n) {
int setBits = 0;
while(n > 0){
if(n&1){
setBits++;
}
n>>=1;
}
return setBits;
}

int main(){
int a,b;
cin>>a>>b;

// take the XOR of both the numbers and then count the set bits in that XOR
int _xor = a^b;
int answer = countSetBits(_xor);
int answer = __builtin_popcount(_xor);

cout<<"number of bits to be flipped "<<answer<<endl;

return 0;
}
}
17 changes: 6 additions & 11 deletions BitManipulation/count_ones/count_ones.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,16 @@

#include <iostream>

using namespace std;
using namespace std;

short count_ones(unsigned int x) {
short num_bits = 0;
while (x) {
num_bits += x & 1; // mask one
x >>= 1;
}
return num_bits;
return __builtin_popcount(x);
}

int main() {
int main() {

int number = 10; // use any number
short result = count_ones(number);
cout << "result: " << result << endl;
int number = 10; // use any number
short result = count_ones(number);
cout << "result: " << result << endl;
return 0;
}
81 changes: 81 additions & 0 deletions Math/miller_rabin_primality_test/miller_rabin_deterministic.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <cstdio>
#include <iterator>
#include <vector>
using namespace std;
const int witness[]={2,3,5,7};
const int witness_size=4; ///remember to edit this value too
/* Note that different witness arrays will cause the function to have different accuracies.
But according to wikipedia: https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test

if n < 2,047, it is enough to test a = 2;
if n < 1,373,653, it is enough to test a = 2 and 3;
if n < 9,080,191, it is enough to test a = 31 and 73;
if n < 25,326,001, it is enough to test a = 2, 3, and 5;
if n < 3,215,031,751, it is enough to test a = 2, 3, 5, and 7; (I am using this)
if n < 4,759,123,141, it is enough to test a = 2, 7, and 61;
if n < 1,122,004,669,633, it is enough to test a = 2, 13, 23, and 1662803;
if n < 2,152,302,898,747, it is enough to test a = 2, 3, 5, 7, and 11;
if n < 3,474,749,660,383, it is enough to test a = 2, 3, 5, 7, 11, and 13;
if n < 341,550,071,728,321, it is enough to test a = 2, 3, 5, 7, 11, 13, and 17.

Note that for the correctness of the algorithm, the witness array should only be filled with prime numbers.
*/

bool isPrime(int i){
///check for the simple cases
if (i==1) return false;
if (i==2) return true;
if (!(i&1)) return false;
for (int x=0;x<witness_size;x++){
if (witness[x]==i) return true;
}

vector<int> pow; ///this holds the bits of i with all the trailing zeros striped off
int s=0; ///number of trailing zeros

int _i=i-1;
while (!(_i&1)){
s++;
_i>>=1;
}

while (_i){
pow.push_back(_i&1);
_i>>=1;
}

long long curr;
for (int x=0;x<witness_size;x++){
curr=1;
for (vector<int>::reverse_iterator it=pow.rbegin();it!=pow.rend();it++){
if (*it){
curr=(curr*curr)%i;
curr=(curr*witness[x])%i;
}
else{
curr=(curr*curr)%i;
}
}

if (curr==1 || curr==i-1) goto _end;

for (int x=1;x<s;x++){
if (curr!=i-1) {
curr=(curr*curr)%i;
if (curr==1) return false;
}
else goto _end;
}
if (curr!=i-1) return false;
_end:;
}

return true;
}

int main(){
///program to test if it works
for (int x=1;x<=1000;x++){
if (isPrime(x)) printf("%d\n",x);
}
}