C++ factorial error reporting
Marc Glisse
marc.glisse at inria.fr
Sat Dec 27 22:36:48 UTC 2014
Hello,
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
logic_error.
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
too-big.
(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