Re: [boost] Re: Re: Math Constants Formal Review
>From: "Daniel Frey" <[EMAIL PROTECTED]> > On Sun, 22 Jun 2003 22:01:19 +0200, Terje Slettebø wrote: > > > > Another thing, are the ADD_OPERATOR macro in your code necessary? It > > compiles fine without it on Intel C++ 7.1. > > The GCC doesn't work without the operators, as it doesn't implicitly tries > to satisfy float*pi_t by casting pi_t to float to use float*float. I > think this is OK as the language can go for two ways: > > a) define float*float and use a promotion/conversion for, say, float*int. > b) define several operators float*float, float*int, ... > > if it's b), the compiler cannot cast pi_t to float as it doesn't know > whether to select float*float or float*int, thus it fails. Maybe a > question for the language lawyers over at csc++ to find out what's > correct. It's an odd thing, anyway. Both g++ 3.2 and MSVC 7.1 complains that there's no matching operator*. > >> Also, I'm not sure whether it's standard compliant code. > > > > I think it is. It specialises a member. What could be the problem with > > this? As you say, errors are caught at link time. > > I think that you have to declare the specialization in the class' > definition, not just outside. But I may be wrong here and I haven't > checked it. I don't think so. I tried that, and it gave the error: "error: explicit specialization is not allowed in the current scope" Regards, Terje ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Math Constants Formal Review
On Sun, 22 Jun 2003 22:01:19 +0200, Terje Slettebø wrote: > Ok. So maybe an extra level of indirection, as in your code (and > Kenniston's) may be preferable. I was wondering what was the point with > it. :) > > Another thing, are the ADD_OPERATOR macro in your code necessary? It > compiles fine without it on Intel C++ 7.1. The GCC doesn't work without the operators, as it doesn't implicitly tries to satisfy float*pi_t by casting pi_t to float to use float*float. I think this is OK as the language can go for two ways: a) define float*float and use a promotion/conversion for, say, float*int. b) define several operators float*float, float*int, ... if it's b), the compiler cannot cast pi_t to float as it doesn't know whether to select float*float or float*int, thus it fails. Maybe a question for the language lawyers over at csc++ to find out what's correct. >> Also, I'm not sure whether it's standard compliant code. > > I think it is. It specialises a member. What could be the problem with > this? As you say, errors are caught at link time. I think that you have to declare the specialization in the class' definition, not just outside. But I may be wrong here and I haven't checked it. Note I didn't say it's illegal, just that *I* am not sure it's legal ;) Regards, Daniel ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] Re: Re: Math Constants Formal Review - usingnamespacestoselectfloat size is simpler?
| -Original Message- | From: [EMAIL PROTECTED] | [mailto:[EMAIL PROTECTED] On Behalf Of Ken Hagan | Sent: 20 June 2003 11:27 | To: [EMAIL PROTECTED] | Subject: [boost] Re: Re: Math Constants Formal Review - | using namespacestoselectfloat size is simpler? | | Paul A Bristow wrote: | > This scheme may offer more surprises to the many naive | users (like me) | > than an explicit (and convenient 'global') choice, for example: | > | > using boost::math::double_constants; | > | > to ensure that the expected size is used. | > | > One can make the compiler warn you about size conversions, | whereas I | > have the impression that these rules will mean that you | won't get any | > warnings. | | AFAICT, you will either get exactly the type that the | context requires, or a diagnostic from the compiler saying | that it is ambiguous. (This assumes that a selection of | possible types are available for each | constant.) I don't think it is possible to get a quiet conversion. | | In contrast, "using boost::math::double_constants" does | allow you to get an implicit size conversion, where the | context requires one. Compilers will warn, but only if users | haven't disabled the warning. | | So, with the "clever" approach, all users will find | themselves writing a few explicit conversions to avoid | ambiguities. With the "simple" approach, only users who have | their warning level right up will need to write explicit | conversions, and then only to silence the compiler. | | Listening to compiler warnings is something the community | might want to encourage (so the simple approach would then | have no advantages), but it isn't the job of a language | standard to mandate "good" programming practices. (In the | absence of such constraints, the definition of "good" tends | to change with time.) I am grateful for this reassurance that conversions not expected, though I hope the compiler writers know the rules - as Michael Caine would have said "Not a lot of people know that" :-) Thanks too for your accurate summing up of pros and cons. My slight preference for the 'simple' approach perhaps came from always setting the compiler to warn about conversions and carefully 'casting them all away'. Alas Microsoft have not chosen this as their default and it is not obvious how to ensure that all files are compiled with the right warning option. (After getting some helpful hints, I previously posted guidance on how to modify common.js to achieve this). But I am persuaded that the 'casting' method is OK. Paul ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: Math Constants Formal Review - using namespacestoselectfloat size is simpler?
Paul A Bristow wrote: > This scheme may offer more surprises to the many naive users (like me) > than an explicit (and convenient 'global') choice, for example: > > using boost::math::double_constants; > > to ensure that the expected size is used. > > One can make the compiler warn you about size conversions, > whereas I have the impression that these rules will mean > that you won't get any warnings. AFAICT, you will either get exactly the type that the context requires, or a diagnostic from the compiler saying that it is ambiguous. (This assumes that a selection of possible types are available for each constant.) I don't think it is possible to get a quiet conversion. In contrast, "using boost::math::double_constants" does allow you to get an implicit size conversion, where the context requires one. Compilers will warn, but only if users haven't disabled the warning. So, with the "clever" approach, all users will find themselves writing a few explicit conversions to avoid ambiguities. With the "simple" approach, only users who have their warning level right up will need to write explicit conversions, and then only to silence the compiler. Listening to compiler warnings is something the community might want to encourage (so the simple approach would then have no advantages), but it isn't the job of a language standard to mandate "good" programming practices. (In the absence of such constraints, the definition of "good" tends to change with time.) ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] RE: Re: Math Constants Formal Review - ()s are a keyissue.
In previous discussions, the main issues debated were: 1 Control of precision is essential, and some users wanted to be able to use float, double and long double at the same time. 2 Avoiding paying for what you don't use, which leads to 2a MACROS provide a simple way of avoiding some cost for constants you don't use, (Although some Boosters were opposed to MACROs because they pollute the global namespace). So, even if other presentations are provided, I strongly believe macros should be published. If you don't like them, don't use them! 2b Splitting the constants into several groups of files: essential, common, esoteric... 3 Efficiency Some compilers can generate better code from functions like "double pi() { return 3.1459;}" but that this implies writing "pi()" instead of plain "pi". 4 Appearance BUT Users extremely strongly prefer to write "float area = pi * r * r;" So the ()s remain a MAJOR issue. Michael Kenniston produced a 'presentation' which allows 'novice' users to write "pi" but get the effect of "pi()" without too many precision surprises. Yet it still allows the 'expert' to write "pi()" and control precision explicitly. I see nothing wrong with your suggestions and examples, but I don't yet understand how your proposal helps to meet this last 'requirement'. Paul Paul A Bristow, Prizet Farmhouse, Kendal, Cumbria LA8 8AB UK +44 1539 561830 [EMAIL PROTECTED] | -Original Message- | From: [EMAIL PROTECTED] | [mailto:[EMAIL PROTECTED] On Behalf Of Daniel Frey | Sent: 14 June 2003 20:48 | To: [EMAIL PROTECTED] | Subject: [boost] RE: Re: Math Constants Formal Review - is | extensible. | | | On Wed, 11 Jun 2003 15:49:05 +0200, Paul A. Bristow wrote: | | > The proposal is for several header files each containing the same | > constants, only one of which would be used for any | compilation. (Users | > have been warned against using more than one! Nobody has | suggested a | > way to guard against this mistake, but I think that it would be | > apparent pretty soon, probably at compile time, and at | link time if | > not.) The macros constants header is the simplest and | could be used | > to provide the appropiate value(s) above. | | The difference IMHO is, that this is not a generic approach. | It's a bit like replacing templates with macros. I haven't | seen any convincing arguments against the code I showed, | which *is* generic IMHO, but as I don't have the background | of the "long saga" you mentioned, I think I'm not the right | one to say what's the best way to go. | | Regards, Daniel | | ___ | Unsubscribe & other changes: | http://lists.boost.org/mailman/listinfo.cgi/b| oost | | ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] RE: Re: Math Constants Formal Review - is extensible.
I understand that this is not normal, but in this case there is a lot of work to do to create the files and I am reluctant to do this if the result is not ultimately going to be accepted. So I'd prefer agreement in principle first to the way of presenting the constants, and to the actual constants, their names and their values in the C macro files. There has already been much dicussion of all these items, but until the MSVC 7.1 compiler was out, the Kenniston presentation format was only sensible on other compilers. Now this has proved to be workable and efficient, it seemed timely to re-review the issue. Paul | I'm a bit surprised, that we currently are reviewing some | ideas instead of a library as far as I understood. | | Regards, | Joerg Paul A Bristow, Prizet Farmhouse, Kendal, Cumbria LA8 8AB UK +44 1539 561830 [EMAIL PROTECTED] ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] RE: Re: Math Constants Formal Review - is extensible.
- Original Message - From: "Daniel Frey" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Saturday, June 14, 2003 9:47 PM Subject: [boost] RE: Re: Math Constants Formal Review - is extensible. > On Wed, 11 Jun 2003 15:49:05 +0200, Paul A. Bristow wrote: > > > The proposal is for several header files each containing the same > > constants, only one of which would be used for any compilation. (Users > > have been warned against using more than one! Nobody has suggested a way > > to guard against this mistake, but I think that it would be apparent > > pretty soon, probably at compile time, and at link time if not.) The > > macros constants header is the simplest and could be used to provide the > > appropiate value(s) above. > > The difference IMHO is, that this is not a generic approach. During my last discussion with Paul I realized that math_constants<> probably isn't the same as numeric_limits<> (nevertheless I'd try to write them based upon the supplied constants ;-). > It's a bit > like replacing templates with macros. I haven't seen any convincing > arguments against the code I showed, which *is* generic I like that code. > IMHO, but as I > don't have the background of the "long saga" you mentioned, I think I'm > not the right one to say what's the best way to go. I'm a bit surprised, that we currently are reviewing some ideas instead of a library as far as I understood. Regards, Joerg ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] RE: Re: Math Constants Formal Review - is extensible.
On Wed, 11 Jun 2003 15:49:05 +0200, Paul A. Bristow wrote: > The proposal is for several header files each containing the same > constants, only one of which would be used for any compilation. (Users > have been warned against using more than one! Nobody has suggested a way > to guard against this mistake, but I think that it would be apparent > pretty soon, probably at compile time, and at link time if not.) The > macros constants header is the simplest and could be used to provide the > appropiate value(s) above. The difference IMHO is, that this is not a generic approach. It's a bit like replacing templates with macros. I haven't seen any convincing arguments against the code I showed, which *is* generic IMHO, but as I don't have the background of the "long saga" you mentioned, I think I'm not the right one to say what's the best way to go. Regards, Daniel ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] RE: RE: Math Constants Formal Review - is extensible.
Sorry I have misunderstood your wish - for existing constants in different types rather than new constants in existing types. Your example is interesting. I think that providing a Macro value allows this sort of UDT extensions code (very like Michael Kenniston's examples). My thesis that 40 decimal digits are enough is because it is enough for all existing floating point hardware, up to 128 significands. I believe that anyone wanting more is likely to be using a separate 'unlimited' precision package anyway. There is also an example of a UDT _interval_ - a 128-bit quad_float type, used by Victor Shoup's NTL package. But it does require using the NTL generator program to create the exactly representable values. (See test_quad_float.cpp example). I believe that interval constants are an important feature - and quite novel. Paul Paul A Bristow, Prizet Farmhouse, Kendal, Cumbria, LA8 8AB UK +44 1539 561830 Mobile +44 7714 33 02 04 Mobile mailto:[EMAIL PROTECTED] mailto:[EMAIL PROTECTED] | -Original Message- | From: [EMAIL PROTECTED] | [mailto:[EMAIL PROTECTED] Behalf Of Daniel Frey | Sent: Sunday, June 08, 2003 9:54 PM | To: [EMAIL PROTECTED] | Subject: [boost] RE: RE: Math Constants Formal Review - is extensible. | | | On Sun, 08 Jun 2003 16:56:53 +0200, Paul A Bristow wrote: | | > You can seen an example of extending to a 'new' constant 'gamma' in the | > examples testFunctionConstants/gamma_function_constants.hpp. | | Either I don't understand the example or we are talking past each other. I | don't meant to extend the framework with new constants, but with | definitions of existing constants for new types. Maybe the attached | example of a small experiment of mine clarifies what I was thinking about. | Look at the "Roguewave"-extension for pi. If I imagine to use | "boost/math_constants.hpp" in the company I work, it would be encapsulated | into another header "base/math_constants.h" and it would provide all | constants for Roguewawve's decimal type, too. I already used the | lambda-library and tought it about the decimal type, which worked very | smooth and I was really happy to see that the library designers didn't | limited it to build-in types. A key-feature for me! | | > defining the constant as a 40 decimal digit string. | | Roguewave's types can be used with precisions up to 1024 bits - probably | more. I don't think that a one-size-fits-all approach can work in the area | of numeric computations. | | > If Boosters agree that this scheme is an acceptable way to go, the the | > example and guidance could be made more helpful to provide the | > encouragement you rightly say is needed. | > | > But first the overall strategy needs agreement. | | Indeed. So if I still missed that the constants can be provided by the | user for their types, please let me know. Otherwise, we should find a | consensus whether such a feature is needed. I personally think it is, but | if the majority thinks it's not that important... :) | | Note that the attached file is not meant to offend you in any way. It way | just a toy example and maybe you can take some ideas out of it. It's not | meant to replace your code as I think you have put a lot of ideas in it | and provide features I don't even know of :) | | Regards, Daniel | | --- | | #include | using namespace std; | | namespace math | { | // Generic base class for all constants | template< typename T, template< class > class F > struct constant | { | // A cast-to-anything-operator :) | template< typename U > operator U() const { return F< U >()(); } | | #define ADD_OPERATOR( OP ) \ | template< typename U > friend U operator OP( const T& lhs, | const U& rhs ) \ | { U nrv( static_cast< U >( lhs ) ); nrv OP##= rhs; return nrv; } \ | template< typename U > friend U operator OP( const U& lhs, | const T& rhs ) \ | { U nrv( lhs ); nrv OP##= static_cast< U >( rhs ); return nrv; } | | ADD_OPERATOR( + ); | ADD_OPERATOR( - ); | ADD_OPERATOR( * ); | ADD_OPERATOR( / ); | #undef ADD_OPERATOR | }; | | // Here's the definition for pi for all types (can be extended by UDTs): | template< typename T > struct pi_value; | template<> struct pi_value< float > { float operator()() const { | return 3.14; } }; | template<> struct pi_value< double > { double operator()() const | { return 3.1416; } }; | template<> struct pi_value< long double > { long double | operator()() const { return 3.1415927; } }; | | /* | // For expensive constructions, maybe this is an option: | template<> struct pi_value< RWDecimal< RWMP3Int > > { | const RWDecimal< RWMP3Int >& operator()
RE: [boost] Re: RE: Math Constants Formal Review - recap & summary
| -Original Message- | From: [EMAIL PROTECTED] | [mailto:[EMAIL PROTECTED] Behalf Of Ed Brey | Sent: Monday, June 09, 2003 2:57 PM | To: [EMAIL PROTECTED] | Subject: [boost] Re: RE: Math Constants Formal Review - recap & summary | | | Paul A Bristow wrote: | > A Mini-recapitulation of the _long_ saga so far: | > | > 7 There are dozens of constants that some users rate 'essential'. | > Splitting into several #include files still risks violating the | > "don't pay for what you don't use" principle. | | > 10 There is evidence that some compilers can generate better code | > from functions like "double pi() { return 3.1459;}" | > but that this implies writing pi() instead of plain "long double pi". | > So the ()s remain a major issue. | | These two points are based on observations that compilers don't | optimally handle constants defined like this: | | double const d1 = 1.2; | | It would be useful to record exactly which compilers have which | troubles, so that as compilers improve, constraints can be dropped. | | For example, VC 7.1 discards d1 if it is not referenced, so there is | no issue with paying for what you don't use when using that method on | that compiler. This is good news. What optimisation did you chose? | It would be useful to know what compilers do retain | unused constants. But is tiresome to find out, and will keep changing. (and if the scheme becomes widely used, compiler writers will have a strong incentive to make sure it is optimised away. | The FAQ entry "Why are functions like double pi() which return | constants provided?" has a start to the idea of documenting specific | compiler limitations. I'd recommend adding this elaboration on VC 7 | (others can help with other compilers): | | - Static constants are referenced via a pointer, which leads to | smaller code if the constant is used more than once, but often to slower code. | | (I would take out the blurb about MSVC 7 Standard edition. Does | anyone who needs to professional-grade execution speed really buy the | standard, rather than professional edition? The professional edition | inlines properly according to the standard-specified "inline" keyword hint.) Agreed. I think this problem looks likely to go away, as I hoped - which is why I waited until 7.1 before this review. Paul ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: RE: Math Constants Formal Review - recap & summary
Paul A Bristow wrote: > A Mini-recapitulation of the _long_ saga so far: > > 7 There are dozens of constants that some users rate 'essential'. > Splitting into several #include files still risks violating the > "don't pay for what you don't use" principle. > 10 There is evidence that some compilers can generate better code > from functions like "double pi() { return 3.1459;}" > but that this implies writing pi() instead of plain "long double pi". > So the ()s remain a major issue. These two points are based on observations that compilers don't optimally handle constants defined like this: double const d1 = 1.2; It would be useful to record exactly which compilers have which troubles, so that as compilers improve, constraints can be dropped. For example, VC 7.1 discards d1 if it is not referenced, so there is no issue with paying for what you don't use when using that method on that compiler. It would be useful to know what compilers do retain unused constants. The FAQ entry "Why are functions like double pi() which return constants provided?" has a start to the idea of documenting specific compiler limitations. I'd recommend adding this elaboration on VC 7 (others can help with other compilers): - Static constants are referenced via a pointer, which leads to smaller code if the constant is used more than once, but often to slower code. (I would take out the blurb about MSVC 7 Standard edition. Does anyone who needs to professional-grade execution speed really buy the standard, rather than professional edition? The professional edition inlines properly according to the standard-specified "inline" keyword hint.) ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] RE: RE: Math Constants Formal Review - is extensible.
On Sun, 08 Jun 2003 16:56:53 +0200, Paul A Bristow wrote: > You can seen an example of extending to a 'new' constant 'gamma' in the > examples testFunctionConstants/gamma_function_constants.hpp. Either I don't understand the example or we are talking past each other. I don't meant to extend the framework with new constants, but with definitions of existing constants for new types. Maybe the attached example of a small experiment of mine clarifies what I was thinking about. Look at the "Roguewave"-extension for pi. If I imagine to use "boost/math_constants.hpp" in the company I work, it would be encapsulated into another header "base/math_constants.h" and it would provide all constants for Roguewawve's decimal type, too. I already used the lambda-library and tought it about the decimal type, which worked very smooth and I was really happy to see that the library designers didn't limited it to build-in types. A key-feature for me! > defining the constant as a 40 decimal digit string. Roguewave's types can be used with precisions up to 1024 bits - probably more. I don't think that a one-size-fits-all approach can work in the area of numeric computations. > If Boosters agree that this scheme is an acceptable way to go, the the > example and guidance could be made more helpful to provide the > encouragement you rightly say is needed. > > But first the overall strategy needs agreement. Indeed. So if I still missed that the constants can be provided by the user for their types, please let me know. Otherwise, we should find a consensus whether such a feature is needed. I personally think it is, but if the majority thinks it's not that important... :) Note that the attached file is not meant to offend you in any way. It way just a toy example and maybe you can take some ideas out of it. It's not meant to replace your code as I think you have put a lot of ideas in it and provide features I don't even know of :) Regards, Daniel --- #include using namespace std; namespace math { // Generic base class for all constants template< typename T, template< class > class F > struct constant { // A cast-to-anything-operator :) template< typename U > operator U() const { return F< U >()(); } #define ADD_OPERATOR( OP ) \ template< typename U > friend U operator OP( const T& lhs, const U& rhs ) \ { U nrv( static_cast< U >( lhs ) ); nrv OP##= rhs; return nrv; } \ template< typename U > friend U operator OP( const U& lhs, const T& rhs ) \ { U nrv( lhs ); nrv OP##= static_cast< U >( rhs ); return nrv; } ADD_OPERATOR( + ); ADD_OPERATOR( - ); ADD_OPERATOR( * ); ADD_OPERATOR( / ); #undef ADD_OPERATOR }; // Here's the definition for pi for all types (can be extended by UDTs): template< typename T > struct pi_value; template<> struct pi_value< float > { float operator()() const { return 3.14; } }; template<> struct pi_value< double > { double operator()() const { return 3.1416; } }; template<> struct pi_value< long double > { long double operator()() const { return 3.1415927; } }; /* // For expensive constructions, maybe this is an option: template<> struct pi_value< RWDecimal< RWMP3Int > > { const RWDecimal< RWMP3Int >& operator()() const { static const RWDecimal< RWMP3Int > value( "3.1415926535897932384626433832" ); return value; } }; */ // Here's the single line to create a useful interface struct pi_t : constant< pi_t, pi_value > {} pi; // Another one: template< typename T > struct pi2_value; template<> struct pi2_value< float > { float operator()() const { return 9.87; } }; template<> struct pi2_value< double > { double operator()() const { return 9.8696; } }; template<> struct pi2_value< long double > { long double operator()() const { return 9.8696044; } }; struct pi2_t : constant< pi2_t, pi2_value > {} pi2; // And their relationship: pi2_t operator*( const pi_t&, const pi_t& ) { return pi2_t(); } // Some obvious (?) constants: #define CONSTANT_VALUE( name, value ) \ template< typename T > struct name##_value { T operator()() const { return value; } }; \ struct name##_t : constant< name##_t, name##_value > {} name; CONSTANT_VALUE( minus_one, -1 ); CONSTANT_VALUE( zero, 0 ); CONSTANT_VALUE( one, 1 ); CONSTANT_VALUE( two, 2 ); CONSTANT_VALUE( three, 3 ); CONSTANT_VALUE( ten, 10 ); #undef CONSTANT_VALUE minus_one_t operator-( const one_t& ) { return minus_one_t(); } one_t operator-( const minus_one_t& ) { return one_t(); } zero_t operator-( const zero_t& ) { return zero_t(); } // Another one: template< typename T > struct half_pi_value; template<> struct half_pi_value< float > { float operator()() const { return 1.57; } }; template<> struct half_pi_value< double > { double operator()() const { return 1.5708; } }; template<>