繁体   English   中英

当 n 非常大时,辛普森的复合规则给出了太大的值

[英]Simpson's Composite Rule giving too large values for when n is very large

使用辛普森的复合规则计算1/ln(x)21,000的积分,但是当使用较大的n (通常约为500,000 )时,我开始得到与我的计算器和其他来源给我的值不同的结果( 176.5644 )。 例如,当n = 10,000,000时,它给我的值为184.1495 想知道为什么会这样,因为随着 n 变大,精度应该会增加而不是降低。

#include <iostream>
#include <cmath>

// the function f(x)
float f(float x)
{
    return (float) 1 / std::log(x);
}




float my_simpson(float a, float b, long int n)
{
  if (n % 2 == 1) n += 1; // since n has to be even
  float area, h = (b-a)/n;


  float x, y, z;
  for (int i = 1; i <= n/2; i++)
  {
    x = a + (2*i - 2)*h;
    y = a + (2*i - 1)*h;
    z = a + 2*i*h;
    area += f(x) + 4*f(y) + f(z);
  }

  return area*h/3;
}



int main()
{
    std::cout.precision(20);
    int upperBound = 1'000;
    int subsplits = 1'000'000;

    float approx = my_simpson(2, upperBound, subsplits);

    std::cout << "Output: " << approx << std::endl;

    return 0;
}

更新:从花车切换到双打,现在效果好多了! 谢谢!

与实数(在数学意义上)不同, float的精度有限。

典型的 IEEE 754 32 位(单精度)浮点数二进制表示仅将 24 位(其中一位是隐含的)用于尾数,并且转换为大约少于 8 个十进制有效数字(请将此视为粗略)。

另一端的double具有 53 个有效位,使其更准确,并且(通常)是当今数值计算的首选。

因为随着 n 变大,精度应该增加而不是减少。

不幸的是,它不是这样工作的。 有一个汗点,但在那之后,舍入误差的积累盛行,结果与预期值背道而驰。

在 OP 的情况下,这个计算

area += f(x) + 4*f(y) + f(z);

由于area变得远大于f(x) + 4*f(y) + f(z) (例如 224678.937 与 0.3606823),引入(并累积)舍入误差。 n越大,相关性越早,从而使结果与真实结果不同。

如评论中所述,另一个问题(未定义的行为)是该area未初始化(为零)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM