Is there a way to convert a mpz_t variable to unsigned long long in C?How about the other way around,from ull to mpz_t?The gmp library doesn't support this as ull are part of C99. I found this but it's in c++,and I don't know how to code in c++.Thanks in advance.
Asked
Active
Viewed 5,132 times
7
-
I am surprised there wasn't any mention of mpz_import / mpz_export. – Marc Glisse Jan 31 '13 at 18:20
-
@MarcGlisse To be fair, I'm not a gmp expert, I was simply trying to do a straightforward translation of the linked C++ code to C. – C. K. Young Aug 25 '13 at 02:31
2 Answers
8
Here are some functions for translating between unsigned long long
and mpz_t
. Note that mpz2ull
will smash your stack if the number is too big to fit into an unsigned long long
:
unsigned long long mpz2ull(mpz_t z)
{
unsigned long long result = 0;
mpz_export(&result, 0, -1, sizeof result, 0, 0, z);
return result;
}
void ull2mpz(mpz_t z, unsigned long long ull)
{
mpz_import(z, 1, -1, sizeof ull, 0, 0, &ull);
}

C. K. Young
- 219,335
- 46
- 382
- 435
-
Very nice...thanks.I'm not familiar with strtoull,why is its' second argument set to 0? – kaiseroskilo Jun 06 '11 at 07:36
-
@kaiseroskilo: The second argument takes an "end pointer", which (if one is given) is set to the end of the number parsing. That way, you can do error checking: if the end is at the null-terminator, the whole string is a valid number. By passing null (written as 0 in my code here), that's saying that I don't care about the end pointer, because I have blind faith that `gmp_snprintf` will always give valid output. ;-) – C. K. Young Jun 06 '11 at 07:41
-
Thanks. Getting a segfault on the second function, probably just needs mpz_init(result) after mpz_t result; – DannyKK Jan 29 '12 at 23:54
-
As pointed out in http://stackoverflow.com/questions/18416425/converting-an-ull-to-an-mpz-t there are several issues with this code. The snprintf calls are missing an argument (n and ull are unused). You can't return an mpz_t. – Marc Glisse Aug 24 '13 at 21:04
-
-
@MarcGlisse I've reimplemented these functions using `mpz_export` and `mpz_import`, as you've mentioned. (I've even tested them this time!) Note: `mpz2ull` will smash your stack if the number is too big to fit. This is a feature (albeit one with undefined behaviour, in order to keep the code simple), not a bug. ;-) – C. K. Young Aug 25 '13 at 03:49
4
These functions should work to convert between mpz_t and signed/unsigned long long. They should be reasonably fast since they avoid having to do string processing:
void mpz_set_sll(mpz_t n, long long sll)
{
mpz_set_si(n, (int)(sll >> 32)); /* n = (int)sll >> 32 */
mpz_mul_2exp(n, n, 32 ); /* n <<= 32 */
mpz_add_ui(n, n, (unsigned int)sll); /* n += (unsigned int)sll */
}
void mpz_set_ull(mpz_t n, unsigned long long ull)
{
mpz_set_ui(n, (unsigned int)(ull >> 32)); /* n = (unsigned int)(ull >> 32) */
mpz_mul_2exp(n, n, 32); /* n <<= 32 */
mpz_add_ui(n, n, (unsigned int)ull); /* n += (unsigned int)ull */
}
unsigned long long mpz_get_ull(mpz_t n)
{
unsigned int lo, hi;
mpz_t tmp;
mpz_init( tmp );
mpz_mod_2exp( tmp, n, 64 ); /* tmp = (lower 64 bits of n) */
lo = mpz_get_ui( tmp ); /* lo = tmp & 0xffffffff */
mpz_div_2exp( tmp, tmp, 32 ); /* tmp >>= 32 */
hi = mpz_get_ui( tmp ); /* hi = tmp & 0xffffffff */
mpz_clear( tmp );
return (((unsigned long long)hi) << 32) + lo;
}
long long mpz_get_sll(mpz_t n)
{
return (long long)mpz_get_ull(n); /* just use unsigned version */
}
The function signatures are supposed to look like native GMP functions.
As with other gmpz_set_
functions, these assume the variables passed have been initialised already, but it is easy to change them into gmp_init_set_
style functions.

mwfearnley
- 3,303
- 2
- 34
- 35