这是我在C程序中编写的代码的一部分---
else if((pow(b,2.0)-4*a*c)>0) {
printf("\nRoots=%.2f and %.2f\n",
(-b+pow(b*b-4*a*c,0.5))/(2*a),
(-b-pow(b*b-4*a*c,0.5))/(2*a));
} else
printf("\nBoth roots are %.2f\n",-b/(2*a));
在控制台中,如果我将a
标记为1
,b
标记为14
,将c
标记为49
,如果标记为&# 34;根= -7.00和-7.00" ...而不是说"两个根都是-7.00"但如果我在pow(b,2)
条件下将b*b
替换为else if
,则会显示后一种结果....为什么会这样?请解释一下。
答案 0 :(得分:3)
请在代码中附上最低限度的工作示例。
无论如何,它适用于我的系统(Debian GNU / Linux测试,gcc 5.2.1):
#include <math.h>
#include <stdio.h>
int main() {
float a,b,c;
scanf("%f",&a);
scanf("%f",&b);
scanf("%f",&c);
if ((pow(b,2.0)-4*a*c)<0)
printf("\nNo roots!\n");
else if((pow(b,2.0)-4*a*c)>0) {
printf("\nRoots=%.2f and %.2f\n",
(-b+pow(b*b-4*a*c,0.5))/(2*a),
(-b-pow(b*b-4*a*c,0.5))/(2*a));
} else
printf("\nBoth roots are %.2f\n",-b/(2*a));
return 0;
}
如果我输入1,14,49,程序将回答Both roots are -7.0
。但是这个可能因系统而异,因为您使用的是浮点运算,我不知道您的pow()
函数是如何实现的。并非所有实数都可以在计算机上显示 - 这里有一个很好的描述它如何适用于single precision floats。并且每个编译器/运行时环境都可能具有可能不同的数学库实现(包括您使用过的pow
)。
所以,如果可能的话,我会尽量避免使用pow
。请改用b*b
,并在您真正需要时保存pow
。正如Tom Karzes所提到的,sqrt
也比使用pow
计算平方根要好。
最后一件事:只计算一次判别式会使你的程序更具可读性:
#include <math.h>
#include <stdio.h>
int main() {
float a,b,c;
float delta;
scanf("%f",&a);
scanf("%f",&b);
scanf("%f",&c);
delta = b*b-4*a*c;
if (delta<0)
printf("\nNo roots!\n");
else if(delta>0)
printf("\nRoots=%.2f and %.2f\n",
(-b+sqrt(delta))/(2*a),
(-b-sqrt(delta))/(2*a));
else
printf("\nBoth roots are %.2f\n",-b/(2*a));
return 0;
}
您可以尝试的另一件事是使用double
代替float
,因此您将获得更高的精确度(根据您将使用的数字不相关,但这是一个好主意如果您没有可能占用太多内存的巨大数字矩阵,则使用doubles
- double
需要两倍于float
代表的内存。
答案 1 :(得分:2)
这可能是一个精确的问题。 pow(b, 2.0)
用于b
肯定的算法可能类似exp(2.0 * log(b))
,可能会生成一个非常接近196.0
但不完全196
的数字。比较失败但是当舍入到小数点后2位进行打印时结果仍然相同。请改为%g
。
b * b
相反b = 14.0
与196
完全一样计算。
顺便说一句,我在笔记本电脑上获得了适当的代码结果,你使用的操作系统和编译器是什么?
答案 2 :(得分:2)
使用pow(b, 2.0)
通常不如b*b
准确。虽然它们在数学上是相同的,但pow
函数将执行类似exp(2.0 * log(b))
的操作。它还需要对否定b
等进行特殊检查。另外,在取平方根时,请使用sqrt(x)
而不是pow(x, 0.5)
,原因类似:它会更快,更准确。
您的代码也将通过计算判别式一次并保存而不是复制代码来改进。
答案 3 :(得分:0)
本文将指导您为什么结果不同:https://randomascii.wordpress.com/2013/07/16/floating-point-determinism/
我建议你试试这个,看看是否有效。
((int)pow(b,2) - (4*a*c))>0 // Assuming computation is based on integers.
如果没有,请尝试这些建议(在C中使用类似功能):
What is the best way to compare floats for almost-equality in Python?