Iterating primes using mpz_nextprime - c++

In C++, I want to print the first n prime numbers (for this example let's assume n=1000).
In order to do this, I've found mpz_nextprime from the GMP library.
I'd assume you use it like this
int n = 2;
for(int i = 0; i < 1000; i++) {
n = mpz_nextprime(n);
cout << n << endl;
}
but this doesnt compile as mpz_nextprime takes two mpz_t arguments.
How can you use mpz_nextprime in this context?

The reason for mpz_nextprime using mpz_t instead of normal integer types like int or long is that after a certain point the prime numbers will be too large to be representable in a int or long.
Here's a snippet of code to print all up to the 1000th prime number:
#include <gmp.h>
int main() {
mpz_t n;
mpz_init(n);
mpz_set_ui(n, 2);
for (size_t i = 0; i < 1000; i++) { // first 1000 primes
mpz_nextprime(n, n);
cout << "The " << (i + 1) << "th " << " prime is " << mpz_get_ui(n) << endl;
}
}
Note that this code will only work up to a certain prime number because in order to print it, we convert it to an unsigned int using mpz_get_ui here.
If you want to print larger prime numbers, use mpz_get_str (but don't forget to free() the string if you use NULL as first parameter).

Related

How to find the greatest number among the numbers given input?

I'm a beginner in programming and as you can see, I created a program where the user is asked to input three numbers. It will display the greatest among the numbers given. But after I finished the code, a question came into my mind, what if the user was asked to input a hundreds of numbers and should display the greatest among the numbers given. So the question is, is it possible to do that? what are the things I need to learn to produce that result? is there any hints you can give me?
#include <iostream>
#include <string>
using std::cout, std::cin, std::endl, std::string;
int main() {
string result = " is the greatest among the numbers given";
double x, y, z;
cout<<"Enter three numbers to decide which is the largest: "<<endl;
cin >>x;
cin >>y;
cin >>z;
system("clear");
if(x>y && x>z){
cout<< x << result;
} else if (y>z && y>x){
cout << y << result;
} else
cout<< z << result;
return 0;
}
With the program below, you can get as many numbers as you want from the user and find the largest of them.
#include <iostream>
int main()
{
int size=0, largestValue=0, value=0;
std::cout << "Enter total numbers you want to add :" << "\n";
std::cin >> size;
for (int i{ 0 }; i < size; ++i)
{
std::cout << "Enter value to add : ";
std::cin >> value;
if (i == 0 || value > largestValue)
{
largestValue = value;
}
}
std::cout << "Largest value = " << largestValue << "\n";
return 0;
}
One solution would be to store your inputs in a list and sort them afterwards. Just google "sorting alorithms". Also there are nice youtube visualizations.
Another one would be to not save the inputs into dedicated variables - in your case x, y, z - but to always save the largest given input:
int largestInput = std::numeric_limits<int>::min();
int input;
for (int i = 0; i < 10000; i++)
{
std::cin >> input;
largestInput = input > largestInput ? input : largestInput;
}
If you know the inputs are large, you can use vectors.
#include <bits/stdc++.h>
using namespace std;
int main(){
int total_num=0;
cout << "Enter total numbers:" << "\n";
cin>>total_num;
int max_number = INT_MIN;
vector<int> v;
for(int i=0;i<total_num;i++){
int x;
cin>>x;
v.push_back(x);
max_number = max(max_number,x);
}
cout<<"Maximum number present: "<< max_number<<endl;
return 0;
}
Although there is no need to store numbers. But it's your choice if you need it later you can use it in that program.
> what are the things I need to learn
what if the user was asked to input a hundreds of numbers
For this, you'll need to learn about arrays. I suggest you first learn about C-style arrays (int x[3]{};), and then std::array (std::array<int, 3> x{};). You also need to learn about loops.
and should display the greatest among the numbers given
Having to find the largest number in an array is very common. If you want to learn how to do so manually, the other answers here should answer your question. Otherwise, look towards the standard library algorithms std::ranges::max() (C++20) and std::max_element.
Examples
Example 1
Here's a program that uses a C-style array and a simple algorithm to get the largest number:
#include <iostream>
int main(){
// Amount of numbers user should input
constexpr int count{ 3 };
std::cout << "Enter " << count
<< " numbers to decide which is the largest:\n";
// The numbers entered by the user
double numbers[count]{}; // Declare and zero-initialize a C-style array of 3 ints
// Get each number from the user and put it in the array
for (int i{ 0 }; i < count; ++i) {
std::cin >> numbers[i];
}
// The biggest number found so far
int max{ numbers[0] }; // Initialize it with the first number
for (int i{ 1 }; i < count; ++i) { // Start at the second element (element 1)
if (numbers[i] > max) { // If the current number is larger than max...
max = numbers[i]; // ...assign it to max
}
}
std::cout << max << " is the greatest among the numbers given\n";
return 0;
}
Note:
int numbers[count]{};
This creates a C-style array called numbers which has count (3) elements. The first element's "index" is 0 and the last element's is 2. The {} initializes the values of all of the numbers to 0 (good practice).
for (int i{ 0 }; i < count; ++i)
std::cin >> numbers[i];
This loops until i isn't less than count (3) and increments i (++i) each time. It starts at 0, so it loops 3 (0 1 2) times. On each iteration, it gets a number from the console and stores it in numbers[i].
Example 2
Here's a shorter program that uses the standard library:
#include <algorithm> // ranges::max()
#include <array> // array<>
#include <iostream> // cin, cout
int main() {
// Amount of numbers user should input
constexpr int count{ 3 };
std::cout << "Enter "
<< count
<< " numbers to decide which is the largest:\n";
std::array<double, count> numbers{}; // Declare an array of 3 ints
for (int i{ 0 }; i < count; ++i) {
std::cin >> numbers[i];
}
// Return the largest number in array "numbers"
std::cout << std::ranges::max(numbers)
<< " is the greatest among the numbers given\n";
return 0;
}
Note:
std::array<int, count> numbers{};
Declares an array of count (3) ints and zero-initializes it.
std::ranges::max(numbers)
This neat function finds the largest number in numbers. It was added in C++20 -- if you're using an older compiler, you should use *std::max_element(numbers.begin(), numbers.end()). If you want to learn how the latter works, you need to learn about iterators and pointers.
Here are some good practices that your tutorial hasn't taught you yet (if it ever will):
DON'T use using namespace std. It's unsafe because it brings everything in the standard library into global scope. The standard library contains a lot of commonly used identifiers like count and list. Bringing these into global scope is dangerous because it can cause naming conflicts.
Don't use copy initialization (int x = 3). Use uniform/brace/list initialization instead (int x{ 3 }). The former sometimes makes an unnecessary copy, whereas the latter doesn't. The latter also refuses to do narrowing conversions (e.g. initializing a short with a long).
Always initialize variables (do: int x{}, don't: int x), even when it seems redundant. If you don't, then the value stored is undefined - it could be anything. Undefined behaviour is hard to debug but luckily easy to avoid.
Use \n instead of std::endl. Both do the same, except std::endl does an extra buffer flush which is slow and unnecessary. \n is shorter anyways.
DRY -- Don't Repeat Yourself. You have the string " is the greatest among the numbers given" three times in your code. You could have stored it in a std::string instead -- then it wouldn't have repeated.
Repeating code is bad, because:
It's harder to read
It's harder to maintain (you would have to modify it everywhere it's repeated)
Maintenance is more error-prone
If I were you, I'd immediately find a different tutorial/book. See this thread.
#include <stdio.h>
int main()
{
int num1, num2, num3, num4;
printf("Enter num1\n");
scanf("%d",&num1);
printf("Enter num2\n");
scanf("%d",&num2);
printf("Enter num3\n");
scanf("%d",&num3);
printf("Enter num4\n");
scanf("%d",&num4);
if(num1>num2 && num1>num3 && num1>num4){
printf("greatest number is %d",num1);
}
if(num2>num3 && num2>num1 && num2>num4){
printf("greatest number is %d",num2);
}
if(num3>num1 && num3>num2 && num3>num4){
printf("greatest number is %d",num3);
}
if(num4>num1 && num4>num2 && num4>num3){
printf("greatest number is %d",num4);
}
return 0;
}

Unusal behaviour of sum in C++?

I'm writing a method to check if a number is palindrome or not. For example 12321 is palindrome and 98765 is not.
In my program I've used a recursive function to create exactly opposite of given number, like 56789 for 98765 and then checking if two numbers are equal or not. But I'm not getting exact opposite of 98765 which is 56789 instead I'm getting 56787.
Here's my code-
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
long int oppositeNum(int n){
if(n<10 && n>=0) return n;
if(n<0) return 0;
static int m=0;
int x = n%10;
long int num = oppositeNum(n/10);
cout << num << "\n";
return (num+ (x*pow(10,++m)));
}
int main(){
int n = 98765;
int oppNum = oppositeNum(n);
cout << oppNum;
if(oppNum==n){
cout << "Number is palindrome";
}else{
cout << "Number is not palindrome";
}
return 0;
}
I'm not getting the exact opposite of my original nnumber. the last digit is getting decremented by 1 every time is what I've observed.
Can anyone help?
I can not reproduce the result you are getting. Maybe it is a consequence of using the function pow
But in any case your function may not be called the second time for a different number because the static variable m is not reinitialized to 0. m continues to keep the value after the previous call of the function for a different number.
You can write the function without using the function pow.
Take into account that a reversed number can be too large to be stored an object of the type long because in some systems the type long has the same width as the type int. So I adjust instead of the type long to use the type long long as the return type.
Here you are.
#include <iostream>
long long int oppositeNum( int n )
{
static long long int multiplier = 1;
const int Base = 10;
int digit = n % Base;
return ( n /= Base ) == 0
? ( multiplier = 1, digit )
: ( n = oppositeNum( n ) , multiplier *= Base, digit * multiplier + n );
}
int main()
{
int n = 12321;
std::cout << n << " -> " << oppositeNum( n ) << '\n';
n = - 12321;
std::cout << n << " -> " << oppositeNum( n ) << '\n';
n = 98765;
std::cout << n << " -> " << oppositeNum( n ) << '\n';
n = -98765;
std::cout << n << " -> " << oppositeNum( n ) << '\n';
return 0;
}
The program output is
12321 -> 12321
-12321 -> -12321
98765 -> 56789
-98765 -> -56789
I changed only as much as it seemed neccessary. It still could use some tail recursion but this would probably required rewriting the whole algorithm.
long int oppositeNum(int n, int &m){
if(n<10) return n;
int x = n%10;
long int num = oppositeNum(n/10, m);
cout << num << "\n";
m *= 10;
return num + x * (long int)m;
}
long int oppositeNum(int n){
if(n<0) return 0;
int m = 1;
return oppositeNum(n, m);
}
What did I change:
Removed the static modifier from m and instead passing it by reference. This allows to use the function more than one time during the program execution. (Also it would allow to use the function by multiple threads at once but I guess this is not a concern here.)
Removed the floating point function pow and instead just multiplying the variable m by ten each iteration.
Added a wrapper for the recursive function so it still can be called with just one argument. Additionally this allow to check for negative numbers only once.
The main source of problem was the function pow. Because it works on floating point numbers, it may not give exact results. It depends on the compiler and the processor architecture but generally you shouldn't expect it to give an exact result. Rounding it to integer additionally increases the difference.
return (num + float(x*pow(10,++m)));
just do this and it will work. the ans is wrong cos the pow func is giving out 4999 and 5999 that is why it changes the units place.
Try this:
return round(num+ (x*pow(10,++m)));
Sometimes the pow function will return the approximated result. e.g. pow(10, 5) could be 99999.9999999, if you round it, you'll get 100000 else it takes the floor value (I think).

Get all ways to express a number as a product of two integers

I've been playing with finding divisors of numbers recently and decided to try and make a program, which prints all ways to express a number N as a product of two integers. I wrote one which works on positive numbers and only considers positive numbers to make up the product.
#include <iostream>
#include <cmath>
int main()
{
int n;
std::cin >> n;
int root = std::sqrt(n);
for(int i = 1; i <= root; i++)
{
if(n % i != 0)
continue;
int j = n / i;
std::cout << i << ", " << j << std::endl;
}
return 0;
}
The code above just finds all divisors of N and prints them as pairs. It works fine, but I wanted to try and make it find all possible ways to get to N, not only with positive numbers.
For example, if I input 10 in the program above, the results will be (1, 10), (2, 5); These are correct, but there are other ways to multiply two numbers and get to 10. It involves negative numbers: (-1, -10), (-2, -5) are also solutions, since when you multiply two negative numbers, you end up with a positive one.
If I wanted the program to only work on positive N values but also find negative multiples, I could just print the negative versions of i and j, since you can only get to a positive number by either multiplying two positive or two negative together.
That works, but now I want to get this code to work on negative N values. For example, an expected output for N = -10 would be: (-1, 10), (1, -10), (2, -5), (-2, 5);
The problem is, the algorithm above can only find positive divisors for positive numbers, since it involves square root, which is only defined for positive numbers, and the loop starts at a positive and ends at a positive.
I noticed that I can just calculate the square root of the absolute value of N, then make the loop start at -root and end at root to go over the negative divisors of N as well. I had to make sure to skip 0, though, because division with 0 isn't defined and that made it crash. The code I ended up with looks like this:
#include <iostream>
#include <cmath>
int main()
{
int n;
std::cin >> n;
int root_n = std::sqrt(std::abs(n));
for(int i = -root_n; i <= root_n; i++)
{
if(i == 0 || n % i != 0)
continue;
int j = n / i;
std::cout << i << ", " << j << std::endl;
}
return 0;
}
It worked properly for all the tests I came up with, but I am not sure if it's the best way to write it. Is there anything that I can improve?
Thanks in advance!
EDIT: Tried using std::div as suggested by Caleth (also used ReSharper addon in VS to give me refactoring suggestions):
#include <iostream>
#include <cstdlib>
int main()
{
int n;
std::cin >> n;
const int sqrt_n = std::sqrt(std::abs(n));
for(auto i = -sqrt_n; i <= sqrt_n; i++)
{
if (i == 0)
continue;
const auto div_res = std::div(n, i);
if (div_res.rem)
continue;
std::cout << i << ", " << div_res.quot << std::endl;
}
return 0;
}
Instead of calculating the remainder, then calculating the quotient, I can just do a single call to std::div, which returns a struct, containing both values.
A major observation is that the negative divisors and the positive divisors of a number are the same, except for sign. You could save half of the time if you looked only at positive numbers and handled signs on your own. For example,
int main()
{
int n;
std::cin >> n;
int root_n = std::sqrt(std::abs(n));
for(int i = 1; i <= root_n; i++) \\ don't loop over negative numbers now
{
if(n % i != 0) \\ not necessary to check for 0 anymore
continue;
int j = n / i;
std::cout << i << ", " << j << "\n";
std::cout << -i << ", " << -j << "\n"; \\ corresponding negative
}
return 0;
}
You might notice that I removed std::endl --- you don't really need to flush the stream that often. It's faster to let output buffer as it wants.
If you are looking for other ways to modify your program, you might try finding the prime factorization and then computing lists of divisors from it. For large, highly composite inputs, this will be faster. But it's also quite different.

Finding the closest number of array to another given number

I have this program to write that I have a array of 11 numbers entered from me. Then I need to find the avarage sum of those numbers, and then im asked to find the closest number of this array to the avarage sum, and then the most distant element of the array to the avarage sum again. SO far I manage to write a program to create this array and find the avarage sum. I asssume there is something to do with abs function of cmath libary , but so far I only fail to make it.
#include <iostream>
using namespace std;
int main() {
unsigned const int size = 11;
float number[size];
for (unsigned i = 0; i<size; i++) {
cout << "Please enter value for number "
<< i + 1 << ":";
cin >> number[i];
}
for (unsigned i = 0; i<size; i++) {
cout << "Number " << i + 1 << " is : "
<< number[i] << endl;
}
unsigned int sum = 0;
for (unsigned i = 0; i<size; i++) {
sum += number[i];
}
What is the problem? You are not asking a question, just making a statement... It does seem that you have not posted the whole code..
In c++ usually to use "abs" you should use fabs from the "math.h" library!
You will be okay with the compare operators.
Just traverse your array in a loop and calculate the difference between your compare value and the current value on your array. Initiate a temporary variable that keeps the array entry that created the smallest difference.
Every time a difference that is smaller than the current one comes up replace the value in your temporary variable.
So you replace under the following condition: If |number[i] - average_value| < |tmp_closest_val -average_val| Then tmp_closest_val = number[i] EndIf.
I hope you get the concept from that rough draft.

C++ Long Division

Whilst working on a personal project of mine, I came across a need to divide two very large arbitrary numbers (each number having roughly 100 digits).
So i wrote out the very basic code for division (i.e., answer = a/b, where a and b are imputed by the user)and quickly discovered that it only has a precision of 16 digits! It may be obvious at this point that Im not a coder!
So i searched the internet and found a code that, as far as i can tell, uses the traditional method of long division by making a string(but too be honest im not sure as im quite confused by it). But upon running the code it gives out some incorrect answers and wont work at all if a>b.
Im not even sure if there's a better way to solve this problem than the method in the code below!? Maybe there's a simpler code??
So basically i need help to write a code, in C++, to divide two very large numbers.
Any help or suggestions are greatly appreciated!
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std; //avoids having to use std:: with cout/cin
int main (int argc, char **argv)
{
string dividend, divisor, difference, a, b, s, tempstring = ""; // a and b used to store dividend and divisor.
int quotient, inta, intb, diff, tempint = 0;
char d;
quotient = 0;
cout << "Enter the dividend? "; //larger number (on top)
cin >> a;
cout << "Enter the divisor? "; //smaller number (on bottom)
cin >> b;
//making the strings the same length by adding 0's to the beggining of string.
while (a.length() < b.length()) a = '0'+a; // a has less digits than b add 0's
while (b.length() < a.length()) b = '0'+b; // b has less digits than a add 0's
inta = a[0]-'0'; // getting first digit in both strings
intb = b[0]-'0';
//if a<b print remainder out (a) and return 0
if (inta < intb)
{
cout << "Quotient: 0 " << endl << "Remainder: " << a << endl;
}
else
{
a = '0'+a;
b = '0'+b;
diff = intb;
//s = b;
// while ( s >= b )
do
{
for (int i = a.length()-1; i>=0; i--) // do subtraction until end of string
{
inta = a[i]-'0'; // converting ascii to int, used for munipulation
intb = b[i]-'0';
if (inta < intb) // borrow if needed
{
a[i-1]--; //borrow from next digit
a[i] += 10;
}
diff = a[i] - b[i];
char d = diff+'0';
s = d + s; //this + is appending two strings, not performing addition.
}
quotient++;
a = s;
// strcpy (a, s);
}
while (s >= b); // fails after dividing 3 x's
cout << "s string: " << s << endl;
cout << "a string: " << a << endl;
cout << "Quotient: " << quotient << endl;
//cout << "Remainder: " << s << endl;
}
system ("pause");
return 0;
cin.get(); // allows the user to enter variable without instantly ending the program
cin.get(); // allows the user to enter variable without instantly ending the program
}
There are much better methods than that. This subtractive method is arbitrarily slow for large dividends and small divisors. The canonical method is given as Algorithm D in Knuth, D.E., The Art of Computer Programming, volume 2, but I'm sure you will find it online. I'd be astonished if it wasn't in Wikipedia somewhere.