GMP mpz_t variable being set with incorrect value - c++

I've been working on the Euler 29 problem for a few days and am having difficulty getting the mpz_t type to work correctly. The objective is to iterate through a^b for values of 2 <= a,b <= 100 and count the nonrepeat values.
Using vector I was able to store the values using pointers in an array like so:
mpz_t a;
mpz_init(a);
vector<mpz_t*> numbers;
numbers.push_back(&a);
However, when running the full program below you can see that after it inserts the first value 4, it doesn't insert any new values. This is because the temp value being compared to rop is not being set to what is already in the array, and instead is set to the value shared by rop.
#include <iostream>
#include <vector>
#include <chrono>
#include "gmp.h"
using namespace std;
int main()
{
auto start = std::chrono::high_resolution_clock::now();
int solution = 0;
bool found = false;
int r = 10;
mpz_t rop;
mpz_init(rop);
mpz_t temp;
mpz_init(temp);
vector<mpz_t*> numbers;
for(int a = 2; a <= 5; a++)
{
for(int b = 2; b <= 5; b++)
{
mpz_ui_pow_ui(rop, a, b);
for(int i = 0; i < numbers.size(); i++)
{
cout << "i: " << i << endl;
cout << "rop: ";
mpz_out_str(stdout,10,rop);
cout << endl;
mpz_set(temp,*(numbers.at(i)));
cout << " temp: ";
mpz_out_str(stdout,10,temp);
cout << endl;
r = mpz_cmp(rop,temp);
cout << " r: " << r << endl << endl;
if(r == 0)
{
found = true;
break;
}
}
if(found == false)
{
numbers.push_back(&rop);
solution++;
cout << "pushed! " << endl << endl;
}
found = false;
}
}
auto done = std::chrono::high_resolution_clock::now();
cout << "Solution: " << solution << endl << endl;
cout << "Program completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(done - start).count() << " milliseconds." << endl;
}
This line of code should be setting temp equal to 4 at the start of the forloop, but instead sets it equal to rop:
mpz_set(temp,*(numbers.at(i)));
Since the problem clearly has to do with the fact I'm using pointers and passing the actual address in memory to store these mpz_t variables, how can I change the code so that it is able to work properly? I'm under the impression using the function mpz_clear(rop) after each push_back to the numbers vector wouldn't work as it releases the address from memory.

I figured out that due to the way mpz_t variables work the mpz_set function does not work with a pointer to mpz_t type variables as a parameter.
Instead, I was able to get the program to work by assigning the mpz_get_str function to a string and pushing that to a vector of strings to check for repeat values.
mpz_t rop;
mpz_init(rop);
char * num;
vector<string> numbers;
num = mpz_get_str(num,10,rop)
numbers.push_back(num);

Related

What should be the proper declaration of array while finding the largest number in array?

