|
|
Math ConstantsRationale |
Mathematical constants (like Archimedes' pi) are exceedingly unlikely to change, whereas estimates of physical ‘constants‘ (like Planck's h) are certain to vary. Physical constants usually have a known uncertainty, usually greater than even the accuracy of float representations, whereas mathematical constants can be calculated to an arbitrarily high precision. So it would be confusing to store mathematical and physical constants in the same header file.
Discussion about naming convention made very clear that it is not
possible to please everyone! Worse still, there seems to be an
irreconcilable conflict between name-first and factor-first conventions
when names of upper and lower limits of intervals are required.
Allowing aliases has some disadvantages.
Some urgent desires to use an alternative name can be met using macros to 'rename', or using the C-style macros #define values, for example:
const double My_Very_Own_Name_for_pi = BOOST_PI;
Naming demands compromises - for this version I have chosen the upper and lower without underscores_ h, for example, oneDivTwoPi.
In general, a C++ Standard Library style is used, favouring longer and easier to read names over ease of typing, and all lower case and underscore _ as separator. Of course, names cannot start with a digit, so words, like two and half, are used instead. C99 names are used where appropriate, but names are not in all capitals as used for constants in many C programs. The rationale is that these names are variable names and not macro or #define names for which ALL CAPITALS are conventionally retained in C++ programs. Some examples, and the rationale for them, should make this clearer than an attempt to write a formal specification.
A major difficulty is the desire to put the name first and follow by type. For example:
pi_div_2 versus half_pi
And yet there was very strong preference for two_pi rather than pi_twice or pi_times_2.
pi // Prefer lower case only - use uppercase only for class names.
loge_pi // much clearer than logepi
sqrt_2 // shorter than sqrt_two
log_2 // clearer with separating _ than log2, despite more typing.
but Boost favours clarity over curtness.
// and reserve log2 for log to base 2, log10 for log to base 10.
// sqrt is commonly used and shorter than square_root_2.
cbrt_2 // ugly, but is C99 name.
ten // can’t be 10 so use the word ten instead.
third // shorter than one_div_three.
one_div_sqrt_2 // one_div rather than reciprocal – short but clear.
// _div clearer than _on or _upon or _over.
half_pi // rather than pi_div_2.
pi_sqr // pi_squared is rather long.
two_pow_three_halves // two_pow_three_div_two is ambiguous.
minus_loge_loge_2 // can't start with - so use word.
There are always problems with more complex constants where brackets would be used
two_pow_three_halves // two_pow_three_div_two is ambiguous.
Explicit typed names can only sensibly follow the C99 convention:
pi_f // float
pi_d // double
pi_l // long double
pi_i // integer???
pi // nearest to pi (usually either upper and/or lower interval limit)
pi_l // pi interval lower limit
pi_u // pi interval upper limit
and where both floating-point type AND upper or lower limit are fixed:
pi_f_l // pi float lower limit
pi_l_l // pi long double lower limit
pi_l_u // pi long double upper limit
I have indicated some rationale for including each one,
drawing on the 'authority' of 3 texts, and Boost discussions:
1 Donald E Knuth, Art of Computer Programming,
2 John Hart, Computer Approximations, and
3 Stephen Moshier, Math Functions, Cephes math function library.
4 Morris, ACM 715 & Brown CDFlib collection of math functions used
in statistics.
as a guide to what has been used in typical math work, in particular
those constants that would be required for a math function library..
All the builtin sqrt, log, trig and pow functions are especially liable
to be inaccurate, (and seriously inaccurate at times)
and all lead to run-time code which is extremely unlikely to be
optimised. I indicate this by saying, for example, 'avoid log()'.
1 Basic math_constants.hpp
| name | alternative name(s) | Use | Comments | Notes |
| e | Euler | |||
| pi | Archimedes | |||
| log_pi | pi_log | avoid log() | ||
| log_sqrt_two_pi | pi_twice_sqrt_log | log( sqrt( two_pi ) ) | avoid log() and sqrt | |
| sqrt_2 | two_sqrt | sqrt_2 is shorter and more obvious | ||
| sqrt_3 | avoid sqrt | |||
| sqrt_5 | avoid psqrt | |||
| sqrt_10 | avoid sqrt | |||
| cbrt_2 | avoid pow | |||
| cbrt_3 | cube_root_3 | avoid pow (but follow cbrt C99 naming convention, even if ugly!) | ||
| fourth_root_2 | long but not common. avoid pow() | |||
| log_2 | loge(2) or ln(2) | avoid log() | ||
| log_3 | loge(3) | avoid log() | ||
| log_4 | loge(4) | avoid log() | ||
| log_5 | loge(5) | avoid log() | ||
| log_10 | loge(10) | avoid log() | ||
| log10_2 | two_log10 | logbase10 of 2 | accuracy | |
| log10_e | e_log10 | logbase10 of e | accuracy | |
| log_two_pi | ||||
| log_e | ||||
| log_pi | ||||
| one_div_log_2 | reciprocal_log_2 | reciprocal is too long? | ||
| one_div_log_10 | ||||
| one_div_pi | accuracy | |||
| sqrt_pi | pi_sqrt | == gamma_half | Need an alias system? | |
| sqrt_1_div_pi | sqrt(1_div_pi) | ambigous | ||
| log_sqrt_two_pi | ||||
| phi | golden_ratio | golden_ratio is too long | Phideas | |
| euler | gamma | name gamma is likely to be used for other purposes. | Euler |
2 Additional
Again note that some of these may be calculated accurately by some
compilers, but are good for clear programs, and avoid any run-time code
for debug and/or less-optimised code.
| name | alternative name(s) | Use | Comments | Notes |
| pi_div_2 | half_pi | Put name pi first. Convenient even if can be calculated accurately. | ||
| pi_div_4 | quarter_pi | Convenient even if can be calculated accurately. | ||
| pi_div_3 | third_pi | |||
| pi_div_6 | sixth_pi | |||
| pi_div_3_twice | two_thirds_pi | two_thirds_pi is MUCH nicer? | ||
| pi_div_3_times_4 | four_thirds_pi | four_thirds_pi is mUCH nicer? | ||
| pi_div_4_times_3 | three_quarters_pi or three_pi_div_4 | Consistency lacks clearness. | ||
| one_div_pi | ||||
| pi_squared | ||||
| two_pi_squared | ||||
| one_div_pi_squared | ||||
| sqrt_pi_div_2 | sqrt_half_pi | |||
| one_div_sqrt_pi | ||||
| sqrt_quarter_pi | ||||
| sqrt_two_div_pi | ||||
| cbrt_pi | ||||
| one_div_cbrt_pi | ||||
| sqrt_2_div_2 | half_sqrt_2 | Convenient even if can be calculated accurately. | ||
| one_div_sqrt_2 | ||||
| one_div_sqrt_two_pi | ||||
| two_pow_two_thirds | 2^(2/3) | |||
| log_2_div_2 | ||||
| e_squared | ||||
| one_div_e | ||||
| one_div_e_sqr | ||||
| two_pow_2_div_3 | ||||
| log_log_2 | ||||
| euler |
A handful of real constants:
| one | floating point 1. NOT integer 1 useful |
| two | completeness? |
| three | completeness? |
| four | completeness? |
| ten | completeness? |
| half | accuracy on any base 10 systems |
| third | accuracy? |
| two_thirds | accuracy? |
| quarter |
3 (More) Obscure
| cbrt_10 sqrt_5 sqrt_32 sin_0 cos_0 tan_0 sin_1 cos_1 tan_1 sin_half cos_half tan_half log_euler one_div_euler one_div_log_euler gamma_third gamma_two_thirds gamma_sixth gamma_min gamma_min e_pow_euler e_pow_quarter_pi e_pow_pi pi_pow_e zeta_three exp(-2) exp(-32) ??? More ??? |
http://www.hetp.u-net.com/public/mathconstants/rational.html, Revised 5 May 2005
© Copyright
Paul
A Bristow
2002-2005. All Rights Reserved.