Boost logo

Boost :

Subject: Re: [boost] [Review Request] Multiprecision Arithmetic Library
From: Andrii Sydorchuk (sydorchuk.andriy_at_[hidden])
Date: 2012-04-03 14:07:34

On Tue, Apr 3, 2012 at 1:13 PM, Neal Becker <ndbecker2_at_[hidden]> wrote:

> Vicente J. Botet Escriba wrote:
> > Le 02/04/12 10:53, John Maddock a écrit :
> >>> I'm wondering if the following compiles and what is the type of c
> >>>
> >>> mp_uint128_t a;
> >>> mp_uint256_t b;
> >>> auto c = a + b;
> >>>
> >>> From the documentation I have the impression that we can not mix
> >>> back-ends.
> >>
> >> Correct, it's a compiler error.
> >>
> >> Allowing mixed type arithmetic opens up a whole can of worms it seems
> >> to me, plus I don't even want to think about how complex the operator
> >> overloads would have to be to support that!
> >>
> >> So for now, if you want to conduct mixed arithmetic, you must
> >> explicitly cast one of the types.
> > Humm, casting seems to be not the good option for fixed point
> > arithmetic. The type of a fixed_point operation depends on the
> > quantization of its arguments.
> >
> > With fixed_point arithmetic the type of fixed_point<7,0> +
> > fixed_point<8,0> is fixed_point<9,0>. Note that no overflow is needed as
> > the resulting type has enough range.
> >
> > Another example
> >
> > fixed_point<10,2> a;
> > fixed_point<2,3> b;
> > fixed_point<2,2> c;
> > auto d = (a + b) * c;
> >
> I have implemented my own fixed_point, and I debated whether the result of
> operations should automatically be a wider type. In the end, I decided it
> was
> best to use explicit casting. Explicit is better than implicit. It's a
> bit
> more verbose, but I can live with that.
> Would you advocate that in C++, int8 * int8 -> int16??

I would say that the result of the expression should not grow
automatically. Consider example of summation of 1000 int32.
The result value would have 1031 bits size, while the actual value it holds
would be at most int42.
There is also another template trick that allows resulting type to be at
least as big as each of the operands:

template <int N, int M>
big_int<(N>M?N:M)> add(const big_int<N>& a, const big_int<M>& b) {
  big_int<(N>M?N:M)> result;
  // Implementation follows.
  return result;
I used this approach for my personal fixed int routines.

The main point of a fixed integer type is its performance. It allows user
to write complex math formulas without thinking about slow memory
I would say that users are responsible to ensure that fixed int doesn't
overflow. If somebody is not satisfied with such behavior they could
use big integer types with dynamic memory allocation.


> Unsubscribe & other changes:

Boost list run by bdawes at, gregod at, cpdaniel at, john at