Opened 17 years ago

Closed 17 years ago

#448 closed Bugs (Invalid)

interval evaluation bug

Reported by: nobody Owned by: Guillaume Melquiond
Milestone: Component: None
Version: None Severity:
Keywords: Cc:

Description

evaluation of sin of [0,1] with interval template 
specification

typedef boost::numeric::interval<
		double, 
		boost::numeric::interval_lib::policies<		
			boost::numeric::interval_lib::
save_state<
				boost::numeric::interval_lib::
rounded_transc_exact<double, 
					boost::numeric::
interval_lib::rounded_arith_opp<double> 
				> 
			>,
			boost::numeric::interval_lib::
checking_strict<double> 
			//boost::numeric::interval_lib::
checking_base<double>
		>
	> Interval;


and rint definition in ms Windows

static double inline rint( double x) 
// Copyright (C) 2001 Tor M. Aamodt, University of 
Toronto 
// Permisssion to use for all purposes commercial and 
otherwise granted. 
// THIS MATERIAL IS PROVIDED "AS IS" WITHOUT 
WARRANTY, OR ANY CONDITION OR 
// OTHER TERM OF ANY KIND INCLUDING, WITHOUT 
LIMITATION, ANY WARRANTY 
// OF MERCHANTABILITY, SATISFACTORY QUALITY, 
OR FITNESS FOR A PARTICULAR 
// PURPOSE. 
{ 
    if( x > 0 ) { 
        __int64 xint = (__int64) (x+0.5); 
        if( xint % 2 ) { 
            // then we might have an even number... 
            double diff = x - (double)xint; 
            if( diff == -0.5 ) 
                return double(xint-1); 
        } 
        return double(xint); 
    } else { 
        __int64 xint = (__int64) (x-0.5); 
        if( xint % 2 ) { 
            // then we might have an even number... 
            double diff = x - (double)xint; 
            if( diff == 0.5 ) 
                return double(xint+1); 
        } 
        return double(xint); 
    } 
}


gives incorrect result:
so sin([0,1]) = [ 0.841471 , -1.60814e-016 ]

Thats looks incredible!!! How can i fix it out?

Change History (2)

comment:1 by Guillaume Melquiond, 17 years ago

Logged In: YES 
user_id=576737

Your rint function does not comply to the C standard; its
behavior confuses the interval library. The interval library
expects this function to "round its argument to an integer
value in floating-point format, using the current rounding
direction" (7.12.9 Nearest integer functions).

You can workaround your deficient standard library by using
the following code (supposing your standard library provides
the floor and ceil functions at least):

struct my_arith_rounding:
  boost::numeric::interval_lib::rounded_arith_opp<double>
{
  double int_down(double f) { return floor(f); }
  double int_up  (double f) { return ceil(f); }
};

typedef boost::numeric::interval<
  double,
  boost::numeric::interval_lib::policies<
    boost::numeric::interval_lib::save_state<
      boost::numeric::interval_lib::rounded_transc_exact<
        double,
        my_arith_rounding > >,
    boost::numeric::interval_lib::checking_strict<double> >
  > Interval;

comment:2 by Guillaume Melquiond, 17 years ago

Status: assignedclosed
Note: See TracTickets for help on using tickets.