C++ This is my code in C++ for finding the largest number in array. When I was running in my IDE then there was no compilation error but it was not giving me output. I think the problem is in the declaration of array at line 8. I replaced the array declaration from line 8 to line 11 then it is working fine in my IDE. So I didn't get it that why the declaration of array was not working at line 8?
#include <bits/stdc++.h>
using namespace std;
int largest_in_array(int a[], int n);
int main() // main function
{
int n; // User will enter the size of array
int arr[n]; // Line 8
cout << "Enter the size of array: " << endl;
cin >> n;
// Line 11
cout << "\nEnter the elements of array: " << endl;
for (int i = 0; i < n; i++) // This loop will run for each element of array that user wants to enter
{
cout << "Enter the " << (i + 1) << " element:";
cin >> arr[i];
cout << endl;
}
cout << "Elements are: [";
for (int i = 0; i < n; i++) // Prints the elements of array
{
// cout << "Enter the " << (i + 1) << " element:";
cout << arr[i] << " ";
// cout << endl;
}
cout << "]";
int res = largest_in_array(arr, n); //Function call
cout << "\nLargest element in array is: " << arr[res] << endl;
return 0;
}
int largest_in_array(int a[], int n) // function that will return the index of largest element in array
{
int max = 0;
for (int i = 1; i < n; i++)
{
if (a[max] < a[i])
{
max = i;
}
}
return max;
}
You declare int arr[n]; before the user has entered a value into n. n has an indeterminate value when you read it and create arr.
You don't check that the user enters a positive value into n. Zero and negative sized arrays are not valid.
Other points:
bits/stdc++.h is not a standard header which makes your program not portable. Use the proper header files, like iostream etc.
arr[n] is a Variable Length Array (VLA) which is not part of standard C++. Make it a std::vector<int> arr(n); instead.
The use of std::endl is unnessesary. There is no need to flush the output streams here. Use \n instead.
Example:
#include <iostream>
#include <limits>
#include <vector>
int largest_in_array(const std::vector<int>& a) {
int max = 0;
for(int i = 1; i < a.size(); i++) {
if(a[max] < a[i]) {
max = i;
}
}
return max;
}
int main() // main function
{
int n; // User will enter the size of array
std::cout << "Enter the size of array:\n";
// check that input succeeds and that the value is valid
if(!(std::cin >> n) || n < 1) return 1;
std::vector<int> arr(n);
std::cout << "\nEnter the elements of array:\n";
for(int i = 0; i < n; i++)
{
std::cout << "Enter the " << (i + 1) << " element:";
if(!(std::cin >> arr[i])) {
std::cout << "invalid input, bye bye\n";
return 1;
}
}
std::cout << "Elements are: [";
for(int i = 0; i < n; i++)
{
std::cout << arr[i] << " ";
}
std::cout << "]";
int res = largest_in_array(arr); // Function call
std::cout << "\nLargest element in array is: " << arr[res] << '\n';
}
That said, you could however use the standard algorithm std::max_element instead of writing your own. It returns an iterator to the maximum element.
You could also make use of range-based for loop when you don't need to know the index in the array, as in your second loop.
Example:
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <iterator>
#include <limits>
#include <vector>
int main() {
int n; // User will enter the size of array
std::cout << "Enter the size of array:\n";
if(!(std::cin >> n) || n < 1) return 1;
std::vector<int> arr(n);
std::cout << "\nEnter the elements of array:\n";
for(int i = 0; i < n; i++) // This loop will run for each element of
// array that user wants to enter
{
std::cout << "Enter the " << (i + 1) << " element:";
if(!(std::cin >> arr[i])) {
std::cout << "invalid input, bye bye\n";
return 1;
}
}
std::cout << "Elements are: [";
for(auto value : arr) { // a range-based for loop
std::cout << value << ' ';
}
std::cout << "]\n";
auto res = std::max_element(arr.begin(), arr.end());
std::cout << "Largest element in array is: " << *res << '\n';
std::size_t index = std::distance(arr.begin(), res);
std::cout << "which has index " << index << '\n';
}
When you have int n on line 8 it is initialized when you use it to create the array. When n is initialized explicitly, it's value is undefined behavior. You may be creating an array larger than the n you inputted on line 10, resulting in the array having extra random junk, it may be smaller meaning your program read memory it really shouldn't, etc.

How to solve a while loop that suddenly terminates itself?

I have code to look for permutations which takes input from the user until the user is satisfied with the amount of input added.
However, when receiving more than 4x input, the code suddenly stuck/terminated itself. I've tried changing the array type to dynamic memory, but the result continues to be the same.
Strangely when I test this code using http://cpp.sh/, it runs normally. I think the problem is with my compiler (I used VS code and MinGW to compile and run it.) What do you think is wrong?
My code is below:
#include <iostream>
#include <string>
using namespace std;
int main() {
int KombAngka;
bool Lanjut = true;
int x = 0;
int *Angka = new int(x);
string YaTidak;
while(Lanjut) {
cout << "Number-" << x + 1 << ": ";
cin >> Angka[x];
LoopYaTidak:
cout << "Are the numbers enough?(y/n)?: ";
cin >> YaTidak;
if (YaTidak == "y") {
Lanjut = false;
}
else if (YaTidak == "n") {
Lanjut = true;
}
else {
cout << "Enter the correct answer!(y/n)" << endl;
goto LoopYaTidak;
}
x++;
}
cout << "All numbers: (";
for (int z = 0; z <= x - 2; z++) {
cout << Angka[z] << ", ";
}
cout << Angka[x - 1] << ")" << endl;
cout << "The number of combinations of numbers used: ";
cin >> KombAngka;
int JumlahAngka = x;
const int StopLoop = JumlahAngka - KombAngka;
for (int i = JumlahAngka - 1; i > StopLoop; i--) {
JumlahAngka = JumlahAngka * i;
}
cout << "The number of queue numbers consisting of " << KombAngka << " different numbers are " << JumlahAngka << endl;
system("pause");
return 0;
}
This line
int *Angka = new int(x);
creates an integer on the heap with a value held by x which here it is 0.
You are accessing memory which you should not, and as mentioned by #fredrik it may cause a buffer overflow.
If you want to create an array on the heap you should do
int *Angka = new int[x];
This creates an array (on heap) of size x.
But since you are using c++ it's better to use vectors, you can simply create a vector with
std::vector<int> Angka;
Vector will take care of memory allocation and all other stuff that you would have to handle if you were to create an array with new.

