Convert uint64 to GMP/MPIR number
Asked Answered
D

5

5

I am using MPIR 2.4.0 on Windows (MSVC 2010) and I was trying to add an unsigned 64bit integer to a mpz_t number. However it seems that MPIR/GMP does not support direct conversion between 64bit Integers and mpz_t. Does this mean I have to convert my uint64 to a string and read this via mpz_init_set_str? Neither is this very appealing nor does it look very quick - two conversion for nothing.

Did I miss something or what is the trick/hack to use here?

Cheers,

Philipp

Deaconess answered 6/7, 2011 at 14:41 Comment(0)
T
7

As suggested by Banthar use mpz_import, but I'd suggest the following which does not rely on the platform endianness:

mpz_import(b, 1, 1, sizeof(a), 0, 0, &a);
Tuberculous answered 6/7, 2011 at 20:58 Comment(2)
Thanks, as Stephen Canon already said: I was not aware of this function, very useful :) But I still think that it is odd for a library of this size not to consider int64 :/Deaconess
Actually using mpz_import appears to be slower than setting lhigher 32bits, mul_2exp to offset by 32bits, then add low 32bits, and if the number is negative, negate mp_sizeArmindaarming
A
4

Use mpz_import:

void mpz_set_ull( mpz_t rop, unsigned long long op )
{
   mpz_import(rop, 1, 1, sizeof(op), 0, 0, &op);
}

EDIT: Code updated according to Frank's comment.

Anacardiaceous answered 6/7, 2011 at 20:49 Comment(3)
Ah, very nice. Wasn't aware of this function.Toogood
It looks nicer but you have to deal with endianess. I'm not sure if this code handles it correctly.Anacardiaceous
What about signed long long op?Hamer
T
2

Yes, if you're on a platform (Windows) that doesn't use the LP64 model, then there is no function to assign a 64-bit integer to a mpz_t. Instead of going through a string, you could separately assign the high and low half of the 64-bit integer and then add them together. Still not very clean, but almost certainly faster.

Edit: see Banthar's answer for a much better workaround.

Toogood answered 6/7, 2011 at 20:44 Comment(0)
A
1

After running some tests on MPIR 3, it appears mpz_import is slower for some reason on 64 bit values, the approach below is uglier, but behaves better IME (hi being higher 32bits and lo being lower 32bits of the UInt64)

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

If the hi part is null, you can shortcut of course, it can be worth making the test.

If it is a negative Int64 (signed), then get the Abs, do the above and then negate the mp_size field.

Armindaarming answered 18/8, 2020 at 16:16 Comment(0)
F
0

MPIR 2.4 introduced support for intmax_t and uintmax_t. Please see mpz_set_ux()/sx() and mpz_get_ux()/sx(). These functions don't exist in GMP but are documented in the MPIR 2.4.0 manual.

Fiendish answered 8/7, 2011 at 16:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.