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
_______________________________________________
gmp-devel mailing list
gmp-devel@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-devel

Reply via email to