Math constants - updated.

I have recently posted to the Boost Sandbox vault an update of my collection of mathematical constants, previously reviewed as a Boost library and ultimately not accepted because of lack of agreement on how to present the constants, especially for User Defined Types, and an outbreak of macrophobia. However the values are still valid and some may find them a useful and convenient source, with even more reassuringly sufficient decimal places to give you a warm feeling ;-) The values are take from Internet sources and then computed with NTL a arbitrary (very high) precision library and presented as 40 decimal digit strings, suitable for all hardware as yet envisioned. I have tried to check as many as possible against two source to try to avoid mistakes, but please tell me of any that you find. The same values are actually presented in header files as macros, floats, doubles, and long doubles, (and also as the functions allowing pi to call a function pi() proposed by Michael Kenniston, even though I am not entirely convinced of their usefulness). So including double_constants.hpp will give lots of values, for example: static const double cubeRootTwo = 1.25992104989487316476721060727822835057; // 2^1/3 If you prefer a macro, the define_constants.h will give you values like #define M_EPOWPI 23.14069263277926900572908636794854738027L /* e^pi */ You can of course also cut and paste invididual lines, if you just want pi. No choice of names will suit everyone - so I have indulged myself. You can change them of course. http://tinyurl.com/7p6es for two zips of headers and documentation as html. Enjoy? Paul PS Some of these values are to be used in the math functions for stats library that I am in danger of getting around to Real Soon Now. Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com

