Search code examples
c++integer64-bitassign

GMP - Store 64 bit interger in mpz_t/mpz_class and get 64 bit integers back


I want to assign the values from 64 bit integers into mpz_class/mpz_t variables and later get 64 bit integers back. However GMP only provides this functionality for 32 bit and lower integers.

So how would I turn an 64 bit integer into a mpz_class/mpz_t variable and vice versa. (I need it for both signed and unsigned integers)


Solution

  • This could be achieved with mpz_import() and mpz_export() functions.
    Code sample (tested on LP64 data model):

    using Type = int64_t;
    
    // We start with some 64bit integer
    const Type builtIn64 = std::numeric_limits<Type>::min();
    std::cout << builtIn64 << '\n';
    
    // Import the integer into the mpz_class
    mpz_t mpzNum;
    mpz_init(mpzNum);
    mpz_import(mpzNum, 1, 1, sizeof(Type), 0, 0, &builtIn64);
    if (builtIn64 < 0) {
        mpz_neg(mpzNum, mpzNum);
    }
    std::cout << mpz_class(mpzNum) << '\n';
    
    // Export the mpz_t value to a buffer allocated by the function and given
    // the word size, get also the number of words required to hold the value
    const size_t wordSize = sizeof(Type);
    size_t wordCount = 0;
    void* outRaw = mpz_export(nullptr, &wordCount, 1, wordSize, 0, 0, mpzNum);
    
    // Make sure that our integer type can still hold the value
    if (wordCount == 1) {
        const Type out = *static_cast<Type*>(outRaw);
        std::cout << out << '\n';
    }
    
    // Free the allocated memory by mpz_export
    void (*freeFunction)(void*, size_t);
    mp_get_memory_functions(nullptr, nullptr, &freeFunction);
    freeFunction(outRaw, wordCount * wordSize);
    
    // Don't forget to free the allocated memory
    mpz_clear(mpzNum);
    

    LIVE DEMO