在 C++ 中对科学常量使用 double 是否安全?

Is it safe to use double for scientific constants in C++?

我想使用几个科学常数在 C++ 中进行一些计算,例如

  1. 有效电子质量(m) 9.109e-31 kg
  2. 电子电荷 1.602e-19 C
  3. 玻尔兹曼常数(k) 1.38×10−23
  4. 时间 8.92e-13

我有这样的计算,sqrt((2kT)/m)

对这些常量和结果使用 double 是否安全?

浮点运算和准确性是一个非常棘手的主题。绝对阅读 floating-point-gui.de 站点。

许多浮点运算的错误会累积到给出无意义结果的程度。因此发生了几起灾难性事件(生命损失,数十亿美元的崩溃)。未来会发生更多。

有一些静态source analyzers dedicated to detect them, for example Fluctuat (by my CEA colleagues, several now at Ecole Polytechnique, Palaiseau, France) and others. But Rice's theorem适用,因此静态分析问题一般无法解决。

(但浮点精度的静态分析有时 实际上 可以在几千个小型 程序上工作行,并且不能很好地扩展到大型程序)

还有一些程序用于计算,例如来自法国巴黎 LIP6 的 CADNA

(但仪器可能会给出一个巨大的过度近似误差)

您可以设计对浮点错误不太敏感的数值算法。这非常困难(您需要 years 的工作才能获得相关技能和专业知识)。

(你需要数值、数学和计算机科学技能,博士水平)

您也可以使用 arbitrary-precision arithmetic, or extended precision one (e.g. 128 bit floats or quad-precision)。这会减慢计算速度。

一个重要的考虑因素是您可以分配多少精力(时间和金钱)来查找浮点错误,以及它们对您的特定问题有多重要。但是有No Silver Bullet,浮点精度的问题仍然是一个非常困难的问题(你可以为它工作一辈子)。

PS。我不是浮点专家。我只是碰巧知道一些。

根据您给出的特定示例(常量 计算):YES

您没有在问题中定义 'safe'。我假设你想保持相同数量的正确有效数字

  • 双精度为 15 位有效数字
  • 您有 4 位有效数字的常量
  • 运算涉及使用乘法、除法和一个平方根
  • 您的结果似乎不会进入 双倍 的 'edge' 情况(对于非常小或大的指数值,尾数会失去精度)

在这个特定的顺序中,结果将正确到 4 位有效数字。


不过,在一般情况下,您必须小心。 (可能不是,这当然取决于您对 'safe' 的定义)。

这是一个庞大而复杂的课题。特别是,如果您有:

,您的结果可能不会正确显示相同数量的有效数字
  • 更多操作,
  • 如果你有相近的数字减法
  • 其他有问题的操作

必读:What Every Computer Scientist Should Know About Floating-Point Arithmetic

参见 的好答案以获取其他参考资料。

此外,对于复杂的计算,对问题的 Condition number 有一些概念是相关的。

如果您需要回答是或否,