# Boost :

From: Daryle Walker (darylew_at_[hidden])
Date: 2001-03-06 23:06:39

on 3/4/01 8:06 AM, Bill Seymour at bsey_at_[hidden] wrote:

> For my newbie submission to Boost, I have:
>
> template<class T, bool Dp = false>
> struct integer_division_traits
> {
> typedef /* unsigned members iff T is unsigned type */ div_t;
> static div_t div(T dividend, T divisor);
>
> static T gcd(T, T); // greatest common divisor
> static T lcm(T, T); // least common multiple
>
> static T floor(T dividend, T divisor);
> static T ceil (T dividend, T divisor);
> static T trunc(T dividend, T divisor); // toward zero
>
> enum rounding_mode
> {
> nearest_even,
> // other obvious ones
> }
> static T round(T dividend, T divisor,
> rounding_mode = nearest_even);
>
> // other minor stuff
> };

A bunch of these are also in the "more_math.zip" package I uploaded to the
vault a while back. I have them as (template) free functions and classes; I
don't see any need to make them static functions within another class. Some
of these functions look more appropriate as part of "rational.hpp".

//==========================================================================
// more_rational.hpp
#include <rational.hpp>

namespace boost
{
enum rounding_mode
{
nearest, // down if < 1/2, up if >= 1/2
nearest_even, // down if < 1/2, up if > 1/2, to even if == 1/2
// following should be obvious from names
towards_zero,
towards_pos_infinity,
towards_neg_infinity,
leaving_zero
};

template < typename T >
T round( rational<T> const &x, rounding_mode = nearest );

template < typename T >
T floor( rational<T> const &x );
template < typename T >
T ceil( rational<T> const &x );
template < typename T >
T trunc( rational<T> const &x );

//...

template < typename T >
inline T floor( rational<T> const &x )
{ return round( x, towards_neg_infinity ); }

template < typename T >
inline T ceil( rational<T> const &x )
{ return round( x, towards_pos_infinity ); }

template < typename T >
inline T trunc( rational<T> const &x )
{ return round( x, towards_zero ); }

}
//==========================================================================

> The second template argument indicates whether a signed divisor
> is known to be > 0, for example, in a rational number class that
> eagerly keeps its denominator positive. It has no effect iff
> T is an unsigned type.

I don't get what you're trying to say here. Wouldn't the greater-than-zero
property be dependent on what you put in the "divisor" argument, and not as
a template parameter. I don't think the sign would matter much in some of
these algorithms, anyway. If you really needed to know if a type is signed,
your code should inspect, or be specialized on,
std::numeric_limits<T>::is_signed instead of making the user fill in the
```--