【问题标题】:Implementation of pow function in c language with power of -3/2 or -5/2c语言实现pow函数,幂为-3/2或-5/2
【发布时间】:2018-03-15 22:06:42
【问题描述】:

我是 C 语言的新手。我正在尝试实现公式(r to power of (-3/2)) * exp(t*(r-1/r)。我正在使用pow 函数,但是当我将这个等式保留在 for 循环中时,它会不断地执行循环说"pow domain error"。我希望 for 循环中的增量为0.2。请帮助我实施这个公式。代码是:

#include <stdio.h>
#include <conio.h>
#include <math.h>

void main()
{
    double R,r;
    float f;
    clrscr();
    for(r=0;r<=5;r+0.2)
    {
        R=pow(r,-1.5)*exp(2.5*(r-1)/r);
        f=r-R;
        printf("value of f is:%f",f);
    }
    getch();
}

【问题讨论】:

  • 部分问题是r+0.2 - 应该是r+=0.2
  • for(r=0;r&lt;=5;r+0.2) 更改为for(r=1;r&lt;=5;r+=0.2)。 (当 r = 0 时,pow(r,-1.5)(r-1)/r 的计算将失败。)
  • 您的循环 for(r=0;r&lt;=5;r+=0.2) 将以迭代结束,其中 r 约为 4.8;它不会执行迭代 r 是 5(或大约 5)。这部分是因为当 .2 转换为常用 C 实现使用的浮点格式时,结果是 0.200000000000000011102230246251565404236316680908203125。要正确迭代,请使用 for (double i = 0; i &lt;= 50; i += 2) 并将 r = i / 10; 放入循环中。

标签: c infinite-loop pow divide-by-zero


【解决方案1】:

您可能需要注意:

C 标准 7.12.1 [ISO/IEC 9899:2011] 定义了三种类型的错误,这些错误与 .第 2 段状态

如果输入参数域外超过,则会发生域错误 定义了数学函数。

第 3 段状态

如果极点误差(也称为奇点或无穷大),则发生 数学函数具有精确的无限结果作为有限输入 参数接近极限。

第 4 段状态

如果函数的数学结果不能 在指定类型的对象中表示,由于极端 幅度。

函数pow(x,y)的可用是:

 (x > 0) || (x == 0 && y > 0) || (x < 0 && y is an integer)

这意味着您不能使用r = 0 作为pow 的参数。

1) pow(r, -1.5) = r^(-3/2) = 1.0/ r^3/2 = 1.0/sqrt(r*r*r);

2) C 语言 main 函数应该返回 int 值并接受 void 而不是空括号 ()

3) 递增操作可以通过r = r + 0.2r += 0.2 完成

4) 为了避免在(r-1)/r 中被零除,必须使用接近0 的值。

5) 为了不丢失double 精度,变量f 也应该声明为double

6) fr=0 的值极难计算。对于r = 0,该算法在数值上不稳定。我们有两个无穷大的除法。解决它的正确方法是在点0+ 处找到函数限制。在数值上,将r 设置为接近0 就足够了。

7) 由于f 函数的性质,您可以考虑为r 设置更小的步长,以便捕获更好的图。

#include<stdio.h>
#include<conio.h>
#include<math.h>

#define  ZERO_PLUS      1e-14       

void calculate_and_print(double r)
{
    double f, f1;

    f =  r -       pow(r, -1.5) * exp(2.5*(r-1)/r);
    f1 = r - (1.0 /sqrt(r*r*r)) * exp(2.5*(r-1)/r);

    printf("Value of f for r= %f  is  f= %f  f1= %f \n", r, f, f1);
}

int main(void)
{
    clrscr();

    calculate_and_print(ZERO_PLUS);  

    for (double r = 0.2; r < 5.0; r += 0.2 )
        calculate_and_print(r);

    calculate_and_print(5.0); 

    return 0;
}

测试:

Value of f for r= 0.000000  is  f= 0.000000  f1= 0.000000                                                                                     
Value of f for r= 0.200000  is  f= 0.199492  f1= 0.199492                                                                                     
Value of f for r= 0.400000  is  f= 0.307038  f1= 0.307038                                                                                     
Value of f for r= 0.600000  is  f= 0.193604  f1= 0.193604                                                                                     
Value of f for r= 0.800000  is  f= 0.051949  f1= 0.051949                                                                                     
Value of f for r= 1.000000  is  f= 0.000000  f1= 0.000000                                                                                     
Value of f for r= 1.200000  is  f= 0.046058  f1= 0.046058                                                                                     
Value of f for r= 1.400000  is  f= 0.166843  f1= 0.166843                                                                                     
Value of f for r= 1.600000  is  f= 0.338256  f1= 0.338256                                                                                     
Value of f for r= 1.800000  is  f= 0.542116  f1= 0.542116                                                                                     
Value of f for r= 2.000000  is  f= 0.765977  f1= 0.765977                                                                                     
Value of f for r= 2.200000  is  f= 1.001644  f1= 1.001644                                                                                     
Value of f for r= 2.400000  is  f= 1.243810  f1= 1.243810                                                                                     
Value of f for r= 2.600000  is  f= 1.489073  f1= 1.489073                                                                                     
Value of f for r= 2.800000  is  f= 1.735278  f1= 1.735278                                                                                     
Value of f for r= 3.000000  is  f= 1.981075  f1= 1.981075                                                                                     
Value of f for r= 3.200000  is  f= 2.225642  f1= 2.225642                                                                                     
Value of f for r= 3.400000  is  f= 2.468498  f1= 2.468498                                                                                     
Value of f for r= 3.600000  is  f= 2.709387  f1= 2.709387                                                                                     
Value of f for r= 3.800000  is  f= 2.948194  f1= 2.948194                                                                                     
Value of f for r= 4.000000  is  f= 3.184898  f1= 3.184898                                                                                     
Value of f for r= 4.200000  is  f= 3.419535  f1= 3.419535                                                                                     
Value of f for r= 4.400000  is  f= 3.652177  f1= 3.652177                                                                                     
Value of f for r= 4.600000  is  f= 3.882916  f1= 3.882916                                                                                     
Value of f for r= 4.800000  is  f= 4.111856  f1= 4.111856                                                                                     
Value of f for r= 5.000000  is  f= 4.339103  f1= 4.339103

如果您还有其他问题,请告诉我。

【讨论】:

  • 可以循环使用double格式的整数值。也就是说,它们应该增加 2 而不是 .2,但可以在浮点类型而不是整数类型中进行。浮点精确地处理整数,直到它们溢出可用宽度(与整数格式相同),并且使用浮点而不是整数可以避免重复的整数到浮点转换。
  • @EricPostpischil 你完全正确!我更正了答案并增加了双精度以避免转换。我增加1.0 以避免除以10.0。乘法比除法快。
  • 我们如何使用c语言绘制f和r之间的图形。有什么函数可以帮助我们绘制。
  • @SudhirKumar C 语言没有任何内置绘图功能。必须使用外部库。检查:stackoverflow.com/questions/1275484/good-plotting-library-for-c
  • 当我试图将这些值写入文件时,它说指针未定义,只有一个值被打印到文件中
【解决方案2】:

来自http://en.cppreference.com/w/c/numeric/math/pow

如果 base 为 0 且 exp 为负数,则可能会出现域错误或极点错误。

当您评估 pow(r, -1.5) 并将 r 的值设置为零时,您会遇到这种情况。

更改您的循环,使 r 以 0.2 而不是零开头。

另外,您需要在for 语句中使用r += 0.2 而不是r+0.2

for ( r = 0.2; r <= 5; r += 0.2)
{
   R = pow(r, -1.5)*exp(2.5*(r-1)/r);
   f = r-R;
   printf("value of f is:%f", f);
}

【讨论】:

  • 一旦我得到结果,我应该为 r 和 f 绘制图形。所以 r 的初始值必须为 0。
  • @SudhirKumar 好吧,如果你能弄清楚pow(0, -1.5) 是什么,那么你就可以继续解决2.5*(0-1)/0 是什么的问题了。
猜你喜欢
  • 2018-09-08
  • 2012-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-05
  • 1970-01-01
  • 2021-12-12
相关资源
最近更新 更多