Вопрос

Я только что обнаружил, к моему смущению, что подача отрицательных показателей в 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;
}
Это было полезно?

Решение

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

Другие советы

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

2 -n = 1 / 2 n

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

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

2 ^ -18

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

1 / (2 ^ 18)

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

  

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top