Opened 14 years ago

Closed 14 years ago

Last modified 14 years ago

#2737 closed Bugs (invalid)

Rounding failed for -0.5

Reported by: kennant.tom@… Owned by: Douglas Gregor
Milestone: Boost 1.38.0 Component: numeric
Version: Boost 1.37.0 Severity: Problem
Keywords: Cc:

Description

using namespace boost::numeric; typedef int T; typedef double S; typedef conversion_traits<T, S> Traits; int i = converter<T, S, Traits, def_overflow_handler, RoundEven<Traits::source_type> >::convert(-0.5);

When I run the code above, -0.5 will be converted to 0, but I expect -0.5 to be converted to -1. The same problem goes for 0.5 as well.

Change History (3)

comment:1 by Steven Watanabe, 14 years ago

Resolution: invalid
Status: newclosed

The library's behavior is correct. Round to even returns the nearest integer or if both adjacent integers are equidistant returns the even one.

comment:2 by anonymous, 14 years ago

Sorry. I didn't realize that for rounding, common method and round-to-even method are different. Is there a way to do rounding in common method?

comment:3 by Steven Watanabe, 14 years ago

The common method is not provided. Round to even has better statistical properties. It would look something like this based on RoundEven

template<class S>
struct RoundCommon
{
  typedef S source_type ;

  typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;

  static source_type nearbyint ( argument_type s )
  {
#if !defined(BOOST_NO_STDC_NAMESPACE)
    using std::floor ;
    using std::ceil  ;
#endif

    // only works inside the range not at the boundaries
    S prev = floor(s);
    S next = ceil(s);

    S rt = (s - prev) - (next - s); // remainder type

    S const zero(0.0);
    S const two(2.0);

    if ( rt < zero )
      return prev;
    else if ( rt > zero )
      return next;
    else if ( prev < zero )
      return prev;
    else
      return next;
  }

  typedef mpl::integral_c< std::float_round_style, std::round_to_nearest> round_style ;
} ;
Note: See TracTickets for help on using tickets.