Boost logo

Boost :

Subject: Re: [boost] Numeric constants
From: Joel Falcou (joel.falcou_at_[hidden])
Date: 2009-01-30 14:28:55


Phil Endecott a écrit :
> John Maddock wrote:
>> template <class T> T pi();
>
> I have a fixed-point class. What actually happens when I call
> pi<fixed>() ? Presumably the implementation just does "return
> 3.1415...", so fixed::fixed(double) gets called. Yes my fixed class
> has a constructor that takes a double, and if I'm really lucky it may
> do the conversion at compile time - but more likely it will happen at
> run time. I would get the same code if you just declared "const
> double pi = 3.1415" (or #defined it).
>
> My 64-bit fixed point type can store more digits of PI than a 64-bit
> floating point value. But I'm not aware of any way of filling those
> extra digits [ignoring the existence of long double]. Similarly if I
> had an arbitrary precision (i.e. variable length) type, how would it
> be constructed from the 100-digit constants that you mention without
> support from the language (or maybe macros)?
>
> (As for the actual constants, the only ones I find myself using are pi
> and the approximate radius of the earth.)

Sorry if i soem up with a bad or already proposed solution. I had to
handle such named constant in soem code with the same ste of constraints
(usability and casting to user-defined type). What I did was to have
class of constants that are build based on a constant ID and expose a
tempalte operator T:

template<class ID> class constant
{
   template<class T> operator T() const
   {
      return cast<T>(ID::Value());
   }

  // proper unary operator and so on
};

ID class are the one containing the actual consatnt value and a "default
type" :

class pi_id
{
    typedef long double type;

    static inline Value() { return 3.1415........; }
};

The T() operator call a cast function which is in fact a polymorphic
function object that uses tag dispatching to either just perform a cast
or to call a user-defined casting operation. Those user defined operator
can be overloaded on the constant id if needed (for example if you have
special algorithm to compute pi with fixed representation but use a cast
for other constant). Those constant are then statically defined as POD
constant :

constant<pi_id> pi_ = {};

How to use those constant ? It rather simple. Things like
double k = pi_;
int u = ten_;
works as intended by auto-casting the valeu to the destination type.

You can force a constant to be of a given type : abs( float(log2_) );
Alternatively, the basic operator (+,-,*,/,unary -, ~, ! and comparison)
are overlaod to autocast the constant into a proper type when used like :

double k,v;
k = v + pi_;
bool test = x > log10_;

A set of result_of enabled traits also allows to computes the correct
type of a constant when used in a complex expression.
Most constant type-cast is performed at compile-time, unless if you use
a user-defined type-casting overload.

I am overthinking it or could this be viable ?

-- 
___________________________________________
Joel Falcou - Assistant Professor
PARALL Team - LRI - Universite Paris Sud XI
Tel : (+33)1 69 15 66 35

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk