Boost logo

Boost :

From: Andy Little (andy_at_[hidden])
Date: 2004-01-23 05:36:40


"Paul A. Bristow" <boost_at_[hidden]> wrote

> Some rather accurate constants that I proposed some years ago are
> attached.

Downloaded... thanks :-)

> The Politically Correct C++ers felt that there was no place for C macros
> in a Boost C++ library,

consider :

#define PI 3.14XXXXXXXXXXXXXXL
float fval= PI;
// compiler warns on conversion from
// long double to float.

//ok try
#define PI 3.14XXXXXXXXXXF
long double ldval = PI;
// No reason to use a long double here...
// only get float accuracy.

> but we have still not found a portable way of presenting these values
> in true C++ form allowing pi (etc) to be written as pi rather than
> pi().

No...Meanwhile... I am happy with this, which allows me to test (no
warnings) different pq_default_value_type's by changing the typedef in my
defaults.hpp file, also useful for templates of course, note Not boost::math
:-) :

//defaults header...

typedef int pq_default_value_type; // set q_ series to have int value_type

// source...

// maybe should be boost::types_promotion_traits
  typedef math_promote<pq_default_value_type,float>::type min_float;

//min_float for power<3> !
  pq_length<min_float>::km const planet_radius(6400);

 // int ok
  q_density::kg_div_m3 const planet_density(5464);

  pq_mass<min_float>::kg planet_mass = (4.0F/3.0F)
    * math::constants<min_float>::pi * power<3>(planet_radius)
    * planet_density;

BTW The header shown in my previous post is better as:

//my_math_constants.hpp
namespace math{

    template<typename Value_type>
    struct constants{
        static Value_type const & pi;
        static Value_type const & e;
        static Value_type const & sqrt2;
    /* other constants */
   };

 }//math

Only the constants used need to be defined, therefore constants struct above
could include all the constants, with *no* redundant memory used:

//custom_math_constants.cpp
 #include "my_math_constants.hpp"
    // static members
    template<>
    long double const & math::constants<long double>::pi
    = 3.141592653589793238462643383279502884197L;

  /* etc */

//dont need these
   /* template<>
    long double const & math::constants<long double>::e
    = 0.5772156649015328606065120900824024310422L;
....
*/

> There was widespread agreement that no solution requiring pi()
> would be widely acceptable.

but again..bottom line... works ok in most situations:

    template <typename Value_type>
    const Value_type& pi();

    template<>
    inline const double& pi<double>()
    { static const double v
        = 3.141592653589793238462643383279502884197;
        return v;
    }
/* etc */
gives:

 pq_mass<min_float>::kg planet_mass = (4.0/3)
    * math::pi<min_float>() //template arg required
    * power<3>(planet_radius) * planet_density;

I would guess that the non-function version would be marginally faster,
based on previous static function constants, which require a check of init
of the constant (only tested in non-opt VC7.1) but function version requires
no extra object file included. Not sure if all specialised functions static
constants instantiated or not though. non-function version is more legible
IMO.

Whatever... that is the functionality I would like. So whatever you come up
with needs:

3) always works ...no odd habits.. (e.g deduced args in functions, UDTs)
1) templateability
2) speed
4) small memory footprint.
5) legibility, personally prefer math::pi, math::constants::pi etc to 'pi'

> PS To Daniel Frey - typeof is fine by me - provided versions can be
> provided for all the recent main compilers. (For the obselete
> compilers we could just provide the C Macro values).

Does VC7.1 do typeof ?
Is typeof standard C++?

regards
Andy Little


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