Boost logo

Boost :

Subject: [boost] [mp_int] Possible bug in comparison with native types causes overflow_error
From: Nathan Kitchen (nathan.kitchen_at_[hidden])
Date: 2009-01-09 20:04:27


I'm getting some strange crashes when I try to compare mp_ints with
native types. The code below is sufficient to reproduce it:

#include <stdint.h>
#include <iostream>
#include <boost/mp_math/mp_int.hpp>

using namespace boost::mp_math;
using namespace std;

int main()
{
  mp_int<> a = mp_int<>("0x100000000");
  cout << (1 < a) << endl;

  return 0;
}

The problem appears to be the definition of integral_ops_impl<...,
true>::q (i.e., for signed IntegralT):

  static const typename MpInt::size_type q =
    std::numeric_limits<IntegralT>::digits + (MpInt::valid_bits - 1)
    / MpInt::valid_bits;

In the case where IntegralT=int32_t and digit_type=uint32_t, q is 31.
Contrast this with the definition for unsigned IntegralT:

  static const typename MpInt::size_type q =
    std::numeric_limits<IntegralT>::digits / (MpInt::valid_bits + 1) + 1;

When IntegralT=uint32_t and digit_type=uint32_t, q is 1.

The overflow of operator< comes because the check that verifies that
the MpInt can't fit in an IntegralT is (condition (lhs.size() > q).
This fails for q=31. If the definition of q had the first line
parenthesized:

  static const typename MpInt::size_type q =
    (std::numeric_limits<IntegralT>::digits + MpInt::valid_bits - 1)
    / MpInt::valid_bits;

then q would be 1, and the code branch with the overflow would not be taken.

-- Nathan


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk