1

How to define portable high-precision floating point variable templates in c++14? The program below should print pi with double and long double precision.

#include <iostream>
#include <iomanip>
#include <limits>

template<typename T>
constexpr T pi = T(3.141592653589793238462643383279502884197);


int main() {
  std::cout << std::setprecision(std::numeric_limits<double>::max_digits10) << pi<double> << std::endl;
  std::cout << std::setprecision(std::numeric_limits<long double>::max_digits10) << pi<long double> << std::endl;
}

When I compile with GCC 5.1.0 g++ -std=c++14 I get

3.1415926535897931
3.141592653589793116

My guess is that gcc converts the number to a double and then applies the template. I don't think the L literal is the answer because I don't want to rewrite when I move to float128 or higher. How can I make the compiler retain all the precision?

Mankka
  • 521
  • 3
  • 12

1 Answers1

4

All floating point literals, unless otherwise suffixed, are of type double. That you use it as an initializer for T (whatever T may be) doesn't matter, you're still going to initialize pi with a double converted to a T.

Suffix the literal with l to make it a long double, which is then converted to T.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Doesn't this defeat the purpose of the [variable templates](http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3651.pdf)? They use 19 digits in the proposal, but according to you, it's completely misleading. Right? – Mankka Jul 29 '15 at 09:44
  • 1
    @Mankka Yes it kind of does defeat the purpose, but on the other hand it doesn't work without templates either, try declaring an ordinary `long double` variable and initialize it similarly, and it won't work either. The compiler is probably capable of knowing that the literal should be of the correct type, but the specification says that floating point literals without suffix are of type `double` so that's what happens. – Some programmer dude Jul 29 '15 at 10:56
  • 2
    @Mankka They have noticed that problem and [added the `L` suffix in the draft standard](https://github.com/cplusplus/draft/commit/e17586537d43bd6916b93d07d9941f393964f4a6). – cpplearner Jul 29 '15 at 11:10
  • Thank you for your comments. I hoped there would have been another way than [Boost constants](http://www.boost.org/doc/libs/1_58_0/libs/math/doc/html/constants.html). – Mankka Jul 29 '15 at 11:19