| Home | Libraries | People | FAQ | More

## Math Constants FAQs

##### Why are these Constants Chosen?

It is, of course, impossible to please everyone with a list like this.

Some of the criteria we have used are:

- Used in Boost.Math.
- Commonly used.
- Expensive to compute.
- Requested by users.
- Used in science and mathematics.
- No integer values (because so cheap to construct).

(You can easily define your own if found convenient, for example: `FPT one =static_cast<FPT>(42);`).

##### How are constants named?

- Not macros, so no upper case.
- All lower case (following C++ standard names).
- No CamelCase.
- Underscore as _ delimiter between words.
- Numbers spelt as words rather than decimal digits (except following pow).
- Abbreviation conventions:
  - root for square root.
  - cbrt for cube root.
  - pow for pow function using decimal digits like pow23 for n2/3.
  - div for divided by or operator /.
  - minus for operator -, plus for operator +.
  - sqr for squared.
  - cubed for cubed n3.
  - words for greek, like π, ζ and Γ.
  - words like half, third, three_quarters, sixth for fractions. (Digit(s) can get muddled).
  - log10 for log10
  - ln for loge

##### How are the constants derived?

The constants have all been calculated using high-precision software working with up to 300-bit precision giving about 100 decimal digits. (The precision can be arbitrarily chosen and is limited only by compute time).

##### How Accurate are the constants?

The minimum accuracy chosen (100 decimal digits) exceeds the accuracy of reasonably-foreseeable floating-point hardware (256-bit) and should meet most high-precision computations.

##### How are the constants tested?

1. Comparison using Boost.Test BOOST_CHECK_CLOSE_FRACTION using long double literals, with at least 35 decimal digits, enough to be accurate for all long double implementations. The tolerance is usually twice `long double epsilon`.
2. Comparison with calculation at long double precision. This often requires a slightly higher tolerance than two epsilon because of computational noise from round-off etc, especially when trig and other functions are called.
3. Comparison with independent published values, for example, using The On-Line Encyclopedia of Integer Sequences (OEIS) again using at least 35 decimal digits strings.
4. Comparison with independently calculated values using arbitrary precision tools like Mathematica, again using at least 35 decimal digits literal strings.

| Warning
We have not yet been able to check that all constants are accurate at the full arbitrary precision, at present 100 decimal digits. But certain key values like `e` and `pi` appear to be accurate and internal consistencies suggest that others are this accurate too.

##### Why is Portability important?

Code written using math constants is easily portable even when using different floating-point types with differing precision.

It is a mistake to expect that results of computations will be identical, but you can achieve the best accuracy possible for the floating-point type in use.

This has no extra cost to the user, but reduces irritating, and often confusing and very hard-to-trace effects, caused by the intrinsically limited precision of floating-point calculations.

A harmless symptom of this limit is a spurious least-significant digit; at worst, slightly inaccurate constants sometimes cause iterating algorithms to diverge wildly because internal comparisons just fail.

##### What is the Internal Format of the constants, and why?

See tutorial above for normal use, but this FAQ explains the internal details used for the constants.

Constants are stored as 100 decimal digit values. However, some compilers do not accept decimal digits strings as long as this. So the constant is split into two parts, with the first containing at least 128-bit long double precision (35 decimal digits), and for consistency should be in scientific format with a signed exponent.

The second part is the value of the constant expressed as a string literal, accurate to at least 100 decimal digits (in practice that means at least 102 digits). Again for consistency use scientific format with a signed exponent.

For types with precision greater than a long double, then if T is constructible `T` is constructible from a `const char*` then it's directly constructed from the string, otherwise we fall back on lexical_cast to convert to type `T`. (Using a string is necessary because you can't use a numeric constant since even a `long double` might not have enough digits).

So, for example, a constant like pi is internally defined as

    BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884e+00, "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+00");

In this case the significand is 109 decimal digits, ensuring 100 decimal digits are exact, and exponent is zero.

See defining new constants to calculate new constants.

A macro definition like this can be pasted into user code where convenient, or into `boost/math/constants.hpp` if it is to be added to the Boost.Math library.

##### What Floating-point Types could I use?

Apart from the built-in floating-point types `float`, `double`, `long double`, there are several arbitrary precision floating-point classes available, but most are not licensed for commercial use.

###### Boost.Multiprecision by Christopher Kormanyos and John Maddock

