lukequaint pisze:Deklaruje się tak samo, ale następnie trzeba zainicjalizować odpowiednimi funkcjami (np. mpz_inits poniżej).
To tłumaczy dlaczego miałem z tym problem.
lukequaint pisze:
Przeczytaj dokładnie dokumentację, wszystko jest jasno opisane.
Niestety jak na razie nie rozumiem większości tej dokumentacji.
Przykład programu działa i zwraca podane wyniki, ale mam kilka pytań.
Tutaj zmiennym są przypisane wartości zero i są inicjowane. Ale można je po prostu zainicjować bez przypisania im żadnej wartości?
Kod: Zaznacz cały
mpz_set_str(bn2, "1234567890987654321", 10);
Ta funkcja "set" jak rozumiem po prostu przypisuje zmiennym wartości? A nie można tego zrobić np. tak bn2=11111? Co to jest ten ukośnik i 0 w drugiej wartości?
Kod: Zaznacz cały
mpz_add_ui(bn1, bn1, 8889);
mpz_add(bn3, bn3, bn1);
Tutaj mamy dodawanie - i mam rozumieć, że zapisu zwykłego dodawania program w przypadku tych zmiennych nie wykona?
Ogólnie mam do "przekonwertowania" na GMP następujący program, który nie ja napisałem, bo moje umiejętności przekracza i nie do końca potrafię zidentyfikować nawet rodzaje zmiennych, które zostały tu zastosowane (np. computeW):
Kod: Zaznacz cały
#include <iostream>
#include <iomanip>
using namespace std;
#include <conio.h>
#include <string>
#include <vector>
#include <cmath>
#include <limits>
//====================================================================================================================
double computeW( int pX, int pY, int pP, const vector < vector < int >>& pXn, const vector < int >& pXIndxs );
bool isNaturalNum( double value );
//====================================================================================================================
int main()
{
int x;
int y;
int p;
cout << "Podaj p: ";
cin >> p;
cout << "Podaj y: ";
cin >> y;
cout << "Podaj x: ";
cin >> x;
vector < vector < int >> xn( y - 1, vector < int >( x + 1 ) );
for( auto & vec: xn )
{
for( int i = 0; i <= x; ++i )
{
vec[ i ] = i;
}
}
vector < int > xIndxs( xn.size(), 0 );
double w;
bool exit = false;
double counter = 0;
unsigned long long howManyFound = 0;
cout << "Start " << endl;
while( !exit )
{
counter++;
w = computeW( x, y, p, xn, xIndxs );
if( isNaturalNum( w ) )
{
++howManyFound;
cout << "w = " << fixed << w << "; ";
for( int i = 0; i < xn.size(); ++i )
{
cout << "x" << i + 1 << "=" << xn[ i ][ xIndxs[ i ] ] <<( i == xn.size() - 1 ? ""
: ", " );
}
cout << endl;
}
++xIndxs[ 0 ];
for( int j = xIndxs.size() - 1; j > 0; --j )
{
if( xIndxs[ j ] == x )
{
if( j == xIndxs.size() - 1 ) { exit = true; break; }
++xIndxs[ j + 1 ];
for( int pom = j; pom >= 0; --pom )
{
xIndxs[ pom ] = xIndxs[ j + 1 ];
}
break;
}
}
if( xIndxs[ 0 ] == x + 1 )
{
if( xIndxs.size() >= 2 )
{
++xIndxs[ 1 ];
xIndxs[ 0 ] = xIndxs[ 1 ];
}
else
{
exit = true;
}
}
}
cout << "Koniec" << endl;
cout << "wszystkich iteracji: " << fixed << setprecision( 0 ) << counter << endl;
cout << "Policzonych całkowitych liczb w: " << howManyFound << endl;
if(pow( 2, y+x )-pow( p, y )<0)
{
cout << "Ujemne" << endl;
}
getch();
return 0;
}
//====================================================================================================================
double computeW( int pX, int pY, int pP, const vector < vector < int >>& pXn, const vector < int >& pXIndxs )
{
double retVal = 0;
int lastPow;
for( int i = 0; i < pXn.size(); ++i )
{
retVal += pow( 2, pXn[ i ][ pXIndxs[ i ] ] ) * pow( pP, i ) / pow( 2, i );
lastPow = i + 1;
}
retVal += pow( pP, pY - 1 ) / pow( 2, pY - 1 );
retVal *= pow( 2, pY - 1 );
retVal /= abs(pow( 2, pX + pY ) - pow( pP, pY ));
return retVal;
}
//*****************************************************************************
bool isNaturalNum( double value )
{
unsigned long long intPart = value;
double rest = value - intPart;
return rest == 0;
}
//*****************************************************************************
Program zwraca błędne wartości dla większych wykładników i zmiennych, np. p=49667, y=5, x=73. Nie potrafi policzyć np.:
\(\displaystyle{ w=\left( 1, \frac {49667} {2}, \frac {49667^{2}} {4}, \frac{ 49667^{3}} {8}, \frac {49667^{4}} {16} \right) \cdot 16 \cdot \left[\begin{array}{ccc}2^{70}\\2^{70}\\2^{70}\\2^{70}\\1\end{array}\right]}\)
tylko zwraca błędny wynik, który identyfikuje także błędne jako całkowity. Zastanawiam, czy wystarczy, że przypiszę liczbie
\(\displaystyle{ w}\) nieograniczoną długość i kilka miejsc po przecinku oraz zmienię retVal, żeby program przestał mieć problemy? Dodatkowo, czy jeżeli chcę sprawdzić naturalność
\(\displaystyle{ w}\), a będzie ona ponad-standardowo duża, to też powinienem użyć jakiejś dedykowanej do tego funkcji? Ponadto czy coś takiego będzie działać w GMP:
Kod: Zaznacz cały
double computeW( int pX, int pY, int pP, const vector < vector < int >>& pXn, const vector < int >& pXIndxs )
Tu jest zdefiniowany chyba wektor lub działanie wektorowe. Jaką zmienną w GMP przypisać computeW?