How To Print Values Stored in an Array

I am working to create a function where I take in 6 values (3 strings, 3 ints), store those values in arrays, then print out each of those values in pairs of 2
Here is what I have:
#include <iostream>
#include <string>
using namespace std;
int main()
{
const int SIZE = 3;
int time[SIZE] = {};
string name[SIZE] = {};
for (int a = 0; a < 3; a++)
{
cout << "Enter runner name: ";
getline (cin, name[+1]);
cout << "Enter runner time: ";
cin >> time[+1];
cin.ignore();
}
for (int a = 0; a < 3; a++)
{
cout << name << " finished in " << time << "\n";
}
return 0;
}
I would like my output to look like this:
name1 finished in time1
name2 finished in time2
name3 finished in time3
Currently, my output looks like this:
0x22fdf0 finished in 0x22fe10
0x22fdf0 finished in 0x22fe10
0x22fdf0 finished in 0x22fe10
How can I get the inputs to be stored in the arrays then output those values to the user?
If this has been answered already, apologies. I haven't been able to find an example where the arrays are populated with user input values and then returned to the display.
You need to actually index the array using the [] subscript operator. Likewise, when printing, you should attempt to index an element in the array. Since when you attempt to print the array itself, the compiler will implicitly convert the array to a pointer, which, when printed, will print the memory address of the first element in that array, rather than the element itself.
So you could dereference the arrays to get the first value in each, but a better way is to index it by the a variable in your for loop, like so:
#include <iostream>
#include <string>
using namespace std;
int main() {
const int SIZE = 3;
int time[SIZE] = {};
string name[SIZE] = {};
for (int a = 0; a < 3; a++) {
cout << "Enter runner name: ";
getline(cin, name[a]);
cout << "Enter runner time: ";
cin >> time[a];
cin.ignore();
}
for (int a = 0; a < 3; a++) {
cout << name[a] << " finished in " << time[a] << "\n";
}
return 0;
}
Alternatively, if you wanted to not index it, you could use your original approach, but then you would have to dereference the pointer using the * dereference operator:
for (int a = 0; a < 3; a++) {
cout << *name << " finished in " << *time<< "\n";
}
However, now you would simply print the first element three times. So to remedy this, you need to employ some pointer arithmetic, and increase the value by a, to get the elements, 0, 1, and 2 past the first element respectively:
for (int a = 0; a < 3; a++) {
cout << *(name + a) << " finished in " << *(time + a)<< "\n";
}
So some things to look up:
* Dereferncing
* Subscripting
* Implicit array to pointer conversion

Creating a Table of Powers with C++

