Как рассчитать 2 ^ -18 с использованием GMP?
Я только что обнаружил, к моему смущению, что кормление отрицательных показателей mpz_pow_ui
не очень хорошо работает ("В руководстве написано, что без знака долго, вы знаете.") 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 ответов
mpz_t
Тип данных может хранить только целые числа, а 2 -18 не является целым числом. Чтобы вычислить это, вы должны будете использовать тип с плавающей точкой mpf_t
или тип рационального числа mpq_t
,
Я не буду сокращать код для вас, но я дам вам знать, что:
2-n = 1/2n
Таким образом, вы можете просто передать положительный показатель, а затем разделить 1 на это число (и выбрать нецелочисленный тип, такой как mpf_t
- mpz_t
тип является целым, поэтому не может представлять реальные числа, такие как 2-18
).
Я не знаю много о GMP, но:
2 ^ -18
эквивалентно:
1 / (2 ^ 18)
Так почему бы не написать функцию, которая обрабатывает отрицательные показатели таким образом?
Отрицательный exp поддерживается, если существует обратный мод base-1 (см. Mpz_invert в Разделе 5.9 [Теоретические функции чисел], стр. 35). Если обратного не существует, то делится на ноль.
Если вы говорите об этом, это касается теории чисел. Деление, или, точнее, обратное умножение, существует только при определенных условиях. Я точно не помню правила, но в основном это говорит о том, что операция деления не будет работать, если мод мода base-1 не существует.
Что вам нужно сделать, зависит от того, что вы хотите, чтобы произошло с битами, которые будут потеряны в операции. Поскольку вы имеете дело с целыми числами, возведение в отрицательную степень подразумевает деление (ну, взаимность), но GMP предлагает несколько форм деления.