Как рассчитать 2 ^ -18, используя GMP?
Вопрос
Я только что обнаружил, к моему смущению, что подача отрицательных показателей в 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 предлагает несколько форм подразделение .