C++ factorial error reporting

Marc Glisse marc.glisse at inria.fr
Sat Dec 27 22:36:48 UTC 2014


I am trying to add factorial to the C++ interface, and since GMP only 
provides mpz_fac_ui, I end up having to check and report errors directly. 
Any preferences?

Calling factorial on a negative integer doesn't make sense, we could have 
assert(number >= 0). I am throwing an exception because that seems a 
little friendlier, but I am still choosing one that derives from 

Calling factorial on a number that is a bit too large is a different 
issue. overflow_error is the natural exception when trying to convert an 
mpz_class to an unsigned long if it will not fit. But even if it fits, it 
may still be too big and mpz_fac_ui may fail, in the allocation function, 
which might abort but a natural replacement would throw bad_alloc. I don't 
think it makes that much sense to have a different exception depending on 
who notices that the number is too big, which is why I was also 
considering throwing bad_alloc instead of overflow_error.

We could also pick a single exception and throw it for both negative and 

(you can check the list of standard exceptions at 
http://en.cppreference.com/w/cpp/error/exception , defining our own 
exception type doesn't seem worth the trouble)

struct __gmp_factorial_function
   static void eval(mpz_ptr z, mpz_srcptr w)
     if (mpz_sgn(w) < 0)
       throw std::domain_error ("factorial(negative)");
     // There is no point trying to compute such a huge number.
     if (!mpz_fits_ulong_p(w))
       throw std::overflow_error ("factorial"); // or std::bad_alloc()?
     eval(z, mpz_get_ui(w));
   static void eval(mpz_ptr z, unsigned long int l) { mpz_fac_ui(z, l); }
   static void eval(mpz_ptr z, signed long int l)
     if (l < 0)
       throw std::domain_error ("factorial(negative)");
     eval(z, static_cast<unsigned long>(l));
   static void eval(mpz_ptr z, double d)
   {  __GMPXX_TMPZ_D;    eval (z, temp); }

Marc Glisse

More information about the gmp-devel mailing list