mpz_t to unsigned long long conversion (gmp lib)

前端 未结 2 2062
小鲜肉
小鲜肉 2020-12-11 17:42

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

相关标签:
2条回答
  • 2020-12-11 18:30

    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);
    }
    
    0 讨论(0)
  • 2020-12-11 18:38

    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.

    0 讨论(0)
提交回复
热议问题