Hi, On Fri, May 06, 2005 at 07:16:43PM +0100, Paul A Bristow wrote:
I have recently posted to the Boost Sandbox vault an update of my collection of mathematical constants, previously reviewed as a Boost library and ultimately not accepted because of lack of agreement on how to present the constants, especially for User Defined Types, and an outbreak of macrophobia.
thanks, I can certainly make use of your library. I have a nitpick with the docs, though: Could you clarify *which* Zeta function the zetaTwo and zetaThree constants refer to? My guess is the Riemann Zeta function and that seems to match with the values you provide. But there are many other Zeta functions as well. (For example, http://mathworld.wolfram.com/ZetaFunction.html gives links to eight Zeta functions.) So it would help to avoid misunderstandings if you identified the Zeta function you refer to. Second, there is an error and a typo in the comment following the definition of zetaTwo: // Zeta(2) or Pi^(2/6) = sum(1/n**2, n=1..infinity ^^^^^^^^ ^^^ This should read // Zeta(2) or Pi^2 / 6 = sum(1/n**2, n=1..infinity) Regards Christoph -- http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/cludwig.html LiDIA: http://www.informatik.tu-darmstadt.de/TI/LiDIA/Welcome.html

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Christoph Ludwig | Sent: 06 May 2005 21:49 | To: boost@lists.boost.org | Subject: Re: [boost] Math constants - updated. Thanks for this, now updated master to | // Riemann Zeta(2) or Pi^2 / 6 = sum(1/n**2, n=1..infinity) This is way outside my knowledge zone - and I was unclear if and how many to include. Do these have any practical use? Or are they only for Pure Mathematicians? Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com

On Fri, May 06, 2005 at 10:55:15PM +0100, Paul A Bristow wrote:
| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Christoph Ludwig | Sent: 06 May 2005 21:49 | To: boost@lists.boost.org | Subject: Re: [boost] Math constants - updated.
Thanks for this, now updated master to
| // Riemann Zeta(2) or Pi^2 / 6 = sum(1/n**2, n=1..infinity)
yup, I think that's clearer. In the meantime, I had a look into the documentation. In rationale.html#which%20constants you list the constants provided. Unfortunately, this list is not current anymore. E.g., double_constants.hpp defines twoPowThreeDivTwo which is not mentioned in rationale.html. cubeRootFour is called two_pow_two_thirds in the documentation.
This is way outside my knowledge zone - and I was unclear if and how many to include.
Do these have any practical use? Or are they only for Pure Mathematicians?
I am not sure either. I have no use for the Riemann Zeta function right now, but it has a habit of popping up in areas where you did not expect it. So others might very well have use for these constants. Regarding the question of how many constants to include: Can your source code easily be modified to generate other constants as well? Would it make sense to distribute it as well so users can easily generate other constants (say, sqrt(e), Riemann Zeta(n) for n > 3 etc.) if they need them? Regards Christoph -- http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/cludwig.html LiDIA: http://www.informatik.tu-darmstadt.de/TI/LiDIA/Welcome.html

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Christoph Ludwig | Sent: 07 May 2005 10:27 | To: boost@lists.boost.org | Subject: Re: [boost] Math constants - updated. | | In the meantime, I had a look into the documentation. In | rationale.html#which%20constants you list the constants | provided. Unfortunately, this list is not current anymore. E.g., | double_constants.hpp defines twoPowThreeDivTwo which is not | mentioned in | rationale.html. cubeRootFour is called two_pow_two_thirds in the | documentation. Sorry I have not updated this much after the discussion during review. I'll do some tidying up - thanks for noting this. Briefly, there was no consensus on naming scheme, so I have left it as something simple for the time being. I feel the values are rather more important than the names. | > This is way outside my knowledge zone - and I was unclear | if and how many to | > include. | > | > Do these have any practical use? Or are they only for Pure | Mathematicians? | | I am not sure either. I have no use for the Riemann Zeta | function right now, | but it has a habit of popping up in areas where you did not | expect it. So others might very well have use for these constants. Well I can easily add them provided I can find accurate reference values. | Regarding the question of how many constants to include: Can | your source code | easily be modified to generate other constants as well? Would | it make sense to | distribute it as well so users can easily generate other constants | (say, sqrt(e), Riemann Zeta(n) for n > 3 etc.) if they need them? No, not easily. I have a trivial C++ program which uses Victor Shoup's NTL library, (freely available) to calculate and write the files. I could post the MS .lib file and the source, but I think it would be easier for people to just ask me to generate a new set of constants files (or a single file if a fancier MAcro-ized scheme is felt more useful. For example, sqrt(e) sounds like a useful addition and I will add it. Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com

Paul A Bristow wrote:
| rationale.html. cubeRootFour is called two_pow_two_thirds in the | documentation.
Sorry I have not updated this much after the discussion during review. I'll do some tidying up - thanks for noting this.
Another typo: sqrt32 is commented as sqrt(10) in the source. And a question: Sometimes, you omit the trailing 0(s) from some constants. Could you change the scripts to not do this? I could make use of it, the current version of my library (not yet published) includes a "port" of your constants, that is also capable of retrieving the original value (that is, the string in the source!) and pass it on to generic mappers to initialize e.g. RWDecimal<RWMP3Int> or other types with a ctor taking const char*. Having the trailing zeros would make a better statement about the real value-range it represents. Example: 1.23 specifies a number from the range [1.225-1.235) while 1.230 specifies a number from the range [1.2295-1.2305) and thus the latter yields more information. BTW: In case you don't like me to port your header, let me know. Of course, credit will be given if you don't have any objections against the port. Regards, Daniel

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Daniel Frey | Sent: 15 May 2005 23:21 | To: boost@lists.boost.org | Subject: [boost] Re: Math constants - updated. | | Paul A Bristow wrote: | > | rationale.html. cubeRootFour is called two_pow_two_thirds in the | > | documentation. | > | > Sorry I have not updated this much after the discussion | during review. | > I'll do some tidying up - thanks for noting this. | | Another typo: sqrt32 is commented as sqrt(10) in the source. Thanks - corrected in my version and will upload some time. | | And a question: Sometimes, you omit the trailing 0(s) from some | constants. Could you change the scripts to not do this? I | could make use | of it, the current version of my library (not yet published) | includes a | "port" of your constants, that is also capable of retrieving the | original value (that is, the string in the source!) and pass it on to | generic mappers to initialize e.g. RWDecimal<RWMP3Int> or other types | with a ctor taking const char*. Having the trailing zeros would make a | better statement about the real value-range it represents. Example: | | 1.23 specifies a number from the range [1.225-1.235) | | while | | 1.230 specifies a number from the range [1.2295-1.2305) | | and thus the latter yields more information. Not easily, I fear, as NTL's RR type does NOT provide all the formatting like double. I'll look into this - ask the author - but I fear not. | BTW: In case you don't like me to port your header, let me know. Of | course, credit will be given if you don't have any objections. You are welcome to the values - they are hardly secret or novel - But CONVENIENT and ACCURATE (I hope!) Paul PS Oh and don't forget the final desiderata for Boost "Doing The Right Thing" - handling smallest intervals, (floating-point format dependent) for example: pi float, radix = 2, digits = 24 pi is 3.141592653589793238462643383279502884197169400753 to 50 decimal digits. float pi to 9 significant digits 3.14159265 static const float v_l = 13176794.0f/(1 << 22); // One representation. static const float v_u = 13176795.0f/(1 << 22); static const float pi_l = 3.141592502593994140625F; // Exactly representables. static const float pi_u = 3.1415927410125732421875F; pi double, radix = 2, digits = 53 pi is 3.141592653589793238462643383279502884197169400753 to 50 decimal digits. double pi to 17 significant digits 3.1415926535897932 static const double v_l = 7074237752028440.0f/(1 << 51) static const double v_u = 7074237752028441.0f/(1 << 51); static const double pi_l = 3.141592653589793115997963468544185161590576171875; // Exactly representables. static const double pi_u = 3.141592653589793560087173318606801331043243408203125; Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com

Hi Paul, I just took a look at your library because I sometimes need certain constants (like zero, one, pi or e) and was missing the rather special ones (as the 12th root of two, integral constants for well-distributed binary permutation or some magic numbers for linear congruental random. However, this is not the point of this post but made me look at the library design from another perspective: A constants-library needs to be extensible in many directions. Paul A Bristow wrote:
I have recently posted to the Boost Sandbox vault an update of my collection of mathematical constants, previously reviewed as a Boost library and ultimately not accepted because of lack of agreement on how to present the constants, especially for User Defined Types, and an outbreak of macrophobia.
"Lack of agreement" sounds pretty sad. Such a library is most useful, especially for generic programming. Will there never ever be a set of predefined math constants in Boost (in fact, I would prefer the most common constants to be part of the standard library) ? However, macros which can be avoided and do not significantly simplify things _do_ suck (please excuse my straightforwardness), unless you are programming in plain-C (well, they still suck but there often is no better way then ;-) ). They are only acceptable as an interface "#ifndef __cplusplus", IMHO and do not belong in a C++ library. Further macros come especially unhandy when trying to build an extensible framework for constant definition because there is no way to automate macro definition with the preprocessor (see below). Static constants in "<type>_constants"-namespaces are also undesirable, because there is no way to select a namespace named "<T>_constants" from within a template. What I have mentioned so far are facts - not a matter of agreement ! The problem with the current design is there are three implementations, two of them are very disadvantageous and the third not optimal, yet (I'll explain why below). I would not give a positive vote for the library as-is because of that, when writing a review. [...]
(and also as the functions allowing pi to call a function pi() proposed by Michael Kenniston, even though I am not entirely convinced of their usefulness).
What do you need to be convinced ? Did you ever take a look at 'numeric_limits' [ ref. 18.2.1.1 ] ? This is C++ style ;-) and the empty parentheses hurt much less than an ugly 'M_'-prefix and heavy namespace pollution ! From what I see in the archive (I did not read up the original proposal) this can still be refined. I'ld prefer: pi<float>() // constructor invocation of a "convertible to float" or pi<T>() in a template. Probably it's even worth thinking about static functions for the sake of runtime efficiency: pi<float>::value() // needs disassembly-reading on several compilers (the functor semantics could be achieved with a wrapper template in this case) The current state also lacks extensibility. It is not acceptable to rely on an external code generator. We have a great preprocessor library for jobs like this one. It is desirable to have user-defined constants for arbitrary types, which can be defined from within user code on-the-fly, using a self-contained code generator. Typically a constant applies to a group of types: Constants like 'zero', 'one' or 'two' exist for pretty much all types. Constants like 'one_half', 'pi' or 'e' exist for real types. Constants for bit-twiddling purposes only make sense for integral types. There might even be a constant, e.g. 'molecules in the ocean', which is only encodable with a special type. There is another orthogonal dimension: Different problem domains require different constants for the math involved. I made a 10-minutes-hack using the Boost.Preprocessor to clarify the one possible direction I see (some parts mentioned above are left open, but the skeleton works and has been tested with the GCC preprocessor): --- [snip] sample invocation // There can be any number of groups of any number of types. // This example group's name is 'real' // (See Preprocessor library documentation Datatype SEQUENCE) #define BOOST_CONSTANT_GROUP_real (float)(double) // Every type needs a "generator" // The generator is macro that forms an expression the specified // type when passed input from the table below #define BOOST_CONSTANT_GENERATOR_float(value) BOOST_PP_CAT(value,f) #define BOOST_CONSTANT_GENERATOR_double(value) value // This tells us we want two constants, 'pi' and 'e' both for // all types in the group 'real' which can be constructed from // the value in the next column by using the "generator" for the // appropriate type // (See Preprocessor library documentation Datatype SEQUENCE) // (See Preprocessor library documentation Datatype TUPLE) #define BOOST_CONSTANTS \ ((real,pi,3.141592653589793238462643383279502884197)) \ ((real,e,2.718281828459045235360287471352662497757)) // Generate code #include <generate_constants.hpp> --- [snap] --- [snip] header generate_constants.hpp // This header is intended for multiple inclusion. #if !defined(BOOST_PP_IS_ITERATING) //------------------------------------------------------------------------------ // Dependecies //------------------------------------------------------------------------------ #ifndef BOOST_GENERATE_CONSTANTS_HPP_INCLUDED #define BOOST_GENERATE_CONSTANTS_HPP_INCLUDED # include <boost/preprocessor/cat.hpp> # include <boost/preprocessor/seq/elem.hpp> # include <boost/preprocessor/seq/size.hpp> # include <boost/preprocessor/tuple/elem.hpp> # include <boost/preprocessor/iteration/iterate.hpp> #endif //------------------------------------------------------------------------------ // Kick off outer iteration //------------------------------------------------------------------------------ #ifndef BOOST_CONSTANTS # error "BOOST_CONSTANTS is not defined" #endif #define BOOST_PP_ITERATION_LIMITS (0,BOOST_PP_SEQ_SIZE(BOOST_CONSTANTS)-1) #define BOOST_PP_FILENAME_1 "generate_constants.hpp" #include BOOST_PP_ITERATE() //============================================================================== #elif !defined(BOOST_CONSTANT_entry) // For each constant: //============================================================================== #define BOOST_CONSTANT_entry BOOST_PP_SEQ_ELEM( BOOST_PP_FRAME_ITERATION(1) \ , BOOST_CONSTANTS ) #define BOOST_CONSTANT_group \ BOOST_PP_CAT( BOOST_CONSTANT_GROUP_ \ , BOOST_PP_TUPLE_ELEM(3,0,BOOST_CONSTANT_entry) ) #define BOOST_CONSTANT_name BOOST_PP_TUPLE_ELEM(3,1,BOOST_CONSTANT_entry) #define BOOST_CONSTANT_value BOOST_PP_TUPLE_ELEM(3,2,BOOST_CONSTANT_entry) //------------------------------------------------------------------------------ template<typename T> struct BOOST_CONSTANT_name ; #define BOOST_PP_ITERATION_LIMITS \ (0,BOOST_PP_SEQ_SIZE(BOOST_CONSTANT_group)-2) #define BOOST_PP_FILENAME_2 "generate_constants.hpp" #include BOOST_PP_ITERATE() //------------------------------------------------------------------------------ #undef BOOST_CONSTANT_value #undef BOOST_CONSTANT_name #undef BOOST_CONSTANT_group #undef BOOST_CONSTANT_entry //============================================================================== #else // For each target type in constant type group //============================================================================== #define BOOST_CONSTANT_type BOOST_PP_SEQ_ELEM( BOOST_PP_FRAME_ITERATION(2) \ , BOOST_CONSTANT_group ) // Specialization comes here // [...] return BOOST_PP_CAT( BOOST_CONSTANT_GENERATOR_ \ , BOOST_CONSTANT_type )(BOOST_CONSTANT_value) ; // [...] } //============================================================================== #endif --- [snap] Just a hack - there is still plenty of room for improvement and more ideas. Done for fun and inspiration... Regards, Tobias

I concur with Tobias on all his points regarding the constants library. Tobias Schwinger wrote:
However, macros which can be avoided and do not significantly simplify things _do_ suck (please excuse my straightforwardness), unless you are programming in plain-C (well, they still suck but there often is no better way then ;-) ). They are only acceptable as an interface "#ifndef __cplusplus", IMHO and do not belong in a C++ library.
Using macros to represent constants has no place in a modern C++ library, and there is no compelling reason to avoid using functions (such as "pi()") to represent the constants. boost is NOT a C library, and no other boost library tries to accommodate C programmers. There is no reason for the constant library to do so, either.
(and also as the functions allowing pi to call a function pi() proposed by Michael Kenniston, even though I am not entirely convinced of their usefulness).
Why is "pi()" any less useful than "pi"? I also find arguments such as "physicists won't use boost, if they have to use the extra parentheses" to be quite unconvincing. Why is that a good reason to avoid the parentheses? Certainly, if it's easy to avoid the parentheses, it makes us all happier. But if it's not easy, why should boost work so hard to accommodate programmers with such dogmatic views? There is a lot in modern C++ programming, including boost, that isn't pretty. But if it helps me write better, more reliable, and easier to debug code, I'm going to use it. If I have to type an extra pair of parentheses to achieve this, I'm going to do it.
The current state also lacks extensibility. It is not acceptable to rely on an external code generator. We have a great preprocessor library for jobs like this one. It is desirable to have user-defined constants for arbitrary types, which can be defined from within user code on-the-fly, using a self-contained code generator.
This sounds like a pretty cool idea to me.

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Deane Yang | Sent: 08 May 2005 05:09 | To: boost@lists.boost.org | Subject: [boost] Re: Math constants - updated. The C-style macros are only provided so that they can be used by anyone unfortunate to be stuck with C, and by anyone wanting to preprocess them somehow. It didn't cost much to generate them, if one is generating the others. | > The current state also lacks extensibility. It is not | acceptable to rely | > on an external code generator. We have a great preprocessor | library for | > jobs like this one. It is desirable to have user-defined | constants for | > arbitrary types, which can be defined from within user code | on-the-fly, | > using a self-contained code generator. | > | | This sounds like a pretty cool idea to me. Well cool indeed - provided the preprocessor can do 50 decimal digit accuracy floating point ;-) So far macros seem to be struggling with ANY floating point calculations! Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com

Paul A Bristow wrote:
| > The current state also lacks extensibility. It is not | acceptable to rely | > on an external code generator. We have a great preprocessor | library for | > jobs like this one. It is desirable to have user-defined | constants for | > arbitrary types, which can be defined from within user code | on-the-fly, | > using a self-contained code generator. | > | | This sounds like a pretty cool idea to me.
Well cool indeed - provided the preprocessor can do 50 decimal digit accuracy floating point ;-)
So far macros seem to be struggling with ANY floating point calculations!
The preprocessor is only used for pasting in my example, no calculations are involved - the precision of the values depends on the quality of the input. A misunderstanding ?? Regards, Tobias

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Tobias Schwinger | Sent: 17 May 2005 16:53 | To: boost@lists.boost.org | Subject: [boost] Re: Math constants - updated. | | Paul A Bristow wrote: | > | > The current state also lacks extensibility. It is not | > | acceptable to rely | > | > on an external code generator. We have a great preprocessor | > | library for | > | > jobs like this one. It is desirable to have user-defined | > | constants for | > | > arbitrary types, which can be defined from within user code | > | on-the-fly, | > | > using a self-contained code generator. | > | > | > | | > | This sounds like a pretty cool idea to me. | > | > Well cool indeed - provided the preprocessor can do 50 decimal digit | > accuracy floating point ;-) | > | > So far macros seem to be struggling with ANY floating point calculations! | The preprocessor is only used for pasting in my example, no | calculations are | involved - the precision of the values depends on the quality | of the input. | | A misunderstanding ?? Well I agree that you are not using it now - but I just wanted to be quite sure that your extensions ideas didn't include using it. It would be exceedingly cool if a preprocessor 'did' floating point at all, especially arbitrary precision. But I'm not holding my breath ;-) Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Paul A Bristow | Sent: 17 May 2005 15:23 | To: boost@lists.boost.org | Subject: RE: [boost] Re: Math constants I attach a short file with some samples of math constants together with their 'interval' upper and lower values, which (mostly) when compiled will be only a single least significant bit different (or the same of course). The upper and lower values contain a lot of decimal digits because they are 'exactly representable' for the floating point layout given. C++ Exactly representable values do not involve any rounding on input (to the appropriate floating point format). Of course this file does not compile - many duplicates - but when the appropriate pair of upper and lower are chosen, they should do. For the most common case of an IEEE double, // C++ Exactly representable interval values of pi for 2 radix & 53 significand bits. static const double pi_l = 3.141592653589793115997963468544185161590576171875; // lower static const double pi = 3.1415926535897932384626433832795028841971694007530293; // starting with this value. static const double pi_u = 3.141592653589793560087173318606801331043243408203125; // upper When used to initialise a double, v_d_l = 3.1415926535897931 == 0x400921fb54442d18 // lower v_d = 3.1415926535897931 == 0x400921fb54442d18 // 'middle' == lower v_d_u = 3.1415926535897936 == 0x400921fb54442d19 // upper The number of possibly significant digits is given by std::numeric_limits<double::digits() * 3010 /10000 and is 17 (std::numeric_limits<double::digits10() in contrast is the number of __guaranteed__ accurate decimal digits and is 15). Questions: 1 Are there many (any?) potential users for interval arithmetic computing (we have a Boost library). 2 Would they find the intervals of the constants updated in the Sandbox useful? 3 Can any MACRO whizz-kids suggest the _best_ way to provide only pairs (or trios) for the appropriate floating point format? 4 I can only calculate for radix == 2 (and can't be bothered to work out for radix 8, 10, 16, 42...?). If anyone wants these and can tell me how, please do so. 5 So one is really only chosing float, double, long double, or some UDT like NTL arbitrary precision quads on the basis of the number of significand bits, usually 24, 53, 64, 105, 106, 113, 127. For example, to produce the above definitions for 53 significand IEEE 754 X86 double. Thanks. Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com

"Paul" == Paul A Bristow <pbristow@hetp.u-net.com> writes:
> | -----Original Message----- | From: > boost-bounces@lists.boost.org | > [mailto:boost-bounces@lists.boost.org] On Behalf Of Paul A > Bristow | Sent: 17 May 2005 15:23 | To: boost@lists.boost.org | > Subject: RE: [boost] Re: Math constants > I attach a short file with some samples of math constants > together with their 'interval' upper and lower values, which > (mostly) when compiled will be only a single least significant > bit different (or the same of course). > The upper and lower values contain a lot of decimal digits > because they are 'exactly representable' for the floating point > layout given. > C++ Exactly representable values do not involve any rounding on > input (to the appropriate floating point format). > Of course this file does not compile - many duplicates - but > when the appropriate pair of upper and lower are chosen, they > should do. > For the most common case of an IEEE double, > // C++ Exactly representable interval values of pi for 2 radix & > 53 significand bits. static const double pi_l = > 3.141592653589793115997963468544185161590576171875; // lower > static const double pi = > 3.1415926535897932384626433832795028841971694007530293; // > starting with this value. static const double pi_u = > 3.141592653589793560087173318606801331043243408203125; // upper > When used to initialise a double, > v_d_l = 3.1415926535897931 == 0x400921fb54442d18 // lower v_d = > 3.1415926535897931 == 0x400921fb54442d18 // 'middle' == lower > v_d_u = 3.1415926535897936 == 0x400921fb54442d19 // upper > The number of possibly significant digits is given by > std::numeric_limits<double::digits() * 3010 /10000 and is 17 > (std::numeric_limits<double::digits10() in contrast is the > number of __guaranteed__ accurate decimal digits and is 15). > Questions: > 1 Are there many (any?) potential users for interval arithmetic > computing (we have a Boost library). > 2 Would they find the intervals of the constants updated in the > Sandbox useful? > 3 Can any MACRO whizz-kids suggest the _best_ way to provide > only pairs (or trios) for the appropriate floating point format? > 4 I can only calculate for radix == 2 (and can't be bothered to > work out for radix 8, 10, 16, 42...?). If anyone wants these and > can tell me how, please do so. > 5 So one is really only chosing float, double, long double, or > some UDT like NTL arbitrary precision quads on the basis of the > number of significand bits, usually 24, 53, 64, 105, 106, 113, > 127. > For example, to produce the above definitions for 53 significand > IEEE 754 X86 double. > Thanks. > Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB > +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com > _______________________________________________ > Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Liu Jin Did you intend to reply to this? Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com | -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Liu Jin | Sent: 30 May 2005 07:49 | To: boost@lists.boost.org | Subject: Re: [boost] Re: Math constants - Smallest Interval values? | | >>>>> "Paul" == Paul A Bristow <pbristow@hetp.u-net.com> writes: | | > | -----Original Message----- | From: | > boost-bounces@lists.boost.org | | > [mailto:boost-bounces@lists.boost.org] On Behalf Of Paul A | > Bristow | Sent: 17 May 2005 15:23 | To: boost@lists.boost.org | | > Subject: RE: [boost] Re: Math constants |

"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Static constants in "<type>_constants"-namespaces are also undesirable, because there is no way to select a namespace named "<T>_constants" from within a template.
FWIW thi would work fine for me: typedef std::math::constants<T> math; 2 * math::pi * r ; regards Andy Little

Static constants in "<type>_constants"-namespaces are also undesirable, because there is no way to select a namespace named "<T>_constants" from within a template.
FWIW thi would work fine for me:
typedef std::math::constants<T> math; 2 * math::pi * r ;
Except you can't then add new constants without changing the definition of math_constants. If you use a namespace for the "container" and free-standing template functions, then you can either: Add new constants. Add support for new types. Without changing the existing code. John.

John Maddock wrote:
Static constants in "<type>_constants"-namespaces are also undesirable, because there is no way to select a namespace named "<T>_constants" from within a template.
FWIW thi would work fine for me:
typedef std::math::constants<T> math; 2 * math::pi * r ;
Except you can't then add new constants without changing the definition of math_constants. If you use a namespace for the "container" and free-standing template functions, then you can either:
Add new constants. Add support for new types.
Without changing the existing code.
These problems (and many more) are already solved by the constants library I wrote some time ago. The weak points are: No documentation yet and I use typeof, although a great deal of functionality can be preserved without typeof. I think I should work on these two points, but till then, you might want to look at the current version, complete with examples for physical constants supporting unit-libraries! It can be found at <http://boost-sandbox.sourceforge.net/vault/index.php?directory=daniel_frey> Regards, Daniel

"Daniel Frey" <d.frey@gmx.de> wrote
These problems (and many more) are already solved by the constants library I wrote some time ago. The weak points are: No documentation yet and I use typeof.
Great.. I hope you will be able to do a review of the typeof library, when it comes up for review around about the 20th of this month? http://boost-sandbox.sourceforge.net/vault/, typeof.zip. AFAIK this would make use of typeof in a bost libaray acceptable in my book . regards Andy Little

Andy Little wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Static constants in "<type>_constants"-namespaces are also undesirable, because there is no way to select a namespace named "<T>_constants" from within a template.
FWIW thi would work fine for me:
typedef std::math::constants<T> math; 2 * math::pi * r ;
This looks nice at first glance. Besides getting rid of the empty parentheses, there are the following disadvantages: - modularity/extensibility (once constants<T> is defined you can't add constants to it) - portability (the code above won't compile with BCC) - there is no way to pass constants as a type template argument Regards, Tobias

"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Andy Little wrote:
FWIW thi would work fine for me:
typedef std::math::constants<T> math; 2 * math::pi * r ;
This looks nice at first glance.
Thanks ......................................... :-)
Besides getting rid of the empty parentheses, there are the following disadvantages: ^^^ I Assume you mean In spite of ?
- modularity/extensibility (once constants<T> is defined you can't add constants to it)
In practise you can. constants struct 's members are really just global constants. Your compiler wont know the difference, because it only instantiates what you ask for, add a new type and it wont know its there till you use it, and will then assume its always been there. However not conforming I guess. A derivation for the newer constants would be conforming. template <typename T> struct constants2 : constants<T>{ static T const & andys_constant; } template <typename T> T const & constants2<T>::andys_constant = T(2005); typedef std::math::constants2<double> math; 2 * math::pi * r ;
- portability (the code above won't compile with BCC)
Whats the error. AFAIK its correct C++ is it not ? If its correct C++ then I think this is not a strong argument.
- there is no way to pass constants as a type template argument. ( IOW use a function ..? ) Well .. is that an essential ?..Do you have a use case demonstrating this need? AFAIK constants are always pretty specific to their own particularly algorithms.
Whatever ... I still like std::math::constants<T>::pi much better than std::pi<T>() :-) regards Andy Little

Andy Little wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Andy Little wrote: Besides getting rid of the empty parentheses, there are the following disadvantages:
^^^ I Assume you mean In spite of ?
Yes I do, thanks for the correction.
- modularity/extensibility (once constants<T> is defined you can't add constants to it)
John's post in this thread explains this point in more detail.
In practise you can. constants struct 's members are really just global constants. Your compiler wont know the difference, because it only instantiates what you ask for, add a new type and it wont know its there till you use it, and will then assume its always been there. However not conforming I guess. A derivation for the newer constants would be conforming.
template <typename T> struct constants2 : constants<T>{ static T const & andys_constant; } template <typename T> T const & constants2<T>::andys_constant = T(2005);
typedef std::math::constants2<double> math; 2 * math::pi * r ;
Hmmm.... This seems most clumsy to me. A matter of personal taste, perhaps.
- portability (the code above won't compile with BCC)
Whats the error. AFAIK its correct C++ is it not ? If its correct C++ then I think this is not a strong argument.
Probably - but it's not the only one.
- there is no way to pass constants as a type template argument.
( IOW use a function ..? )
No. A class somehow like this: template<typename T> struct name; template<> struct name<TYPE> { operator TYPE() const { return ... }; TYPE operator() () const { return ... }; }; //...
Well .. is that an essential ?..Do you have a use case demonstrating this need?
The interface of std::generate is more generic than the one of std::fill. Representing constants as functors we don't need to write less flexible interfaces like the one of std::fill (which can be seen as a special case of std::generate, provided for convenience).
AFAIK constants are always pretty specific to their own particularly algorithms.
I don't think e.g. 'zero' or 'one' are.
Whatever ... I still like std::math::constants<T>::pi much better than std::pi<T>() :-)
Any pro arguments ;-) ? It's common practice to call getter member functions, so what is wrong with "global getter functors" to encapsulate constants ? It's even formally correct math, as you can define functions like this: f(a,b,c) = d = const I also feel some sympathy for the idea of allowing any number of (dummy) arguments for operator() because it plugs nicely into generic functional code. Example: template< [...], typename AngleFunction> struct hinge { AngleFunction f; [...] f(time) [...] }; typedef hinge< [...], constants::pi > const_hinge_180; Regards, Tobias

"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Andy Little wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
- there is no way to pass constants as a type template argument.
( IOW use a function ..? )
No. A class somehow like this:
template<typename T> struct name;
template<> struct name<TYPE> { operator TYPE() const { return ... }; TYPE operator() () const { return ... }; };
FWIW I had alook at this approach yesterday. see "test.cpp" attached. I think it could be made to work. In unary contexts it requires explicit conversion, but I guess there is no way around that. Of course you need an object.. boost::math::pi pi ; or a temporary.. boost::math::pi() ;. However I guess this means you can use either pi or pi() syntax ... :-) regards Andy Little

Andy Little wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Andy Little wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
- there is no way to pass constants as a type template argument.
( IOW use a function ..? )
No. A class somehow like this:
template<typename T> struct name;
template<> struct name<TYPE> { operator TYPE() const { return ... }; TYPE operator() () const { return ... }; };
FWIW I had alook at this approach yesterday. see "test.cpp" attached. I think it could be made to work. In unary contexts it requires explicit conversion, but I guess there is no way around that. Of course you need an object.. boost::math::pi pi ; or a temporary.. boost::math::pi() ;. However I guess this means you can use either pi or pi() syntax ... :-)
Is it asked too much to let the user just specify the type ? Every variable declaration requires a type so why make things more complicated for constants ? C++ is a strictly typed language and I really can't see the point in emulating loose typedness for constants (especially since you can "declare" a pi constant by instantiating an object, e.g: "pi<float> PIf;"). Regards, Tobias

"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Is it asked too much to let the user just specify the type ?
but the user can specify the type...: float f = double(pi);
Every variable declaration requires a type so why make things more complicated for constants ?
In the math constants review I understood that not requiring to declare the type was a desirable feature.
C++ is a strictly typed language and I really can't see the point in emulating loose typedness for constants (especially since you can "declare" a pi constant by instantiating an object, e.g: "pi<float> PIf;").
I guess... Whatever... if explicit type declaration is required so be it... Heigh Ho ... regards Andy Little

Andy Little wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Is it asked too much to let the user just specify the type ?
but the user can specify the type...:
float f = double(pi);
Every variable declaration requires a type so why make things more complicated for constants ?
In the math constants review I understood that not requiring to declare the type was a desirable feature.
C++ is a strictly typed language and I really can't see the point in emulating loose typedness for constants (especially since you can "declare" a pi constant by instantiating an object, e.g: "pi<float> PIf;").
I guess...
Whatever... if explicit type declaration is required so be it... Heigh Ho ...
-LOL- it's my personal opinion and I don't claim to own an "exclusive lock" on the truth of things. It feels more in the spirit of the language to me, that's all (but I'm glad to hear my babbleing sounds convincing). Btw. Daniel Frey's library looks very interesting - did you take a look at it ? It uses expression templates to allow "constant expressions" e.g: 'pi * two' or 'pow(two,one / twelve)' and (just as your test) does "context-detection" to get the type from the expression the constant is used in (well, if users want this, so be it - heigh ho ;-) ). Regards, Tobias

"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Btw. Daniel Frey's library looks very interesting - did you take a look at it ?
I looked at it during the math constants review. I didnt look at the latest version, but I have now. Unfortunately it doesnt compile on VC7.1 but looks like a smarter version of my offering. (I guess that 's where the idea for mine came from.) OTOH it doesnt do eg double(pi) which syntax I happen to like.
It uses expression templates to allow "constant expressions" e.g: 'pi * two' or 'pow(two,one / twelve)'
Thats interesting . I need this type of thing , but its clumsy in use. In an ideal world I guess one would be able to say e.g pow(my_num, n ,d ); and get the function template <typename T, int N, int D > T pow(T,N, D);
and (just as your test) does "context-detection" to get the type from the expression the constant is used in (well, if users want this, so be it - heigh ho ;-) ).
It does fit most of the criteria laid down in the review, but perhaps its just too smart :-) regards Andy Little

Andy Little wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Btw. Daniel Frey's library looks very interesting - did you take a look at it ?
I looked at it during the math constants review. I didnt look at the latest version, but I have now. Unfortunately it doesnt compile on VC7.1 but looks like a smarter version of my offering. (I guess that 's where the idea for mine came from.) OTOH it doesnt do eg double(pi) which syntax I happen to like.
Me too, but it doesn't work for generic types T. If T has several ctors that take different types (e.g. float, double, T), pi has no way to decide which cast would be appropriate.
It uses expression templates to allow "constant expressions" e.g: 'pi * two' or 'pow(two,one / twelve)'
Hm... I just had the idea of allowing a simple 'constant_<2> two;' to declare integer constants, but immediately ran into a more subtle problem involving two_value. Seems there's still something to redesign, so I have to play with this idea for some time...
Thats interesting . I need this type of thing , but its clumsy in use.
What is clumsy, what would be an improvement? Or a better syntax? Even if it seems impossible, I would like to know what others consider intuitive. If you have an idea how it should look like, please share it.
In an ideal world I guess one would be able to say e.g pow(my_num, n ,d ); and get the function template <typename T, int N, int D > T pow(T,N, D);
Here, I'm at a loss. Can you elaborate, please? Regards, Daniel

I very much appreciate Daniel's efforts on this, but I do get the impression that it still needs more testing and tweaking. Couldn't boost first accept a constants library that has an easier-to-implement modern C++ interface (parentheses and all), so that we can all start using it sooner rather than later, and then incorporate Daniel's interface at a later date? Daniel Frey wrote:
Andy Little wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Btw. Daniel Frey's library looks very interesting - did you take a look at it ?

"Deane Yang" <deane_yang@yahoo.com> wrote in message news:d5qr1n$4ef$1@sea.gmane.org...
I very much appreciate Daniel's efforts on this, but I do get the impression that it still needs more testing and tweaking.
Couldn't boost first accept a constants library that has an easier-to-implement modern C++ interface (parentheses and all), so that we can all start using it sooner rather than later, and then incorporate Daniel's interface at a later date?
I agree. How about ' math constants' staying with the simplest approach (eg function) while Daniel Freys 'smart constants' are made into a separate proposal? regards Andy Little

I have just returned from a "well-earned ;-)" holiday to see many have responded to my post about math constants. Thanks for all your interest and suggestions. Can I respond with a few comments: 1 There is VIOLENT opposition to requiring pi(). You may not like it, but there IS! I am sympathetic to this view - many equations are complex enough with yet more bracket clutter. This is why Walter Brown is pushing for a C++0X change to avoid the ()s, and I think it will probably happen. 2 Daniel Frey's suggestions look most promising, but they just don't work portably - yet. There are now C++0X language typeof proposals and Boost typeof kludges. If he can get it to work using these for the main recent compilers, I'll happily produce the values. (Or Daniel could use the greatly despised macro values, and the undefines to erase all traces of macro names. This is anexample of why I have included these two files: if they offend you, don't use them!). 3 Before you get TOO excited about further calculated values, don't forget that you _can't_ just use the compiler to evaluate the expressions and be sure of the most accurate results. This is especially true for pow, sqrt, log, exp which are usually several 'bits' wrong. This is why using a higher accuracy system is still a good idea to get the most accurate and most usefully in practice, the most _consistent_ value, and so the most _portable_ value. 4 I concluded from the previous review that we could never agree until the language problems are resolved (or worked round). 5 Don't also forget the desirability of including the smallest intervals which include values, to allow use with the existing Boost interval library. These have the additional complication of being floating-point format dependent. Meanwhile, I hope some will find the sandbox values useful taking them in whichever format offends you least! I suspect 95% of people will find #include double_constants.hpp will meet 99% of their needs. I also suspect that many people will simple copy and paste the single line defining the value that they need. Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com | -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Deane Yang | Sent: 10 May 2005 18:37 | To: boost@lists.boost.org | Subject: [boost] Re: Math constants - updated. | | I very much appreciate Daniel's efforts on this, but I do get the | impression that it still needs more testing and tweaking. | | Couldn't boost first accept a constants library that has an | easier-to-implement modern C++ interface (parentheses and | all), so that | we can all start using it sooner rather than later, and then | incorporate | Daniel's interface at a later date? | | Daniel Frey wrote: | > Andy Little wrote: | > | >>"Tobias Schwinger" <tschwinger@neoscientists.org> wrote | >> | >> | >>>Btw. Daniel Frey's library looks very interesting - did you take a | >>>look at it | >>>? | | _______________________________________________ | Unsubscribe & other changes: | http://lists.boost.org/mailman/listinfo.cgi/boost |