This is a well-maintained and fully featured library which provides numerous high-precision types, as well as wrappers to other popular libraries like MPFR.

###### NTL class quad_float

NTL by Victor Shoup has fixed and arbitrary high precision fixed and floating-point types. However none of these are licenced for commercial use.

    #include <NTL/quad_float.h> // quad precision 106-bit, about 32 decimal digits.
    using NTL::to_quad_float; // Less precise than arbitrary precision NTL::RR.

NTL class `quad_float`, which gives a form of quadruple precision, 106-bit significand (but without an extended exponent range.) With an IEC559/IEEE 754 compatible processor, for example Intel X86 family, with 64-bit double, and 53-bit significand, using the significands of two 64-bit doubles, if `std::numeric_limits<double>::digits10` is 16, then we get about twice the precision, so `std::numeric_limits<quad_float>::digits10()` should be 32. (the default `std::numeric_limits<RR>::digits10()` should be about 40). (which seems to agree with experiments). We output constants (including some noisy bits, an approximation to `std::numeric_limits<RR>::max_digits10()`) by adding 2 or 3 extra decimal digits, so using `quad_float::SetOutputPrecision(32 + 3);`

Apple Mac/Darwin uses a similar doubledouble 106-bit for its built-in `long double` type.

| Note
The precision of all `doubledouble` floating-point types is rather odd and values given are only approximate.

New projects should use Boost.Multiprecision.

###### NTL class RR

Arbitrary precision floating point with NTL class RR, default is 150 bit (about 50 decimal digits) used here with 300 bit to output 100 decimal digits, enough for many practical non-'number-theoretic' C++ applications.

NTL A Library for doing Number Theory is not licenced for commercial use.

This class is used in Boost.Math and is an option when using big_number projects to calculate new math constants.

New projects should use Boost.Multiprecision.

###### GMP and MPFR

GMP and MPFR have also been used to compute constants, but are licensed under the Lesser GPL license and are not licensed for commercial use.

##### What happened to a previous collection of constants proposed for Boost?

A review concluded that the way in which the constants were presented did not meet many peoples needs. None of the methods proposed met many users' essential requirement to allow writing simply `pi` rather than `pi()`. Many science and engineering equations look difficult to read because function call brackets can be confused with the many other brackets often needed. All the methods then proposed of avoiding the brackets failed to meet all needs, often on grounds of complexity and lack of applicability to various realistic scenarios.

So the simple namespace method, proposed on its own, but rejected at the first review, has been added to allow users to have convenient access to `float`, `double` and `long double` values, but combined with template struct and functions to allow simultaneous use with other non-built-in floating-point types.

##### Why do the constants (internally) have a struct rather than a simple function?

A function mechanism was provided by in previous versions of Boost.Math.

The new mechanism is to permit partial specialization. See Custom Specializing a constant above. It should also allow use with other packages like ttmath Bignum C++ library.

##### Where can I find other high precision constants?

1. Constants with very high precision and good accuracy (>40 decimal digits) from Simon Plouffe's web based collection http://pi.lacim.uqam.ca/eng/.
2. The On-Line Encyclopedia of Integer Sequences (OEIS)
3. Checks using printed text optically scanned values and converted from: D. E. Knuth, Art of Computer Programming, Appendix A, Table 1, Vol 1, ISBN 0 201 89683 4 (1997)
4. M. Abrahamovitz & I. E. Stegun, National Bureau of Standards, Handbook of Mathematical Functions, a reference source for formulae now superseded by
5. Frank W. Olver, Daniel W. Lozier, Ronald F. Boisvert, Charles W. Clark, NIST Handbook of Mathematical Functions, Cambridge University Press, ISBN 978-0-521-14063-8, 2010.
6. John F Hart, Computer Approximations, Kreiger (1978) ISBN 0 88275 642 7.
7. Some values from Cephes Mathematical Library, Stephen L. Moshier and CALC100 100 decimal digit Complex Variable Calculator Program, a DOS utility.
8. Xavier Gourdon, Pascal Sebah, 50 decimal digits constants at Number, constants and computation.

##### Where are Physical Constants?

Not here, because physical constants:

- Are measurements, not truly constants.
- Are not truly constant and keeping changing as metrology improves.
- Have intrinsic uncertainty.
- Mathematical constants are stored and represented at varying precision, but should never be inaccurate.

Some physical constants may be available in Boost.Units.