【问题标题】:Portable floating point variable templates可移植的浮点变量模板
【发布时间】:2015-07-29 08:22:21
【问题描述】:

如何在c++14中定义可移植的高精度浮点变量模板?下面的程序应该以doublelong double 精度打印 pi。

#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;
}

当我使用 GCC 5.1.0 g++ -std=c++14 编译时,我得到了

3.1415926535897931
3.141592653589793116

我的猜测是 gcc 将数字转换为双精度然后应用模板。我不认为 L 文字是答案,因为当我移动到 float128 或更高版本时我不想重写。如何让编译器保持所有精度?

【问题讨论】:

  • 便携镜腿?祭坛可能是个问题。
  • 它是可移植的,因为它是浮动的。 :)

标签: c++ gcc c++14


【解决方案1】:

所有浮点字面量,除非另有后缀,都是double 类型。将其用作T 的初始化器(无论T 可能是什么)都没有关系,您仍将使用转换为doubledouble 来初始化pi

在文字后面加上l,使其成为long double,然后转换为T

【讨论】:

  • 这不是破坏variable templates 的目的吗?他们在提案中使用 19 位数字,但根据您的说法,这完全是一种误导。对吗?
  • @Mankka 是的,它确实违背了目的,但另一方面,如果没有模板,它也无法工作,尝试声明一个普通的 long double 变量并类似地初始化它,它不会也不行。编译器可能能够知道文字应该是正确的类型,但规范说没有后缀的浮点文字是 double 类型,所以会发生这种情况。
  • @Mankka 他们已经注意到了这个问题并且added the L suffix in the draft standard
  • 感谢您的 cmets。我希望除了Boost constants之外还有其他方式。
猜你喜欢
  • 2012-05-24
  • 2014-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-01
  • 1970-01-01
相关资源
最近更新 更多