Paul, Paul A Bristow wrote:
1 There is VIOLENT opposition to requiring pi(). You may not like it, but there IS! I am sympathetic to this view - many equations are complex enough with yet more bracket clutter.
Where is this "VIOLENT opposition" being expressed? I have never seen anything of the sort on this list; I have only seen your assertions that it exists. Could you elaborate? Deane

Deane Yang wrote:
Paul,
Paul A Bristow wrote:
1 There is VIOLENT opposition to requiring pi(). You may not like it, but there IS! I am sympathetic to this view - many equations are complex enough with yet more bracket clutter.
Where is this "VIOLENT opposition" being expressed? I have never seen anything of the sort on this list; I have only seen your assertions that it exists. Could you elaborate?
Deane
I unfortunately have seen this opposition too, although not on the boost list. I've mostly encountered it from my colleagues who are physicists first, and use code as a tool, but couldn't care less about actually learning current idioms. For instance, there was a recent discussion on mailing list for the ROOT software package, which is a high energy physics analysis framework written in C++ (based on the CINT C++ interpreter). The discussion was about the introduction of more "modern" idioms into the visible programmer interface, and there was vociferous opposition (mostly from those who have been around for a while) to the use of such "exotic" C++ features as templates because "most compilers don't support them yet", and new style casts, "because the C way is less verbose". There was also concern expressed about using boost components because some people thought that most of boost relied on "non-standard" C++ that "wasn't portable except to a few platforms". Mention of smart pointers among my memory leaking colleagues is met with blank stares ... memory leaks are, after all, just a part of writing code in C and C++, right? The complaints I've heard about namespaces alone would be enough to bring you to tears... Make no mistake ... these are very, very smart people saying these things. But like most of us, they just can't or won't be bothered to invest energy in keeping up with current trends in areas outside their fields of expertise. That all said, I don't put much weight on the opinions of practitioners who fail to keep current or to understand why things are the way they are. Boost should "do the right thing". The users who complain will follow along after a time, because they'll have no choice ... their tools will change out from under them, and their graduate students will roll their eyes and force them to adapt to the modern idioms. We shouldn't be held back by the whiners ... if we did, the projects I work on would still be writing all our data acquisition and analysis code in Fortran IV :-)
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Kevin Lynch wrote:
Deane Yang wrote:
I unfortunately have seen this opposition too, although not on the boost list. I've mostly encountered it from my colleagues who are physicists first, and use code as a tool, but couldn't care less about actually learning current idioms.
....
Make no mistake ... these are very, very smart people saying these things. But like most of us, they just can't or won't be bothered to invest energy in keeping up with current trends in areas outside their fields of expertise.
As some recent postings to this list have indicated, it is probably true that MOST C++ programmers, and not just the physicists, avoid templates and the idioms used and promoted by boost. On the other hand, the boost libraries have never, as far as I can tell, compromised on interfaces to accommodate programmers who don't like templates or modern C++ idioms. Why should the constants library be any different? Why should boost give physicists special consideration that most C++ programmers do not get?
That all said, I don't put much weight on the opinions of practitioners who fail to keep current or to understand why things are the way they are. Boost should "do the right thing". The users who complain will follow along after a time, because they'll have no choice ... their tools will change out from under them, and their graduate students will roll their eyes and force them to adapt to the modern idioms. We shouldn't be held back by the whiners ... if we did, the projects I work on would still be writing all our data acquisition and analysis code in Fortran IV :-)
Amen!

Hi, I don't generally post to this list, but I think this warrants a comment.
As some recent postings to this list have indicated, it is probably true that MOST C++ programmers, and not just the physicists, avoid templates and the idioms used and promoted by boost.
On the other hand, the boost libraries have never, as far as I can tell, compromised on interfaces to accommodate programmers who don't like templates or modern C++ idioms.
ROOT voice is one. Mine is another, nowhere near as negative about template as ROOT. I think there are many good uses for templates, there are good uses for most tools. No tool is the best solution for every problem, and the same goes for templates. I find boost code close to impenetrable, and I am pretty good with C++. I have no doubt I can fully understand the code if I take the time -- but is that good use of my time? In comparison, I can take a glance of Qt-based code and immediately understand what it does. So as functional as boost is, I rarely suggest it to be used at my current work, it's rarely worth the investment required. There are exceptions, but they are not many and tend to be from the simpler variety. The set of things that can be used as black boxes, without needing to know the internals, is small and grows very slowly. (Witness how long it takes for example for std::vector to get into mainstream code.) From my point of view, a good engineer takes the people along them giving them all the time what they need -- a few paces ahead, not a whole marathon ahead.
Why should the constants library be any different? Why should boost give physicists special consideration that most C++ programmers do not get?
There is nothing extraordinary about it. A library is designed for clients, and it's sound to listen to what they desire. If they don't like the product, they'll use something else. That may or may not matter to you. Lassi -- What we have here is a case of too many pieces of software trying to outsmart each other and the user loses. --Robert Lipe

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Deane Yang | Sent: 16 May 2005 02:37 | To: boost@lists.boost.org | Subject: [boost] Re: Math constants - updated. | Where is this "VIOLENT opposition" being expressed? I have never seen | anything of the sort on this list; I have only seen your | assertions that it exists. Could you elaborate? You are obviously living in a world of 'real' programmers - who never eat quiche! But there is another planet on which live nearly all 'amateur' programmers, scientists and engineers, sociologists, medics, electricians and plumbers ... me even ;-) who, if told that pi is a function, will assume you are joking and just head back to use a more sensible language. They don't read or contribute to the Boost list, let alone understand! But they _ARE_ the 'customers'. And I re-iterate that they do have a good point. Equations are bracket-infested enough already. Why is there a syntatic requirement for yet more brackets? pi IS a constant after all. This is why Walter Brown has proposed to change the language to make them unnecessary, in response to his 'customers' wishes. Don't forget too, that >95% of all use is simply a IEEE 64-bit double, so ALL the others are corner cases. We need to ensure that using the double case is nice and easy. We want to avoid decorating every reference to pi with (double) or <double> or ... This seems to me the advantage of using namespaces - a single using statement can fix it. Chosing a header file double_constants.hpp also achieves this ease_of_using_doubles. But I have no fixed views on how to achieve this. Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com

Paul A Bristow wrote:
But there is another planet on which live nearly all 'amateur' programmers, scientists and engineers, sociologists, medics, electricians and plumbers ... me even ;-) who, if told that pi is a function, will assume you are joking and just head back to use a more sensible language.
I don't see why boost should be influenced by people who will make decisions so cavalierly.
They don't read or contribute to the Boost list, let alone understand! But they _ARE_ the 'customers'.
Perhaps I misunderstand, but I think you're talking about people who either do not even know about boost or, if they have, took one look and ran the other way. So I don't see them as being the customers. Or, if they're the ones you're targeting, why are you trying to place the library in boost, which clearly targets only the most sophisticated C++ programmers? I have nothing against physicists or other C++ programmers who find templates and boost way too obscure or complex to use and choose to stick with older techniques that they know how to use effectively. I am, in fact, one of the "amateur" programmers you refer to, and I myself find much of boost way too difficult to learn. Like everybody else, I'm sure if I had the time to study boost more carefully, I could use it effectively. But I don't. So I use only the parts I understand. But what I like about boost a lot is that it adheres relatively well to a core set of principles and idioms that fit very well with my programming style. In particular, I am absolutely delighted to have stumbled onto a community of C++ programmers who understand the power of templates way better than I do. I am against "polluting" boost with code that compromises these principles, because it would re-introduce difficulties that boost helps me avoid. I am not against your different implementations of the constants library; I might even use them myself as a compromise. But I just don't think they belong in boost; I rely on boost as being a fairly uncompromising library that tries to remains true to its basic principles.

I have nothing against physicists or other C++ programmers who find templates and boost way too obscure or complex to use and choose to stick with older techniques that they know how to use effectively. [...] But what I like about boost a lot is that it adheres relatively well to a core set of principles and idioms that fit very well with my programming style. [...] I am against "polluting" boost with code that compromises these principles, because it would re-introduce difficulties that boost helps me avoid.
Do I read you correctly that you actually say templates are an essential part to every design in boost? I must admit such an approach would never occur to me, I have always thought one picks a technique applicable to the problem, and sometimes it's the 100-year old version that does the best job. "One hammer doesn't fit all screws" they say :) Lassi -- But in our enthusiasm, we could not resist a radical overhaul of the system, in which all of its major weaknesses have been exposed, analyzed, and replaced with new weaknesses. --Bruce Leverett, "Register Allocation in Optimizing Compilers"

Lassi A.Tuura wrote:
I have nothing against physicists or other C++ programmers who find templates and boost way too obscure or complex to use and choose to stick with older techniques that they know how to use effectively. [...] But what I like about boost a lot is that it adheres relatively well to a core set of principles and idioms that fit very well with my programming style. [...] I am against "polluting" boost with code that compromises these principles, because it would re-introduce difficulties that boost helps me avoid.
Do I read you correctly that you actually say templates are an essential part to every design in boost? I must admit such an approach would never occur to me, I have always thought one picks a technique applicable to the problem, and sometimes it's the 100-year old version that does the best job. "One hammer doesn't fit all screws" they say :)
I'm sorry for not being clear. Not every part of boost uses templates, but templates are used quite extensively in boost. I think boost does try to use the best technique applicable to each problem. For the vast majority of the problems addressed by boost, templates play a crucial role. Before I found boost, I was starting to discover the power of templates in my own programming, and I was very happy to find a group of real C++ programmers (unlike me) who already understood this better than me, had developed libraries I needed, and made them far more bulletproof than I am capable of. If boost had done all of this without templates, I would have been just as happy, but, as it happens, templates do provide a crucial tool.

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Paul A Bristow | Sent: 15 May 2005 18:48 | To: boost@lists.boost.org | Subject: RE: [boost] Re: Math constants - updated. | | This is why Walter Brown is pushing for a C++0X change | to avoid the ()s, and I think it will probably happen. See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1785.pdf for details. Perhaps we should wait for this? But use double_constants.hpp etc for now? Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com

"Daniel Frey" <d.frey@gmx.de> wrote
Andy Little wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Btw. Daniel Frey's library looks very interesting - did you take a look at it ?
I looked at it during the math constants review. I didnt look at the latest version, but I have now. Unfortunately it doesnt compile on VC7.1 but looks like a smarter version of my offering. (I guess that 's where the idea for mine came from.) OTOH it doesnt do eg double(pi) which syntax I happen to like.
Me too, but it doesn't work for generic types T. If T has several ctors that take different types (e.g. float, double, T), pi has no way to decide which cast would be appropriate.
I got around this ( I thought) in my quickie by using a traits class, but its messy... I guess. However IMO it shouldnt be convertible to anything. There needs to be some concept that it models. FWIW I would be content with , float, double long double. IOW numeric types. But ... eg FWIW my version still fails in boost::numeric::interval. This is always going to be the problem when trying to make one type maquerade as another :-(
It uses expression templates to allow "constant expressions" e.g: 'pi * two' or 'pow(two,one / twelve)'
Hm... I just had the idea of allowing a simple 'constant_<2> two;' to declare integer constants, but immediately ran into a more subtle problem involving two_value. Seems there's still something to redesign, so I have to play with this idea for some time...
A 'math constant' is expected to be pretty unexciting, which this doesnt deliver. Maybe if it was repackaged as say a quirky 'smart constant', rather than The std::math_constant it would be more gratefully received. IOW The big hurdle is that its slightly weird and dont always act like the type its supposed to replace. ( Which is why I am pretty content with my original solution.eg template <typename T> struct constant{ T const & pi; T const & e;... etc}Ok.... its not extensible (re higher in the thread) but it is simple and acts exactly as you would expect a T to always, (because it is a T);) The alternative is just a function eg pi<T>(); I guess.
Thats interesting . I need this type of thing , but its clumsy in use.
What is clumsy, what would be an improvement? Or a better syntax? Even if it seems impossible, I would like to know what others consider intuitive. If you have an idea how it should look like, please share it.
In an ideal world I guess one would be able to say e.g pow(my_num, n ,d ); and get the function template <typename T, int N, int D > T pow(T,N, D);
Here, I'm at a loss. Can you elaborate, please?
sure .. .... but of course it isnt doable in the language. (BTW the pi * pi stuff is cool !. Sorry... it appears I have been dismissive of that.) int val = my::pow(9,3,2); eg replaces std::pow( static_cast<double>(9) ,3./2) with the above signature. ( val --> 27 ) today you might do this as my::pow<9,3,2>(); Another example of using compile time constants directly in expressions point + point --> affine_point_combination<2> point + point + point --> affine_point_combination<3> etc.. point p = affine_combination<N>() / n ; //( where n == N and the exact function depends on whether n is a compile time constant and the runtime version throws an exception if n !=N ) affine_combination<N> / x ( where x is a compile time evaluable constant And x!=N) ---> Compile time Error I guess however, that this would require figuring out the type of constness of n. regards Andy Little

Andy Little wrote:
"Daniel Frey" <d.frey@gmx.de> wrote
Andy Little wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote
Btw. Daniel Frey's library looks very interesting - did you take a look at it ?
I looked at it during the math constants review. I didnt look at the latest version, but I have now. Unfortunately it doesnt compile on VC7.1 but looks like a smarter version of my offering. (I guess that 's where the idea for mine came from.) OTOH it doesnt do eg double(pi) which syntax I happen to like.
Me too, but it doesn't work for generic types T. If T has several ctors that take different types (e.g. float, double, T), pi has no way to decide which cast would be appropriate.
I got around this ( I thought) in my quickie by using a traits class, but its messy... I guess.
You can't. Except you only offer a single conversion operator, but that means your solution doesn't scale anymore. It's a limitation from the language that cannot be worked-around. Or maybe we are talking about different things? I mean: struct SomeFloatType { SomeFloatType( double ); }; struct SomeConstant { template< typename T > operator T() const { return T(); } }; int main() { SomeConstant c; SomeFloatType x( c ); // ambiguous! } GCC 3.3.5 says: g++ -Wall -ansi -pedantic -O3 --message-length=0 t.cc -o t t.cc: In function `int main()': t.cc:14: error: call of overloaded `SomeFloatType(SomeConstant&)' is ambiguous t.cc:2: error: candidates are: SomeFloatType::SomeFloatType(const SomeFloatType&) t.cc:3: error: SomeFloatType::SomeFloatType(double) make: *** [t] Error 1 To sum it up: *Some* examples do work, but T(c) is not a *generic* syntax that works. Thus I went for .get<T>()
However IMO it shouldnt be convertible to anything. There needs to be some concept that it models. FWIW I would be content with , float, double long double. IOW numeric types. But ... eg FWIW my version still fails in boost::numeric::interval. This is always going to be the problem when trying to make one type maquerade as another :-(
FWIW, the constants I wrote only look as if they convert to anything. But in the end, you must have an implementation that yields the value. If there is no constant (or explicit mapper) for a type called "fluffy", the compiler complains. Static type checking should be preserved - and is. I tried to avoid magic that leads to surprises, as this immediatly leads to bugs in the real world.
It uses expression templates to allow "constant expressions" e.g: 'pi * two' or 'pow(two,one / twelve)'
Hm... I just had the idea of allowing a simple 'constant_<2> two;' to declare integer constants, but immediately ran into a more subtle problem involving two_value. Seems there's still something to redesign, so I have to play with this idea for some time...
A 'math constant' is expected to be pretty unexciting, which this doesnt deliver. Maybe if it was repackaged as say a quirky 'smart constant', rather than The std::math_constant it would be more gratefully received.
The constant itself is still simple: two. It should come from some header as well as all other constants you usually need. A normal user should not be concerned with defining constants. The best example is probably still: template< typename Y > inline typename SI< Y >::quantity idealGasLaw( const typename SI< Y >::pressure& p, const typename SI< Y >::volume& v, const typename SI< Y >::temperature& t ) { using boost::units::si::constants::chemistry::R; return p * v / ( R * t ); } The constant comes from a header, the user is not bothered with anything else at this point. Whatever float-point-type (native or UDT) he uses for Y, the algorithm as well as the constant library itself will be unaffected. You can define algorithm libraries containing the above, unit libraries, constant libraries (that is libraries that yield the constants for a certain use-case, not the library that helps to define these constants (my lib)) and float-point-types independently. A user might need to add some glue to use certain combinations in his projects, although most things for float/double will work out-of-the-box. The most important point is, that the user should never be forced to reinvent the wheel, only assemble some stuff! This is what I consider reuseability.
In an ideal world I guess one would be able to say e.g pow(my_num, n ,d ); and get the function template <typename T, int N, int D > T pow(T,N, D);
Here, I'm at a loss. Can you elaborate, please?
sure .. .... but of course it isnt doable in the language. (BTW the pi * pi stuff is cool !. Sorry... it appears I have been dismissive of that.)
int val = my::pow(9,3,2); eg replaces std::pow( static_cast<double>(9)
With my library, you can make pow(nine,three,two) a constant. Today. Given the ideas I have about constant_<9> nine; etc., this might even work for all integer numbers in the future, although I can't promise anything. If it works, you could also spell it sqrt(pow(nine,two)) or sqrt(nine*nine) - all leading to real constants :) Regards, Daniel

"Daniel Frey" <d.frey@gmx.de> wrote
GCC 3.3.5 says:
[etc]
To sum it up: *Some* examples do work, but T(c) is not a *generic* syntax that works. Thus I went for .get<T>()
Ok. ... but its ugly to write that. Maybe aesthetics shoulnt count but unfortunately they do. And in different contexts you need different invocations.
However IMO it shouldnt be convertible to anything. There needs to be some concept that it models. FWIW I would be content with , float, double long double. IOW numeric types. But ... eg FWIW my version still fails in boost::numeric::interval. This is always going to be the problem when trying to make one type maquerade as another :-(
FWIW, the constants I wrote only look as if they convert to anything. But in the end, you must have an implementation that yields the value. If there is no constant (or explicit mapper) for a type called "fluffy", the compiler complains. Static type checking should be preserved - and is. I tried to avoid magic that leads to surprises, as this immediatly leads to bugs in the real world.
Its tricky to assess this as it wont compile in VC7.1
A 'math constant' is expected to be pretty unexciting, which this doesnt deliver. Maybe if it was repackaged as say a quirky 'smart constant', rather than The std::math_constant it would be more gratefully received.
The constant itself is still simple: two. It should come from some header as well as all other constants you usually need. A normal user should not be concerned with defining constants. The best example is probably still:
template< typename Y > inline typename SI< Y >::quantity idealGasLaw( const typename SI< Y >::pressure& p, const typename SI< Y >::volume& v, const typename SI< Y >::temperature& t ) { using boost::units::si::constants::chemistry::R; return p * v / ( R * t ); }
The constant comes from a header, the user is not bothered with anything else at this point.
Sure the same thing can be done with 'units. Question is though Does the user think its weird? What happens when the user wants to say std::cout << R ; ? std::cout << R.get<double>(); // is not exactly elegant. If I have to go throught this.. why not make the useage consistent and just make the thing a function?
Whatever float-point-type (native or UDT) he uses for Y, the algorithm as well as the constant library itself will be unaffected. You can define algorithm libraries containing the above, unit libraries, constant libraries (that is libraries that yield the constants for a certain use-case, not the library that helps to define these constants (my lib)) and float-point-types independently. A user might need to add some glue to use certain combinations in his projects, although most things for float/double will work out-of-the-box. The most important point is, that the user should never be forced to reinvent the wheel, only assemble some stuff! This is what I consider reuseability.
Unfortunately I cant get this to compile in VC7.1 .
sure .. .... but of course it isnt doable in the language. (BTW the pi * pi stuff is cool !. Sorry... it appears I have been dismissive of that.)
int val = my::pow(9,3,2); eg replaces std::pow( static_cast<double>(9)
With my library, you can make pow(nine,three,two) a constant. Today. Given the ideas I have about constant_<9> nine; etc., this might even work for all integer numbers in the future, although I can't promise anything. If it works, you could also spell it sqrt(pow(nine,two)) or sqrt(nine*nine) - all leading to real constants :)
Yes ... but my_type / two is not as nice as my_type / 2, which is my point. regards Andy Little

There is a small correction I have to make to this code: BOOST_CONSTANTS was intended to be a "Named Parameter" (as defined in the Documentation of Boost.Preprocessor). Without the #undef it is easily misunderstood as "static data": Tobias Schwinger wrote:
[...]
#define BOOST_PP_FILENAME_1 "generate_constants.hpp" #include BOOST_PP_ITERATE()
#undef BOOST_CONSTANTS
//==============================================================================
#elif !defined(BOOST_CONSTANT_entry) // For each constant: //============================================================================== [...]
Regards, Tobias
participants (10)
-
Andy Little
-
Christoph Ludwig
-
Daniel Frey
-
Deane Yang
-
John Maddock
-
Kevin Lynch
-
Lassi A.Tuura
-
Liu Jin
-
Paul A Bristow
-
Tobias Schwinger