我正在尝试使用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);
}
}
答案 0 :(得分:1)
欢迎使用数值计算。 这里有一些问题:
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
十进制
精度数字!