Problem with large values in GMP...

wraithx at morpheus.net wraithx at morpheus.net
Sun Mar 20 15:06:21 UTC 2016


On 3/19/2016 7:50 PM, sisyphus1 at ... wrote:
> I couldn't locate the original script that the OP used. Are we sure it specified:
>
> printf("num bits in num3 = %llu\n", mpz_sizeinbase(num3, 2));
> and not
> printf("num bits in num3 = %u\n", mpz_sizeinbase(num3, 2));
>
> (The latter version will report "30").

I must apologize, I did unfortunately use %u to print out the mpz_sizeinbase.
The code I was working on that led me to this incorrect print statement did have
a problem on Win64 systems.  It used:
unsigned long i = 0;
for (i = mpz_sizeinbase(n, 2); i > 0; i--) {...}
This "for" loop was behaving like n had only 30 bits.  I have switched i to use
a larger type and it is behaving as expected.


Thank you all very much for helping me track down that error.  Now I've been
testing Rob's code and am wondering why we can create a number with
slightly more than 2^32 bits, but above a certain point I get an error of:
GNU MP: Cannot allocate memory (size=4294909984)

For example, if we use these exponents:
mpz_mul_2exp(num2, num2, 4006516961)
mpz_mul_2exp(num2, num2, 500814592)
The program will calculate mpz_mul(num3, num1, num2) with no problem.  And the 
result will have:
num bits in num3 = 4507331553

However, with the following exponents:
mpz_mul_2exp(num2, num2, 4006516961)
mpz_mul_2exp(num2, num2, 500814593)
The program will crash during mpz_mul(num3, num1, num2) saying:
GNU MP: Cannot allocate memory (size=4294909984)

Is this due to internal variable sizes in GMP, or perhaps just an issue with my 
own computer?  I have 12GB of ram, so it isn't an available memory issue.  Rob, 
would you mind testing out these exponents on your Win64 system and see if you 
get the same results?


Something else I'd like to report.  While trying to come up with a test case for 
my original "problem", I stumbled onto what appears to be another problem.  When 
I ran a particular mpz_ui_pow_ui it would succeed with GMP 6.0.0 and 6.1.0, but 
there was a memory leak with GMP 5.1.2 and 5.1.3. (These are the only 4 versions 
I tested)

For example with GMP 6.0.0 and 6.1.0, it would take 1m20s to calculate the 
value, and only use ~1600MB.  With 5.1.2 and 5.1.3, after 9m50s it had already 
used ~6470MB, and at that point I killed the program.  Here is the program that 
I tested with:

/**********************************/
#include <stdio.h>
#include <gmp.h>

int main (int argc, char* argv[])
{
   mpz_t num1;
   unsigned int base = 4097, exp = 347903438;

   mpz_init (num1);

   printf ("GMP version = %s\n", gmp_version);
   printf ("Calculating num1 = %u^%u\n", base, exp);
   mpz_ui_pow_ui (num1, base, exp);
   printf ("Num bits in num1 = %llu\n", mpz_sizeinbase (num1, 2));

   mpz_clear (num1);

   return 0;
}

/**********************************/

-David C.

>
> Below my sig is the actual program I ran.
>
> Cheers,
> Rob
>
> /**********************************/
> #include <stdio.h>
> #include <gmp.h>
>
> int main(void) {
> mpz_t num1, num2, num3;
>
> mpz_init(num3);
> mpz_init_set_ui(num1, 1);
> mpz_init_set_ui(num2, 1);
>
> mpz_mul_2exp(num1, num1, 4006516961);
> mpz_mul_2exp(num2, num2, 288450365);
>
> mpz_sub_ui(num1, num1, 1);
> mpz_sub_ui(num2, num2, 1);
> mpz_mul(num3, num1, num2);
>
> printf("mpz_mul(num3, num1, num2)\n");
> printf("num bits in num1 = %llu\n", mpz_sizeinbase(num1, 2));
> printf("num bits in num2 =  %llu\n", mpz_sizeinbase(num2, 2));
> printf("num bits in num3 = %llu\n", mpz_sizeinbase(num3, 2));
>
> return 0;
> }
>
> /**********************************/
>
>


More information about the gmp-discuss mailing list