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

Sam*_*a K 2 c++ floating-accuracy

我想用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是否安全?

Bas*_*tch 7

浮点运算和精度是一个非常棘手的主题.绝对阅读floating-point-gui.de网站.

许多浮点运算的错误可能会累积到无意义的结果.由此发生了几起灾难性事件(生命损失,数十亿美元的崩溃).将来会发生更多.

有一些静态源分析仪专门用于检测它们,例如Fluctuat(我的CEA同事,现在法国Palaiseau的Ecole Polytechnique的几个)和其他人.但Rice的定理适用于静态分析问题一般无法解决.

(但浮点精度的静态分析有时几乎可以用于几千行的一些程序,并且不能很好地扩展到大型程序)

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

(但是仪表可能会给出错误的过高估计)

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

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

您还可以使用任意精度算术或扩展精度算法(例如128位浮点数或四精度).这会减慢计算速度.

一个重要的考虑因素是您可以分配多少精力(时间和金钱)来捕获浮点错误,以及它们对您的特定问题有多重要.但是没有银子弹,浮点数的问题仍然是一个非常困难的问题(你可以在你的整个生活中工作).

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


Pac*_*ac0 5

使用您给出的特定示例(常量计算):

您没有在问题中定义"安全".我假设你想保持相同数量的正确有效数字.

  • 双打是正确的15位有效数字
  • 你有4个有效数字的常量
  • 操作涉及使用乘法,除法和一个平方根
  • 它似乎并不认为你的结果会的"边缘"的情况下双打(非常小的或大的指数值,其中尾数损失精度)

按此特定顺序,结果将对4位有效数字正确.


但是,在一般情况下,你必须要小心.(可能不是,这取决于你对"安全"的定义).

这是一个庞大而复杂的主题.特别是,如果您有以下结果,您的结果可能不正确相同的有效位数:

  • 更多的操作,
  • 如果你有相互靠近的数字的减数
  • 其他有问题的操作

强制阅读:每个计算机科学家应该知道的浮点运算

有关其他参考资料,请参阅@Basile Starynkevitch的正确答案.

此外,对于复杂的计算,有一些关于问题的条件数的概念是相关的.