
Boost : 
Subject: [boost] [mp_int] Possible bug in comparison with native types causes overflow_error
From: Nathan Kitchen (nathan.kitchen_at_[hidden])
Date: 20090109 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