1

I am using boost::multiprecision::cpp_int, and I cannot find confirmation that division of two positive cpp_int's truncates towards 0; i.e., that

boost::multiprecision::cpp_int A {11};
boost::multiprecision::cpp_int B {4};

boost::multiprecision::cpp_int C = A / B; // 2, right?

In C++, were A and B builtin integer types, the standard requires truncation towards 0, so that the answer would be C equals 2.

I assume that cpp_int works the same way - that the answer is 2 for cpp_int, also.

However, I cannot find confirmation of this assumption. I have also looked for a few minutes in the source code for boost::multiprecision::cpp_int, but I did not find it trivial to confirm the behavior.

I would like to confirm that boost::multiprecision::cpp_int works as expected when dividing two positive integers - namely, that it truncates the result towards 0.

Thanks!

Dan Nissenbaum
  • 13,558
  • 21
  • 105
  • 181

2 Answers2

2

The main options for integer division or modulo operators is rounding towards zero or rounding towards negative infinity. Although rounding towards negative infinity is mathematically more correct, C / C++ round towards zero. This affects division or modulo when the dividend and divisor have differing signs. Rounding towards zero means that the result of modulo has the same sign as the dividend (or zero), and rounding towards negative infinity means the result of modulo has the same sign as the divisor (or zero).

rcgldr
  • 27,407
  • 3
  • 36
  • 61
1

There is no truncation involved.

Truncation assumes that there is an intermediate, non-integral, result. This is not the case. The only division operations defined for cpp_int (or any other multiprecision integer) involve integer division:

  • divide_qr - Sets q = x / y and r = x % y.

    template <class Backend, expression_template_option ExpressionTemplates>
        void divide_qr(const number-or-expression-template-type& x, const number-or-expression-template-type& y,
        number<Backend, ExpressionTemplates>& q, number<Backend, ExpressionTemplates>& r);
    
  • integer_modulus - Returns x % val;

    template <class Integer>
    Integer integer_modulus(const number-or-expression-template-type& x, Integer val);
    

Apart from integer division being this well-defined concept, and appearing throughout all mainstream programming languages, it wouldn't make any sense to have it otherwise, because (at least for positive integers*¹*)

x == (q*y) + r

should be true


¹ IIRC mixed-sign modulo is undefined for C++; I wouldn't expect guarantees here unless you can find them in the code/documentation

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Mixed-sign modulo is no different from same-sign modulo in C++. The only thing which leads to undefined behavior according to C++11 Standard is zero divisor (see 5.6/4). In practice, `-1%INT_MIN` also traps (at least on x86), which is accounted/clarified for by the Standard since C++14 by the requirement that `a/b` is representable in the type of the result. – Ruslan Mar 16 '18 at 14:19
  • That's improved over time yes – sehe Mar 16 '18 at 15:02