I'm attempting to debug my implementation of the standard (i.e., probabilistic) Miller-Rabin test. This is the code right now, with a rudimentary test execution in the main method:
#include <iostream>
#include <random>
typedef unsigned long long int ulli;
std::random_device rd;
std::mt19937_64 mt(rd());
ulli upow(ulli x, ulli y) {
if (y == 0)
return 1;
else if (y == 1)
return x;
else if (y % 2 == 0)
return upow(x*x, y/2);
else
return x * upow(x*x, (y-1)/2);
}
bool miller_rabin(ulli n, ulli d) {
std::uniform_int_distribution<ulli> dist(2, n-2);
ulli a = dist(mt);
ulli x = upow(a, d) % n;
if (x == 1 || x == n - 1)
return true;
while (d != n - 1) {
x = x*x % n;
d *= 2;
if (x == 1)
return false;
if (x == n - 1)
return true;
}
return false;
}
bool is_prime(ulli n, ulli k) {
if (n <= 1)
return false;
if (n <= 3)
return true;
if (n % 2 == 0)
return false;
ulli d = n - 1;
while (d % 2 == 0)
d /= 2;
for (int i = 0; i < k; ++i) {
if (!miller_rabin(n, d))
return false;
}
return true;
}
int main() {
ulli tests = 30;
std::cout << "is_prime(2): " << is_prime(2, tests) << std::endl;
std::cout << "is_prime(10): " << is_prime(10, tests) << std::endl;
std::cout << "is_prime(97): " << is_prime(97, tests) << std::endl;
std::cout << "is_prime(256): " << is_prime(256, tests) << std::endl;
std::cout << "is_prime(179424691): " << is_prime(179424691, tests) << std::endl;
std::cout << "is_prime(32416187563): " << is_prime(32416187563, tests) << std::endl;
}
The problem I'm currently having is this: the last two tests are returning false, which (because they are both prime) should be impossible. Even with as high a number of tests as I'm passing, is_prime still outputs false.
At this point, I'm genuinely lost as to what's wrong. Any ideas?
Related
Keep in mind I've only been using CPP for around a week so the code is not very good. I wrote this to solve the problem 1362A on CodeForces. Long story short, the code works fine except for the fact that it says the memory used is 262100 KB. I've looked over it multiple times but can't find anything that would cause lots of memory to be used.
#include <iostream>
#include <cstdint>
using namespace std;
uint64_t makeq(uint64_t x, uint64_t y)
{
uint64_t q;
if (x >= y)
{
q = x / y;
}
else
{
q = y / x;
}
return q;
}
bool check(uint64_t x, uint64_t y, uint64_t q)
{
if (x >= y)
{
if (x % y != 0)
{
cout << -1 << "\n";
return false;
}
}
else
{
if (y % x != 0)
{
cout << -1 << "\n";
return false;
}
}
//checking float
if (q > 8 && q % 8 != 0)
{
cout << -1 << "\n";
return false;
}
if (q == 1)
{
cout << 0 << "\n";
return false;
}
if (q % 2 != 0)
{
cout << -1 << "\n";
return false;
}
return true;
}
int main()
{
uint64_t n, x, y, q, c;
cin >> n;
while (n--)
{
c = 0;
cin >> x >> y;
q = makeq(x, y);
if (check(x, y, q) == false)
{
continue;
}
while (q > 1)
{
if (q >= 8 && q % 8 == 0)
{
q /= 8;
c += 1;
}
else
{
if (q >= 4 && q % 4 == 0)
{
q /= 4;
c += 1;
}
else
{
q /= 2;
c += 1;
}
}
}
cout << c << endl
<< flush;
}
return 0;
}
**
So far I have this code. I'm trying to print prime factorization with exponents. For example, if my input is 20, the output should be 2^2, 5
#include <iostream>
#include <cmath>
using namespace std;
void get_divisors (int n);
bool prime( int n);
int main(int argc, char** argv) {
int n = 0 ;
cout << "Enter a number and press Enter: ";
cin >>n;
cout << " Number n is " << n << endl;
get_divisors(n);
cout << endl;
return 0;
}
void get_divisors(int n){
double sqrt_of_n = sqrt(n);
for (int i =2; i <= sqrt_of_n; ++i){
if (prime (i)){
if (n % i == 0){
cout << i << ", ";
get_divisors(n / i);
return;
}
}
}
cout << n;
}
bool prime (int n){
double sqrt_of_n = sqrt (n);
for (int i = 2; i <= sqrt_of_n; ++i){
if ( n % i == 0) return 0;
}
return 1;
}
I hope someone can help me with this.
You can use an std::unordered_map<int, int> to store two numbers (x and n for x^n). Basically, factorize the number normally by looping through prime numbers smaller than the number itself, dividing the number by the each prime as many times as possible, and recording each prime you divide by. Each time you divide by a prime number p, increment the counter at map[p].
I've put together a sample implementation, from some old code I had. It asks for a number and factorizes it, displaying everything in x^n.
#include <iostream>
#include <unordered_map>
#include <cmath>
bool isPrime(const int& x) {
if (x < 3 || x % 2 == 0) {
return x == 2;
} else {
for (int i = 3; i < (int) (std::pow(x, 0.5) + 2); i += 2) {
if (x % i == 0) {
return false;
}
}
return true;
}
}
std::unordered_map<int, int> prime_factorize(const int &x) {
int currentX = abs(x);
if (isPrime(currentX) || currentX < 4) {
return {{currentX, 1}};
}
std::unordered_map<int, int> primeFactors = {};
while (currentX % 2 == 0) {
if (primeFactors.find(2) != primeFactors.end()) {
primeFactors[2]++;
} else {
primeFactors[2] = 1;
}
currentX /= 2;
}
for (int i = 3; i <= currentX; i += 2) {
if (isPrime(i)) {
while (currentX % i == 0) {
if (primeFactors.find(i) != primeFactors.end()) {
primeFactors[i]++;
} else {
primeFactors[i] = 1;
}
currentX /= i;
}
}
}
return primeFactors;
}
int main() {
int x;
std::cout << "Enter a number: ";
std::cin >> x;
auto factors = prime_factorize(x);
std::cout << x << " = ";
for (auto p : factors) {
std::cout << "(" << p.first << " ^ " << p.second << ")";
}
}
Sample output:
Enter a number: 1238
1238 = (619 ^ 1)(2 ^ 1)
To begin with, avoid using namespace std at the top of your program. Second, don't use function declarations when you can put your definitions before the use of those functions (but this may be a matter of preference).
When finding primes, I'd divide the number by 2, then by 3, and so on. I can also try with 4, but I'll never be able to divide by 4 if 2 was a divisor, so non primes are automatically skipped.
This is a possible solution:
#include <iostream>
int main(void)
{
int n = 3 * 5 * 5 * 262417;
bool first = true;
int i = 2;
int count = 0;
while (i > 1) {
if (n % i == 0) {
n /= i;
++count;
}
else {
if (count > 0) {
if (!first)
std::cout << ", ";
std::cout << i;
if (count > 1)
std::cout << "^" << count;
first = false;
count = 0;
}
i++;
if (i * i > n)
i = n;
}
}
std::cout << "\n";
return 0;
}
Note the i * i > n which is an alternative to the sqrt() you are using.
I don't get why the summation never works properly, yet sums consistently.
It dosent throw any errors, but never gets the correct result. According to wolfram|alpha i can be off with as much as 20 000 000 000 for large calculations. I have no idea why this happens, so any ideas you might have are greatly appreciated!
Note: Compiled with -O3 and -std=c++14 flags.
Code:
#include "stdafx.h"
#include <math.h>
#include <vector>
#include <stdio.h>
#include <iostream>
typedef unsigned long long ul;
const ul PRIMES = 1000000;
bool isPrime(ul n)
{
if (n <= 1) return false;
double sqN = sqrt(n);
for (ul i = 3; i <= sqN; i++) {
if ((int)n % i == 0) return false;
} return true;
}
int main()
{
std::vector<ul> primes;
ul sumPrimes = 0;
ul numPrimes = 0;
for (ul n = 2; n <= PRIMES; n++) if (isPrime(n)) primes.push_back(n);
numPrimes = primes.size();
for (ul sp : primes) sumPrimes += sp;
std::vector<ul> fizz, buzz, fizzbuzz;
ul sumF = 0, sumB = 0, sumFB = 0;
ul numF = 0, numB = 0, numFB = 0;
for (ul prime = 0; prime < primes.size(); prime++) {
if (prime % 15 == 0) {
fizzbuzz.push_back(primes[prime]);
}
else if (prime % 5 == 0) {
buzz.push_back(primes[prime]);
}
else if (prime % 3 == 0) {
fizz.push_back(primes[prime]);
}
}
for (ul fb : fizzbuzz) sumFB += fb;
for (ul f : fizz) sumF += f;
for (ul b : buzz) sumB += b;
numF = fizz.size(); numB = buzz.size(); numFB = fizzbuzz.size();
std::cout << "Stats for primes upto\t" << PRIMES << "\n";
std::cout << "Primecount:\t\t" << numPrimes << "\n";
std::cout << "Sum Primes:\t\t" << sumPrimes << "\n";
std::cout << "Fizzcount:\t\t" << numF << "\n";
std::cout << "Sum Fizz:\t\t" << sumF << "\n";
std::cout << "Buzzcount:\t\t" << numB << "\n";
std::cout << "Sum Buzz:\t\t" << sumB << "\n";
std::cout << "FizzBuzzcount:\t\t" << numFB << "\n";
std::cout << "Sum FizzBuzz:\t\t" << sumFB << "\n";
std::system("pause");
return 0;
}
And this is the output i get:
output
In your isPrime method, you are starting with i = 3. Start with i = 2 so that you are removing non primes that have a factor of 2.
bool isPrime(ul n)
{
if (n <= 1) return false;
double sqN = sqrt(n);
for (ul i = 3; i <= sqN; i++) {
if ((int)n % i == 0) return false;
} return true;
}
Try
bool isPrime(ul n)
{
if (n <= 1) return false;
double sqN = sqrt(n);
for (ul i = 2; i <= sqN; i++) {
if ((int)n % i == 0) return false;
} return true;
}
Unless I have misunderstood something.
I wanted to practice math in c++ and I tried making a program that answered this question from math class
0 < r < 1, find the number of rational r values for which the
numerator and the denominator add to make 1000 where r is in simplest
form
After an hour or two debugging, I finally got something that makes it through all the numbers. In class, the answer was 200. I got 216. Run for yourself
#include <math.h>
#include <iostream>
bool rprime_test(int a, int b) {
int tmp = 2;
std::cout << a << "/" << b;
tmp1:
for (tmp; (tmp < a) && (a % tmp != 0); tmp++) {
}
if ((b % tmp == 0 && a % tmp == 0) || b % a == 0) {
std::cout << " == irreduced\n";
return false;
} else if (!tmp < a) {
std::cout << " == reduced\n";
return true;
} else {
//std::cout << tmp << ","<< a << std::endl;
goto tmp1;
}
}
int main() {
int r = 0, a = 1;
int b = 1000 - a;
while (a < b) {
if (rprime_test(a, b)) {
r++;
}
std::cout << "total = " << r << std::endl;
a++;
b = 1000 - a;
//std::cout << "assigned " << a << "/" << b << std::endl;
}
std::cout << "final result = " << r << std::endl;
return 0;
}
please I don't know what I did wrong for this. Also, is there any better way to optimize this?
Your main issue is with your rprime_test function. Without digging too much into your existing function, try using the gcd. Two numbers a and b are an irreducible fraction when they are "coprime," which is when their "greatest common denominator" (gcd) is 1. The way you compute the gcd of two values is with the Euclidean Algorithm:
int gcd (int a, int b) {
return b % a == 0 ? a : gcd (b % a, a);
}
And your check becomes
if (gcd (a, b) == 1) {
a++;
/* etc */
}
Following works:
#include <iostream>
int gcd(unsigned int a, unsigned int b)
{
if (b < a) {
return gcd(b, a);
}
int r = a % b;
while (r != 0) {
a = b;
b = r;
r = a % b;
}
return b;
}
int main()
{
int count = 0;
for (int i = 1; i != 500; ++i) {
if (gcd(1000 - i, i) == 1) {
++count;
}
}
std::cout << count << std::endl;
}
Live example
I'm trying to write program to calculate and display the number of primes in the first 50 “chiliads”. There must be 2 user defined functions "isPrime" and "primeCount". It seems like the "primeCount" is appending 4469969 to every count. It isn't doing that when I paste it into the main function.
int main (){
long x = 1;
long y = 1000;
char reply;
cout << "Start End Number of Primes" << endl;
while (y <= 50000)
{
cout << x << " " << y << " ";
cout << primeCount(x, y) << endl;
x = 1000 + x;
y = 1000 + y;
}
//exits the program
cout << "Enter q to quit... ";
cin >> reply;
return 0;
}// End main function
bool isPrime(long n)
{
long i = 2;
if (n == 1)
return false;
if (n == 2)
return true;
if (n == 3)
return true;
if ((n % 2) == 0)
return false;
if ((n % 3) == 0)
return false;
while (i < n)
{
if (n % i == 0 )
{
return false;
}
else
{
i++;
}
}
return true;
}
long primeCount (long x, long y)
{
long count = 0;
while (x < y)
{
if (isPrime(x) == 1)
{
count++;
}
x++;
}
cout << count;
}
You were not returning a value from "primeCount" you were printing it.
I cleaned up the code as follows, along with some optimizations (we prove that the candidate is odd, so we don't need to check even divisors, and we only check for the value of 2 when we already know the number is even, saving us 1 extra test per odd number).
#include <iostream>
// prototypes for functions we implement after we use them.
long primeCount(long x, long y);
bool isPrime(long n);
int main (){
long x = 1;
long y = 1000;
std::cout << "Start End Number of Primes" << std::endl;
while (y <= 50000)
{
std::cout << x << " " << y << " ";
std::cout << primeCount(x, y) << std::endl;
x += 1000;
y += 1000;
}
return 0;
}
bool isPrime(long n)
{
if((n & 1) == 0) // even
return (n == 2);
if(n == 1)
return false;
for (long i = 3; i < n / 2; i += 2)
{
if ((n % i) == 0 )
return false;
}
return true;
}
long primeCount(long x, long y)
{
long count = 0;
while (x < y)
{
if (isPrime(x))
count++;
++x;
}
return count;
}