0

erf 函数的 Boost 实现中

在此处输入图像描述

<boost/math/special_functions/erf.hpp>在我们的标题中

result = z * 1.125 + z * 0.003379167095512573896158903121545171688L;

在下面附加的代码片段中。我的问题是:为什么没有

大号

此添加的第一个组件中的长后缀,而第二个组件中有一个?它背后的基本原理是什么,它带来了什么影响?

template <class T, class Policy>
T erf_imp(T z, bool invert, const Policy& pol, const mpl::int_<113>& t)
{
   BOOST_MATH_STD_USING
   BOOST_MATH_INSTRUMENT_CODE("113-bit precision erf_imp called");

   if(z < 0){
      if(!invert)
         return -erf_imp(-z, invert, pol, t);
      else if(z < -0.5)
         return 2 - erf_imp(-z, invert, pol, t);
      else
         return 1 + erf_imp(-z, false, pol, t);
   }

   T result;

   // Big bunch of selection statements now
   if(z < 0.5){
      // We're going to calculate erf:
      if(z == 0){
         result = 0;
      }else if(z < 1e-20){
         result = z * 1.125 + z * 0.003379167095512573896158903121545171688L;
                          ^^^ no L?                                       ^^^
4

1 回答 1

5

如果z已经是 a long double,则乘法z * 1.125已经是long double乘法。常量1.125完全可以表示为 a double,它的类型。实际上,它可以完全表示为float. 所以不需要指明long double这个常量的类型。如果z具有更宽的浮点类型,则无论如何都会在乘法之前提升常量。

相比之下,用十进制写的实数 0.003379167095512573896158903121545171688 不能以任何二进制浮点精度精确表示。如果0.003379167095512573896158903121545171688L0.003379167095512573896158903121545171688在程序中,则表示最接近double指示的十进制序列,与最接近的 不同,离long double实际值更远。

您可以使用下面的 C 程序观察差异:

#include <stdio.h>

int main(int c, char **v)
{
  printf("%s\n%.24Lf\n%.24Lf\n\n%La\n%La\n", 
     "0.003379167095512573896158903121545171688",
     (long double) 0.003379167095512573896158903121545171688,
     0.003379167095512573896158903121545171688L,
     (long double) 0.003379167095512573896158903121545171688,
     0.003379167095512573896158903121545171688L);
}

结果:

0.003379167095512573896158903121545171688
0.003379167095512573739530
0.003379167095512573896231

0xd.d750429b6d118p-12
0xd.d750429b6d11ae4p-12
于 2013-05-18T03:23:55.490 回答