Re: [PATCH] C++ math constants
Hi, On 03/01/2013 03:54 PM, Ulrich Drepper wrote: How about this patch then? As I said, I have code in need of constants lined up and Edward likely also wants to take advantage of them in some of his code. this seems straightforward enough to go in even at this late stage. Thanks, Paolo.
Re: [PATCH] C++ math constants
On 03/01/2013 05:15 AM, Ulrich Drepper wrote: On Thu, Feb 21, 2013 at 12:38 PM, Benjamin De Kosnik b...@redhat.com wrote: Not seeing it. Say for: #include iostream // A class for math constants. templatetypename _RealType struct __math_constants { // Constant @f$ \pi @f$. static constexpr _RealType __pie = 3.1415926535897932384626433832795029L; }; templateclass T void print(const T t) { std::cout t; } int main() { print(__math_constantsdouble::__pie); return 0; } I'm not getting any definition, even at -O0. Even more so: how would an explicit instantiation even work? You don't need an explicit instantiation, just a regular templated definition. This example shows that a definition is needed, and how one is provided. template class T struct a { static constexpr T m = T(1); }; template class T constexpr T aT::m; const int * f() { return aint::m; } int main() { return f() == 0; } -- Florian Weimer / Red Hat Product Security Team
Re: [PATCH] C++ math constants
How about this patch then? As I said, I have code in need of constants lined up and Edward likely also wants to take advantage of them in some of his code. Index: include/Makefile.am === --- include/Makefile.am (revision 196362) +++ include/Makefile.am (working copy) @@ -499,6 +499,7 @@ ${ext_srcdir}/array_allocator.h \ ${ext_srcdir}/bitmap_allocator.h \ ${ext_srcdir}/cast.h \ + ${ext_srcdir}/cmath \ ${ext_srcdir}/codecvt_specializations.h \ ${ext_srcdir}/concurrence.h \ ${ext_srcdir}/debug_allocator.h \ --- /dev/null 2013-02-06 19:11:05.441448320 -0500 +++ include/ext/cmath 2013-03-01 09:28:36.448535383 -0500 @@ -0,0 +1,152 @@ +// Math extensions -*- C++ -*- + +// Copyright (C) 2013 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// http://www.gnu.org/licenses/. + +/** @file ext/cmath + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _EXT_CMATH +#define _EXT_CMATH 1 + +#pragma GCC system_header + +#if __cplusplus 201103L +# include bits/c++0x_warning.h +#else + +#include cmath +#include type_traits + +namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // A class for math constants. + templatetypename _RealType +struct __math_constants +{ + static_assert(std::is_floating_point_RealType::value, +template argument not a floating point type); + + // Constant @f$ \pi @f$. + static constexpr _RealType __pi = 3.1415926535897932384626433832795029L; + // Constant @f$ \pi / 2 @f$. + static constexpr _RealType __pi_half = 1.5707963267948966192313216916397514L; + // Constant @f$ \pi / 3 @f$. + static constexpr _RealType __pi_third = 1.0471975511965977461542144610931676L; + // Constant @f$ \pi / 4 @f$. + static constexpr _RealType __pi_quarter = 0.7853981633974483096156608458198757L; + // Constant @f$ \sqrt(\pi / 2) @f$. + static constexpr _RealType __root_pi_div_2 = 1.2533141373155002512078826424055226L; + // Constant @f$ 1 / \pi @f$. + static constexpr _RealType __one_div_pi = 0.3183098861837906715377675267450287L; + // Constant @f$ 2 / \pi @f$. + static constexpr _RealType __two_div_pi = 0.6366197723675813430755350534900574L; + // Constant @f$ 2 / \sqrt(\pi) @f$. + static constexpr _RealType __two_div_root_pi = 1.1283791670955125738961589031215452L; + + // Constant Euler's number @f$ e @f$. + static constexpr _RealType __e = 2.7182818284590452353602874713526625L; + // Constant @f$ 1 / e @f$. + static constexpr _RealType __one_div_e = 0.36787944117144232159552377016146087L; + // Constant @f$ \log_2(e) @f$. + static constexpr _RealType __log2_e = 1.4426950408889634073599246810018921L; + // Constant @f$ \log_10(e) @f$. + static constexpr _RealType __log10_e = 0.4342944819032518276511289189166051L; + // Constant @f$ \ln(2) @f$. + static constexpr _RealType __ln_2 = 0.6931471805599453094172321214581766L; + // Constant @f$ \ln(3) @f$. + static constexpr _RealType __ln_3 = 1.0986122886681096913952452369225257L; + // Constant @f$ \ln(10) @f$. + static constexpr _RealType __ln_10 = 2.3025850929940456840179914546843642L; + + // Constant Euler-Mascheroni @f$ \gamma_E @f$. + static constexpr _RealType __gamma_e = 0.5772156649015328606065120900824024L; + // Constant Golden Ratio @f$ \phi @f$. + static constexpr _RealType __phi = 1.6180339887498948482045868343656381L; + + // Constant @f$ \sqrt(2) @f$. + static constexpr _RealType __root_2 = 1.4142135623730950488016887242096981L; + // Constant @f$ \sqrt(3) @f$. + static constexpr _RealType __root_3 = 1.7320508075688772935274463415058724L; + // Constant @f$ \sqrt(5) @f$. + static constexpr _RealType __root_5 = 2.2360679774997896964091736687312762L; + // Constant @f$ \sqrt(7) @f$. + static constexpr _RealType __root_7 = 2.6457513110645905905016157536392604L; + // Constant @f$
Re: [PATCH] C++ math constants
On Thu, Feb 21, 2013 at 12:38 PM, Benjamin De Kosnik b...@redhat.com wrote: Not seeing it. Say for: #include iostream // A class for math constants. templatetypename _RealType struct __math_constants { // Constant @f$ \pi @f$. static constexpr _RealType __pie = 3.1415926535897932384626433832795029L; }; templateclass T void print(const T t) { std::cout t; } int main() { print(__math_constantsdouble::__pie); return 0; } I'm not getting any definition, even at -O0. Even more so: how would an explicit instantiation even work? Try this simplified code: templatetypename T struct a { static constexpr T m = T(1); }; If you try template constexpr int a::mint; nothing gets emitted into the object file (this is even with the trunk gcc). If I use template constexpr int a::mint = 1; I get a definition but I have to remove the initialization in the class definition itself. If I use struct template aint; there is no output in the file as well. All this makes perfect sense with gcc. Since the constant will never be referenced as a variable there is no need for the compiler to emit a definition. If the argument is that there has to be one, how would it be done?
[PATCH] C++ math constants
How about the attached file as a start for ext/math. I used the constexpr approach (instead of function calls) and replicated the constants that are available in math.h in Unix. What other constants to add? math Description: Binary data
Re: [PATCH] C++ math constants
2013/2/21 Ulrich Drepper drep...@gmail.com: How about the attached file as a start for ext/math. I used the constexpr approach (instead of function calls) and replicated the constants that are available in math.h in Unix. 1) In this case I miss the corresponding variable definitions, because you violate the ODR, when you have something like the following: #include iostream templateclass T void print(const T t) { std::cout t; } int main() { print(__math_constantsdouble::__pi); } 2) You need to use either braced initializers *or* using initializers with equal, a parenthesized initializer isn't supported (/brace-or-equal-initializer/). - Daniel
Re: [PATCH] C++ math constants
On 21/02/13 16:32, Ulrich Drepper wrote: How about the attached file as a start for ext/math. I used the constexpr approach (instead of function calls) and replicated the constants that are available in math.h in Unix. What other constants to add? Pi/3 ln(3) ln(10) (for base conversions) sqrt(3) sqrt(5) sqrt(7) 1/e I'll write down what I use in my day to day stuff, keep you posted.
Re: [PATCH] C++ math constants
How about the attached file as a start for ext/math. I used the constexpr approach (instead of function calls) and replicated the constants that are available in math.h in Unix. then this should really be ext/cmath 1) In this case I miss the corresponding variable definitions, because you violate the ODR, when you have something like the following: #include iostream templateclass T void print(const T t) { std::cout t; } int main() { print(__math_constantsdouble::__pi); } Not seeing it. Say for: #include iostream // A class for math constants. templatetypename _RealType struct __math_constants { // Constant @f$ \pi @f$. static constexpr _RealType __pie = 3.1415926535897932384626433832795029L; }; templateclass T void print(const T t) { std::cout t; } int main() { print(__math_constantsdouble::__pie); return 0; } I'm not getting any definition, even at -O0. Any chance you could expand on your thinking here Daniel? 2) You need to use either braced initializers *or* using initializers with equal, a parenthesized initializer isn't supported (/brace-or-equal-initializer/). Yeah. This works: // Constant @f$ \pi @f$. static constexpr _RealType __pie = 3.1415926535897932384626433832795029L; -benjamin
Re: Re: [PATCH] C++ math constants
On 02/21/13, Alec Teala.t...@warwick.ac.uk wrote: On 21/02/13 16:32, Ulrich Drepper wrote: How about the attached file as a start for ext/math. I used the constexpr approach (instead of function calls) and replicated the constants that are available in math.h in Unix. What other constants to add? Pi/3 ln(3) ln(10) (for base conversions) sqrt(3) sqrt(5) sqrt(7) 1/e I'll write down what I use in my day to day stuff, keep you posted. I use the Euler constant a *lot* in special functions. Also, I use the golden ratio to size dialog boxes in GUI work. // Constant @f$ @f$. static constexpr _RealType __pi_third(1.0471975511965977461542144610931676L); // Constant @f$ \gamma_E @f$. static constexpr _RealType __gamma_e(0.5772156649015328606065120900824024L); // Constant @f$ \phi = (1 + \sqrt(5))/2 @f$. static constexpr _RealType __golden_ratio(1.6180339887498948482045868343656381L);
Re: [PATCH] C++ math constants
On Thu, 2013-02-21 at 17:14 +, Alec Teal wrote: On 21/02/13 16:32, Ulrich Drepper wrote: How about the attached file as a start for ext/math. I used the constexpr approach (instead of function calls) and replicated the constants that are available in math.h in Unix. What other constants to add? Pi/3 1/e I'm wondering, why adding constants for these if the compiler can figure it out from e.g. math::pi/3 (or whatever the namespace is)? ln(3) ln(10) (for base conversions) sqrt(3) sqrt(5) sqrt(7) Aren't these evaluated by the compiler and converted to constants? Cheers, Oleg
Re: [PATCH] C++ math constants
On Thu, Feb 21, 2013 at 08:06:02PM +0100, Oleg Endo wrote: On Thu, 2013-02-21 at 17:14 +, Alec Teal wrote: On 21/02/13 16:32, Ulrich Drepper wrote: How about the attached file as a start for ext/math. I used the constexpr approach (instead of function calls) and replicated the constants that are available in math.h in Unix. What other constants to add? Pi/3 1/e I'm wondering, why adding constants for these if the compiler can figure it out from e.g. math::pi/3 (or whatever the namespace is)? It can't, you generally want to avoid double rounding for these, first rounding infinite precision pi to the corresponding floating point format and then performing in that finite precision division by 3 (and rounding again to that precision) might very well give different results from dividing infinite precision pi by 3 and only then rounding the result to the corresponding precision. Haven't tried it, so you might be lucky and in some of float, double or long double it might be equal. ln(3) ln(10) (for base conversions) sqrt(3) sqrt(5) sqrt(7) Aren't these evaluated by the compiler and converted to constants? Only if optimizing. Furthermore, I don't think std::sqrt etc. are constexpr, therefore you can't use them to initialize constexpr vars or in constexpr functions. Jakub
Re: [PATCH] C++ math constants
2013/2/21 Benjamin De Kosnik b...@redhat.com: How about the attached file as a start for ext/math. I used the constexpr approach (instead of function calls) and replicated the constants that are available in math.h in Unix. then this should really be ext/cmath 1) In this case I miss the corresponding variable definitions, because you violate the ODR, when you have something like the following: #include iostream templateclass T void print(const T t) { std::cout t; } int main() { print(__math_constantsdouble::__pi); } Not seeing it. An implementation is not required to diagnose it. You will notice a linker error with Clang for example and this is conforming, because __math_constantsdouble::__pi is ODR-used. Say for: #include iostream // A class for math constants. templatetypename _RealType struct __math_constants { // Constant @f$ \pi @f$. static constexpr _RealType __pie = 3.1415926535897932384626433832795029L; }; templateclass T void print(const T t) { std::cout t; } int main() { print(__math_constantsdouble::__pie); return 0; } I'm not getting any definition, even at -O0. Any chance you could expand on your thinking here Daniel? No ;-) - Daniel
Re: [PATCH] C++ math constants
On Thu, Feb 21, 2013 at 4:18 PM, Daniel Krügler daniel.krueg...@gmail.com wrote: 2013/2/21 Benjamin De Kosnik b...@redhat.com: How about the attached file as a start for ext/math. I used the constexpr approach (instead of function calls) and replicated the constants that are available in math.h in Unix. then this should really be ext/cmath 1) In this case I miss the corresponding variable definitions, because you violate the ODR, when you have something like the following: #include iostream templateclass T void print(const T t) { std::cout t; } int main() { print(__math_constantsdouble::__pi); } Not seeing it. An implementation is not required to diagnose it. You will notice a linker error with Clang for example and this is conforming, because __math_constantsdouble::__pi is ODR-used. Say for: #include iostream // A class for math constants. templatetypename _RealType struct __math_constants { // Constant @f$ \pi @f$. static constexpr _RealType __pie = 3.1415926535897932384626433832795029L; }; templateclass T void print(const T t) { std::cout t; } int main() { print(__math_constantsdouble::__pie); return 0; } I'm not getting any definition, even at -O0. Any chance you could expand on your thinking here Daniel? No ;-) - Daniel There will be a proposal for 'constexpr variable template' in the Bristol mailing. It should take care of these issues. -- Gaby