Преобразование uint64 в номер GMP / MPIR

Я использую MPIR 2.4.0 в Windows (MSVC 2010), и я пытался добавить 64-битное целое число без знака к номеру mpz_t. Однако кажется, что MPIR / GMP не поддерживает прямое преобразование между 64-битными целыми числами и mpz_t. Означает ли это, что мне нужно преобразовать свой uint64 в строку и прочитать это через mpz_init_set_str? Это не очень привлекательно и не выглядит очень быстрым - две конверсии впустую.

Я что-то пропустил или какой трюк / хак здесь использовать?

Ваше здоровье,

Филипп


person ThE_-_BliZZarD    schedule 06.07.2011    source источник


Ответы (5)


Как было предложено Бантаром, используйте mpz_import, но я бы предложил следующее, которое не зависит от порядка байтов платформы:

mpz_import(b, 1, 1, sizeof(a), 0, 0, &a);
person Frank    schedule 06.07.2011
comment
Спасибо, как уже сказал Стивен Кэнон: я не знал об этой функции, очень полезной :) Но я все же думаю, что для библиотеки такого размера странно не рассматривать int64: / - person ThE_-_BliZZarD; 12.07.2011
comment
На самом деле использование mpz_import оказывается медленнее, чем установка lhigher 32 бита, mul_2exp для смещения на 32 бита, затем добавление младших 32 бита, а если число отрицательное, отрицание mp_size - person Eric Grange; 18.08.2020


Да, если вы работаете на платформе (Windows), которая не использует модель LP64, тогда нет функции для присвоения 64-битного целого числа mpz_t. Вместо того, чтобы перебирать строку, вы можете отдельно назначить старшую и младшую половину 64-битного целого числа, а затем сложить их вместе. Все еще не очень чисто, но почти наверняка быстрее.

Изменить: см. Ответ Banthar для гораздо лучшего обходного пути.

person Stephen Canon    schedule 06.07.2011

После запуска некоторых тестов на MPIR 3 выясняется, что mpz_import по какой-то причине работает медленнее на 64-битных значениях, подход ниже уродливее, но ведет себя лучше IME (привет - выше 32 бита, а lo - меньше 32 бита UInt64).

 mpz_set_ui(dest, hi);
 mpz_mul_2exp(dest, dest, 32);
 mpz_add_ui(dest, lo);

Если часть hi имеет значение null, вы, конечно, можете использовать ярлык, возможно, стоит провести тест.

Если это отрицательный Int64 (со знаком), получите Abs, сделайте то, что описано выше, а затем инвертируйте поле mp_size.

person Eric Grange    schedule 18.08.2020

MPIR 2.4 представил поддержку intmax_t и uintmax_t. См. Mpz_set_ux () / sx () и mpz_get_ux () / sx (). Этих функций нет в GMP, но они описаны в руководстве по MPIR 2.4.0.

person casevh    schedule 08.07.2011