|
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