Opened 6 years ago

Last modified 6 years ago

#12261 new Bugs

LT_HalfPrevLoT and GT_HalfSuccHiT are not symmetrical

Reported by: Christophe Brassart <christophe.brassart@…> Owned by: Fernando Cacciola
Milestone: To Be Determined Component: numeric
Version: Boost 1.61.0 Severity: Problem
Keywords: Cc:

Description

Reusing low boost conversion policies to implement my own roundToInt method...

If you try the following code:

template <class To, class From>
struct NumericRangeCheckerTraits {
	typedef To target_type;
	typedef From source_type;
	typedef From argument_type;
};

struct ToTextOverflowHandlerPolicy {
	void operator() ( boost::numeric::range_check_result result) {
		switch (result) {
		case boost::numeric::cInRange:
			std::cout << "the value is in range"<< std::endl;
			break;
		case boost::numeric::cNegOverflow:
		case boost::numeric::cPosOverflow:
			std::cout << "the value is out of range"<< std::endl;
			break;
		}
	}; 
};

double dmax = std::numeric_limits<int>::max() + 0.5;
double dmin = std::numeric_limits<int>::min() - 0.5;

boost::numeric::convdetail::generic_range_checker<NumericRangeCheckerTraits<int, double>,
	boost::numeric::convdetail::LT_HalfPrevLoT<NumericRangeCheckerTraits<int, double>>,
	boost::numeric::convdetail::GT_HalfSuccHiT<NumericRangeCheckerTraits<int, double>>,
	ToTextOverflowHandlerPolicy>::validate_range(dmax);

boost::numeric::convdetail::generic_range_checker<NumericRangeCheckerTraits<int, double>,
	boost::numeric::convdetail::LT_HalfPrevLoT<NumericRangeCheckerTraits<int, double>>,
	boost::numeric::convdetail::GT_HalfSuccHiT<NumericRangeCheckerTraits<int, double>>,
	ToTextOverflowHandlerPolicy>::validate_range(dmin);

You will get:

the value is out of range
the value is in range

When they should be both out of range.

This is because GT_HalfSuccHiT should implement range_check_result as such:

static range_check_result apply ( argument_type s ) {
  return s > static_cast<S>(bounds<T>::highest()) + static_cast<S>(0.5)
           ? cPosOverflow : cInRange ;

instead of using >=.

The comment to describe GT_HalfSuccHiT should be changed as well to:

// s > Highest(T) + 0.5 ? cPosgOverflow : cInRange

Change History (3)

comment:1 by viboes, 6 years ago

Owner: changed from viboes to Vladimir Batov

comment:2 by Vladimir Batov, 6 years ago

Component: convertnumeric
Owner: changed from Vladimir Batov to Fernando Cacciola

I do not believe that is a Boost.Convert issue. I am under impression that it is Boost.NumericConversion by Fernando.

comment:3 by anonymous, 6 years ago

This is indeed an issue on Boost.NumericConversion and I'll try to take a detailed look next week.

Note: See TracTickets for help on using tickets.