I'm working on a project to print out a table of exponential numbers using nested for-loops. Users specify the number of rows to print and the number of powers. For example, if the users specifies 2 rows and 3 powers, the program should print 1,1,1 and 2,4,9 (2^1,2,3 etc). I should note this is for class and we aren't allowed to use cmath, otherwise I would use pow(). I can't seem to figure out the correct function in a nested for loop that can change both values of the base and the exponent. Here's what I have so far. Thanks for your help!
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
int r, p, a;
cout << "The program prints a table of exponential powers.\nEnter the number of rows to print: ";
cin >> r;
cout << "Enter the number of powers to print: " ;
cin >> p;
cout << endl;
for (int i = 1 ; i <= r; i++)
{
cout << setw(2) << i;
for (int q = 1; q <= i; q++)
{
a = (q * q); //This only works for static numbers...
cout << setw(8) << a;
}
cout << endl;
}
}
for (int i = 1 ; i <= r; i++)
{
cout << setw(2) << i;
int a = 1;
for (int q = 1; q <= r; q++)
{
a = (a * i);
cout << setw(8) << a;
}
cout << endl;
}
Several things to note. First, you can compute the powers by maintaining the variable a and multiplying it by i for each power. Also, I think you want the upper bound on your second loop to be r and not i.
You need couple to change the way accumulate the values of raising a number to a power.
Also, you are using the wrong variable to end the loop in the inner for-loop.
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
int r, p, a;
cout << "The program prints a table of exponential powers.\nEnter the number of rows to print: ";
cin >> r;
cout << "Enter the number of powers to print: " ;
cin >> p;
cout << endl;
for (int i = 1 ; i <= r; i++)
{
cout << setw(2) << i;
a = 1; // Start with 1
for (int q = 1; q <= p; q++) // That needs to <= p, not <= i
{
a *= i; // Multiply it by i get the value of i^q
cout << setw(8) << a;
}
cout << endl;
}
}

Using pointer arithmetic to add the contents of two arrays and save to an empty array

So I have written a function that should simply add the values of each element stored in two separate arrays, and save them to a third array.
I don't understand what the issue is, I am simply adding together the value of the int stored at the location referenced by each of my pointers, and saving it to my third, empty, array.
My code compiles just fine, but when I loop to print the contents of my third array (which should contain the sum of the two previous arrays elements at their respective indexes) it just prints a bunch of memory addresses. What gives?
EDIT: I fixed my while loop to perform the arithmetic, and everything is working well. My working code is below. Hope it helps someone else.
#include<iostream>
#include<stdlib.h>
using namespace std;
void arrayAdd(int firstArray[], int secondArray[], int targetArray[], int size){
int *firstPtr = firstArray;
int *secondPtr = secondArray;
int *tragetPtr = targetArray;
while (firstPtr <= &firstArray[size - 1] ){
//add the first two array elements
*tragetPtr = (*firstPtr + *secondPtr);
// point to the next location
*firstPtr++;
*secondPtr++;
*tragetPtr++;
}
}
int main() {
int totalElements;
const size_t ARRAY_SIZE = 50;
int firstIntegerArray[ARRAY_SIZE];
int secondIntegerArray[ARRAY_SIZE];
int thirdIntegerArray[ARRAY_SIZE];
cout << "Please enter the total number of elements for your array: ";
cin >> totalElements;
for(int i = 0; i < totalElements; i++){
cout << "Please enter a value for the first array at index " << i << ": ";
cin >> firstIntegerArray[i];
}
for(int i = 0; i < totalElements; i++){
cout << "Please enter a value for the second array at index " << i << ": ";
cin >> secondIntegerArray[i];
}
//run our arrayAdd function
arrayAdd(firstIntegerArray, secondIntegerArray, thirdIntegerArray, totalElements);
cout << "The conents of your two arrays added together is; " << endl;
for(int i = 0; i < totalElements; i++){
cout << thirdIntegerArray[i] << ", ";
}
return 0;
}
A local array decays to a pointer when it is passed to a function, so you can't use sizeof on it anymore. Indeed this:
void arrayAdd(int firstArray[]) {
int *firstPtr = firstArray;
std::cout << "sizeof(firstArray) == " << sizeof(firstArray) << std::endl;
std::cout << "sizeof(firstPtr) == " << sizeof(firstPtr) << std::endl;
}
int main() {
int test[] = {1,2,3,4,5,6,7,8,9,0};
arrayAdd(test);
return 0;
}
Prints:
sizeof(firstArray) == 8
sizeof(firstPtr) == 8
on my 64 bit machine.
Casting int[] to int* doesn't change anything since it already became a pointer as an argument. You should pass the size of the array to the method or, since you are working with C++, use an std::array or std::vector which will just solve any problem.