【问题标题】:Calculating Maxwell-Boltzmann Distribution计算麦克斯韦-玻尔兹曼分布
【发布时间】:2017-04-10 05:04:41
【问题描述】:

我正在尝试计算 Maxwell-Boltzmann 分布,但这段代码给出了 0.00000,这是什么问题?

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{

    float e=2.718228183, pi=3.14159265, m=2.66*pow(10,-23), t, k=1.38*pow(10,-23), v, result;

    scanf("%f %f", &t, &v);

    result = sqrt(pow( m / (2*pi*k*t),   3))   * 4 * pi * pow(v,2) * pow(e, -(m * pow(v,2)) / (2*k*t)); 

    printf("%f", result);
}

【问题讨论】:

  • 代码为 what 输入值提供0.000000
  • 应该打印什么?顺便说一句,我不知道您为什么使用float。您的系统无法使用double吗?
  • double 也给出 0.000000 @WeatherVane
  • 请注意,数学库提供了 eπ 的值,还有函数 exp 可以完成您正在使用的 @ 987654326@for.
  • 旁白:您的玻尔兹曼常数为k=1.38*pow(10,-23)。我建议k=1.3806485279e-23。同样,您对 m 的初始化也不必要地调用了 pow 函数。

标签: c precision floating-accuracy scientific-computing


【解决方案1】:

替换

double pi=acos(-1.);

而不是

 double pi=3.1415926535897932384626433832795028842;

【讨论】:

    【解决方案2】:

    如 cmets 中所述,float 的使用以及常数精度的降低给出的结果不再可表示为 float。将数据类型单独更改为双精度会给出两位小数的精度。如果我们使用exp,更多位数的 pi 并对计算进行一些重组,我们得到 12 位数的准确度。例如:

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    int main()
    {
    
      double pi = 3.1415926535897932384626433832795028842, m = 2.66e-23, k =
          1.38e-23;
      double t, v, v2, dkt, result;
      // check omitted
      scanf("%lf %lf", &t, &v);
    
      v2 = v * v;
      dkt = 2 * k * t;
    
      result = pow(m / (pi * dkt), 3 / 2.0) * 4 * pi * v2 * exp(-(m * v2) / (dkt));
      printf("%.20g\n", result);
      return 0;
    }
    

    Pari/GP 的结果是8.1246636077915008261803395870165527173e-9,我们用上面的代码得到的结果是8.1246636077914841125e-09。如果没有中间结果v2dktsqrt 的替换,我们得到了8.1246636077914824582e-09,差别不大,尤其是在没有任何收获的准确性方面。

    如果您想要完整的 16 位十进制数字,则需要将整个内容分开并采用不同的方法。

    【讨论】:

    • 代码中的真正修复是偶然的。使用printf("%e", result);,OP 的代码计算8.127763e-09。其他的变化大多是毛茸茸的......
    • @EOF 上面的代码并不意味着修复,正如最后一句话所阐明的那样。至少我认为——最后一句话——可以说清楚,没有直接的解决办法,只有用完全不同的方法。双倍(112 位双倍)可能会在一些有限但可能足够大的范围内做到这一点,但我没有对计算进行完整分析。 exppow(x,y) (= exp(y log x)) 将建议使用 Remez 或类似方法(例如在 lolengine.net/wiki/oss/lolremez 的帮助下)找到的系列和极小多边形。
    • OP 的错误可能不是第 n 个十进制数字错误。 OP 的问题是,由于 %f 作为 printf()-conversion 说明符的愚蠢,结果完全没用
    猜你喜欢
    • 2020-11-27
    • 2017-01-26
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 2014-02-04
    • 1970-01-01
    相关资源
    最近更新 更多