Как рассчитать 2 ^ -18, используя GMP? - PullRequest
4 голосов
/ 07 января 2009

Я только что обнаружил, к моему смущению, что подача отрицательных показателей к mpz_pow_ui не очень хорошо работает. («Вы знаете, что в руководстве написано unsigned long».) Для других mpz_pow функций в руководстве используются понятия, которые я не понимаю. Например, " base ^ exp mod mod " в следующем:

void mpz_powm (mpz_t rop, mpz_t base, mpz_t exp, mpz_t mod) 
void mpz_powm_ui (mpz_t rop, mpz_t base, unsigned long int exp, mpz_t mod)
Set _rop_ to _base_^_exp_ mod _mod_.
Negative exp is supported if an inverse base-1 mod mod exists (see mpz_invert in Section 5.9 [Number Theoretic Functions], page 35). If an inverse doesn’t exist then a divide by zero is raised.

В следующем коде, что я должен изменить, чтобы он мог обрабатывать отрицательные показатели?

#define Z(x) mpz_t x; mpz_init( x );

BSTR __stdcall IBIGPOWER(BSTR p1, long p2 ) {
    USES_CONVERSION;

    Z(n1);
    Z(res);

    LPSTR sNum1 = W2A( p1 );

    mpz_set_str( n1, sNum1, 10 );

    mpz_pow_ui( res, n1, p2 );

    char * buff =  (char *) _alloca( mpz_sizeinbase( res, 10 ) + 2 );

    mpz_get_str(buff, 10, res);

    BSTR bResult = _com_util::ConvertStringToBSTR( buff );
    return bResult;
}

Ответы [ 5 ]

9 голосов
/ 07 января 2009

Я не буду сокращать код для вас, но я сообщу вам, что:

2<sup>-n</sup> = <sup>1</sup>/<sub>2<sup>n</sup></sub>

Таким образом, вы можете просто передать положительную экспоненту и затем разделить 1 на это число (и выбрать нецелочисленный тип, например mpf_t - тип mpz_t является целым, поэтому не может представлять действительные числа, такие как 2<sup>-18</sup>).

7 голосов
/ 07 января 2009

Тип данных mpz_t может хранить только целые числа, а 2 -18 не является целым числом. Чтобы вычислить это, вам нужно использовать тип с плавающей точкой mpf_t или тип рационального числа mpq_t.

2 голосов
/ 07 января 2009

Я не знаю много о GMP, но:

2 ^ -18

эквивалентно:

1 / (2 ^ 18)

Так почему бы не написать функцию, которая обрабатывает отрицательные показатели таким образом?

1 голос
/ 08 января 2009

Отрицательный опыт поддерживается, если существует обратный мод base-1 (см. mpz_invert в Разделе 5.9 [Номер Теоретические функции], стр. 35). Если обратного не существует, то делим на ноль повышен.

Если вы говорите об этом, это касается теории чисел. Деление, или, точнее, обратное умножение, существует только при определенных условиях. Я точно не помню правила, но в основном говорится, что операция деления не будет работать, если base-1 mod mod не существует.

0 голосов
/ 07 января 2009

То, что вам нужно сделать, зависит от того, что вы хотите сделать с битами, которые будут потеряны в операции. Поскольку вы имеете дело с целыми числами, повышение до отрицательной степени подразумевает деление (ну, возвратно-поступательное движение), но GMP предлагает несколько форм деление .

...