C 西塔多克公式不能精确工作
我试图用Citardauq公式计算一个二次方程的根,这是一种数值上更稳定的方法来计算这些根。然而,例如,当我输入方程x^2+200x-0.000002=0时,该程序无法精确计算根。为什么?我在我的代码中没有发现任何错误,灾难性的取消不应该发生在这里 您可以找到Citardauq公式工作的原因(第二个答案)C 西塔多克公式不能精确工作,c,precision,numerical-methods,C,Precision,Numerical Methods,我试图用Citardauq公式计算一个二次方程的根,这是一种数值上更稳定的方法来计算这些根。然而,例如,当我输入方程x^2+200x-0.000002=0时,该程序无法精确计算根。为什么?我在我的代码中没有发现任何错误,灾难性的取消不应该发生在这里 您可以找到Citardauq公式工作的原因(第二个答案) #包括 #包括 int main() { 双a,b,c,行列式; 双根1,根2; printf(“引入系数a、b和c:\n”); 扫描(“%lf%lf%lf”、&a、&b和&c); 行列式=b
#包括
#包括
int main()
{
双a,b,c,行列式;
双根1,根2;
printf(“引入系数a、b和c:\n”);
扫描(“%lf%lf%lf”、&a、&b和&c);
行列式=b*b-4*a*c;
如果(0>行列式)
{
printf(“该方程没有实际解”);
返回0;
}
如果(b>0)
{
root1=(-b-sqrt(行列式))/(2*a);
root2=(c/(a*root1));
printf(“解决方案是%.16lf和%.16lf\n”,root1,root2);
}
else if(b<0)
{
root1=(-b+sqrt(行列式))/(2*a);
root2=(c/(a*root1));
printf(“解决方案是%.16lf和%.16lf\n”,root1,root2);
}
}
欢迎使用数值计算。
这里有几个问题:
1) 正如一些程序员所指出的那样,浮点数的精确表示存在问题
对于标准binary64格式的0.1,表示形式可以是
写得一模一样
0.10000000000000055115123125782702118158340454015625
2) 双精度(Double)仅提供有效位52位、指数位11位和符号位1位。
C语言中的浮点数使用IEEE 754编码
3) sqrt
精度也受到限制
在您的情况下,解决方案如下:
你可以看到,从精度的角度来看,这不是一个简单的方程
给出了如下解决方案:
1.0000007932831068e-8 -200.00000001
您的程序更好:
Introduce coefficients a b and c:
1
200
-0.000002
The solutions are -200.0000000100000079 i 0.0000000100000000
所以其中一个根是-200.0000000 10000。忘掉其余的数字。
这正是我们所能期望的,因为double具有15
decimal
精确的数字 你得到了什么结果?你期待什么?也许你也会感兴趣阅读。旁白:else如果(b@Someprogrammerdude我得到一个根是0.0000000100000000,失去了意义(我想要避免的).基本上我只想用C编码。谢谢你的回答,我想我现在理解得更清楚了。但是,第二个根是0.000000010000000,因此我失去了7位意义,对吗?我想实现编码的目的是避免失去意义。我有另一个代码,使用标准样方计算根ic公式,它们给出了相同的答案。考虑一下,两个程序应该给出相同的答案,因为它们是根,但是我怎样才能避免失去意义呢?@codingnight不,你没有丢失7位数字。在0.0000000 100000000
中,你还有15
“好”数字。那么,在代码中我也不会丢失任何数字吗?@codingnight是的,根据双分辨率,您将始终拥有15
“好”数字。这可以通过算法的数字不稳定性进行更改,但这不是您的情况。数字79
超出15
好数字范围。它们只是一个数字“噪音”。
Introduce coefficients a b and c:
1
200
-0.000002
The solutions are -200.0000000100000079 i 0.0000000100000000