|
Boost Users : |
Subject: [Boost-users] [numeric conversation] behavior on std::numeric_limits<double>::max() + eps with numeric_cast
From: Olaf Peter (ope-devel_at_[hidden])
Date: 2014-06-09 02:53:32
Hello,
at this time I play with numeric_cast and struggle with this:
first:
double z = std::numeric_limits<double>::max();
z += 2*std::numeric_limits<double>::epsilon(); // doesn't
matter if 1*eps
std::cout << z << std::endl;
std::cout << boost::numeric_cast<double>(z) << '\n';
I would expect that an exception is thrown which isn't, the output is
1.79769e+308
1.79769e+308
and as second: If I write my onw UDT as shown in the tutorial like:
namespace my {
enum range_check_result
{
cNonFinite = 0,
cInRange = 1,
cNegOverflow = 2,
cPosOverflow = 3
} ;
//! Define a custom range checker
template<typename Traits, typename OverFlowHandler>
struct range_checker
{
typedef typename Traits::argument_type argument_type;
typedef typename Traits::source_type S;
typedef typename Traits::target_type T;
//! Check range of integral types.
static range_check_result out_of_range(argument_type value)
{
if(!std::isfinite(value.to_builtin())) // Neither infinity
nor NaN.
return cNonFinite;
else if(value > boost::numeric::bounds<T>::highest())
return cPosOverflow;
else if(value < boost::numeric::bounds<T>::lowest())
return cNegOverflow;
else
return cInRange;
}
static void validate_range(argument_type value)
{
BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_bounded);
OverFlowHandler()(out_of_range(value));
}
};
....
struct bad_numeric_cast : virtual boost::exception, virtual
std::bad_cast
{ ... };
struct rounding_error : virtual boost::exception, std::domain_error
{
rounding_error() : std::domain_error("NaN or Infinity") {} //
XXX Better solution?
virtual const char * what() const throw() {
return "bad numeric conversion: can not be represented in
the target integer type";
}
};
struct negative_overflow : virtual bad_numeric_cast
{ .... };
struct positive_overflow : virtual bad_numeric_cast
{ .... };
struct overflow_handler
{
void operator()(range_check_result result)
{
if(result == cNonFinite)
BOOST_THROW_EXCEPTION(rounding_error());
else if(result == cNegOverflow)
BOOST_THROW_EXCEPTION(negative_overflow());
else if(result == cPosOverflow)
BOOST_THROW_EXCEPTION(positive_overflow());
}
};
it doesn't change the result - is this the right way?
Thanks,
Olaf
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net