Wydaje mi się, że Twój problem leży w realizowanym algorytmie, używany typ liczby tylko zaciemnił Ci problem
tzn. jakiego byś typu nie użył - reprezentacja liczby niewymiernej zawsze jakoś obcina - niewymierność
co rzutuje na obliczenia ?, a tym samym na wyniki
podstawowym problemem są liczby niewymierne, których musisz używać
podam najprostszy trywialny przykład : 2*(1/3+1/6)
2 - wymierna
1/3 - niewymierna
1/6 - niewymierna
ale złożenie tego daje nam liczbę wymierną
przy realizacji tego w programie możemy osiągniemy wymierność wyniku
ale można się spodziewać, że niekoniecznie wynikiem będzie zawsze 1
tzn. coś tam na dalekim miejscu miedzy (1/3 + 1/6) różni się od 1/2
(nie sprawdzałem ale oczywiście chodzi o pokazaniu problemu, a nie ten konkretny przykład)
stąd dla mnie jest oczywistym jest, że np.
for( int i = 0; i < pXn.size(); ++i )
{
mpz_ui_pow_ui( pow1.get_mpz_t(), 2, pXn[ i ][ pXIndxs[ i ] ] );
mpz_ui_pow_ui( pow2.get_mpz_t(), pP, i );
mpz_ui_pow_ui( pow3.get_mpz_t(), 2, i );
tmpf = pow1 * pow2;
tmpf /= pow3;
w += tmpf;
}
generuje w każdej operacji błędy (niewymierności).
które mogą rzutować na otrzymywane wyniki
Przyznam się, że nie chce mi się rozgryzać Twojego algorytmu, dlatego być może jest to inne podobne miejsce (albo i tam masz problem)
Myślę, że znasz Ten algorytm na pamięć i znajdziesz to szybko sam.
pytanie czy da się to naprawić :-)
Osobiście napisałbym inny algorytm do rozwiązania tego problemu "sprawdzić liczbę"
w = (2^x1 + 2^x2 * p/2 + 2^x3 * p^2/4 + 2^x4 * p^3/8 + ... + p^(y-1)/2^(y-1))
* 2^(y-1)
/(2^(x+y)-p^y)
podzieliłem na 3 kawałki bo każdy z nich jest wymierny (nawet całkowity)
istotne na błędy niewymierność są / (dzielenia) i * (mnożenia)
- dzielenie na pewno bardzo istotne
- mnożenie w pewnych przypadkach chyba też ( ? ale nie zawsze)
- pamiętamy, że potęgowanie to też mnożenie
czy możemy zastąpić je operacją, która usunie ten problem ?
mam przekonanie, że tak "+" dodawanie i "-" odejmowanie
liczba wymierna + liczba wymierna -> liczba wymierna
liczba wymierna - liczba wymierna -> liczba wymierna
teraz już tylko rozwiązać problem "niezmienności" liczby wymiernej
tzn. nie przekroczenia zakresu
nie używałem "zmiennych GMP", ale to może wystarczy - nie jest to jednak podstawowy problem tego algorytmu.
Z powyżej opisanego powodu zmieniłbym algorytm na używający powyżej opisanych zasad "-" zamiast "/"
"+" zamiast "*" i potęgowania - jeśli "-" nie wystarczy