我试图使用Citardauq公式计算二次方程的根,这是一种更加数值稳定的方法来计算这些根。但是,例如,当我输入等式x ^ 2 + 200x-0.000002 = 0时,该程序不会精确计算根。为什么?我的代码中没有发现任何错误,这里不应该发生灾难性的取消。
您可以找到为什么Citardauq公式适用于here(第二个答案)。
#include <stdio.h>
#include <math.h>
int main()
{
double a, b, c, determinant;
double root1, root2;
printf("Introduce coefficients a b and c:\n");
scanf("%lf %lf %lf", &a, &b, &c);
determinant = b * b - 4 * a * c;
if (0 > determinant)
{
printf("The equation has no real solution\n");
return 0;
}
if (b > 0)
{
root1 = (-b - sqrt(determinant)) / (2 * a);
root2 = (c / (a * root1));
printf("The solutions are %.16lf and %.16lf\n", root1, root2);
}
else if (b < 0)
{
root1 = (-b + sqrt(determinant)) / (2 * a);
root2 = (c / (a * root1));
printf("The solutions are %.16lf and %.16lf\n", root1, root2);
}
}
欢迎来到数值计算。这里有一些问题:
1)正如some-programmer-dude
指出的那样,浮动数字Is floating point math broken?的精确表示存在问题
对于标准二进制64格式的0.1,表示可以完全写为0.1000000000000000055511151231257827021181583404541015625
2)双精度(双精度)只给出52位有效位,11位指数和1位符号位。 C中的浮点数使用IEEE 754编码。
3)sqrt
精度也有限。
从精确的角度来看,你可以看出它并不容易。
On line calculator 1提供的解决方案如下:
1.0000007932831068e-8 -200.00000001
你的程序更好:
Introduce coefficients a b and c:
1
200
-0.000002
The solutions are -200.0000000100000079 i 0.0000000100000000
所以其中一个根就是-200.000000010000。忘记其余的数字。这正是人们可以期待的,因为double有15
十进制数字的精度!