计算Pascal中二次方程的实根

时间:2012-08-11 14:31:09

标签: freepascal quadratic equation-solving

我正在尝试解决这个问题:

(编写程序来计算二次方程的实根(ax 2 + bx + c = 0)。根可以使用以下公式计算:

x1 =( - b + sqrt(b 2 - 4ac))/ 2a

x2 =( - b - sqrt(b 2 - 4ac))/ 2a

我编写了以下代码,但不正确:

program week7_lab2_a1;
var a,b,c,i:integer;
x,x1,x2:real;

begin
  write('Enter the value of a :');
  readln(a);

  write('Enter the value of b :');
  readln(b);

  write('Enter the value of c :');
  readln(c);

  if (sqr(b)-4*a*c)>=0 then
    begin
      if ((a>0) and (b>0)) then
        begin
          x1:=(-1*b+sqrt(sqr(b)-4*a*c))/2*a;
          x2:=(-1*b-sqrt(sqr(b)-4*a*c))/2*a;

          writeln('x1=',x1:0:2);
          writeln('x2=',x2:0:2);
        end
      else
        if ((a=0) and (b=0)) then
          write('The is no solution')
        else
          if ((a=0) and (b<>0)) then
            begin
              x:=-1*c/b;
              write('The only root :',x:0:2);
            end;
    end
  else
    if (sqr(b)-4*a*c)<0 then
      write('The is no real root');

  readln;
end.
你知道为什么吗?

并且取a = -6,b = 7,c = 8 ..你可以在编写pesudocode后进行检查吗?

2 个答案:

答案 0 :(得分:2)

这里有一个运算符优先级错误:

x1:=(-1*b+sqrt(sqr(b)-4*a*c))/2*a;
x2:=(-1*b-sqrt(sqr(b)-4*a*c))/2*a;

最后看,2 * a不符合你的想法。它将表达式除以2,但由于优先级规则,乘以a。这就是你想要的:

x1:=(-1*b+sqrt(sqr(b)-4*a*c))/(2*a);
x2:=(-1*b-sqrt(sqr(b)-4*a*c))/(2*a);

实际上,这是因为表达式是从左到右的wrt括号和乘法和除法have the same priority进行评估。所以基本上,一旦它除以2,它就说“我已经完成了除法,我将把我现在所用的a乘以”告诉“。

由于你给出的公式似乎并不清楚,这是二次公式:

enter image description here

正如你所看到的,你需要除以2a,所以你必须在这里使用括号使其正常工作,正如这个等式的正确纯文本表达式是x =( - b + - sqrt(b ^ 2) - 4ac))/(2a)。


否则代码看起来很好,如果有点复杂(例如,您可以在输入后立即丢弃(a = 0)和(b = 0)的情况,这将稍后简化逻辑)。您是否真的想要排除负系数,或者只是零系数?你应该检查一下。

还要注意浮点相等比较 - 它适用于0,但通常不适用于大多数常量,因此如果需要检查一个值是否等于另一个值,请使用epsilon(如:{ {1}})

答案 1 :(得分:1)

完全赞同托马斯在答案中所说的话。只想添加一些优化标记:

检查if语句中的判别值,然后再次使用它:

if (sqr(b)-4*a*c)>=0 then
...
x1:=(-1*b+sqrt(sqr(b)-4*a*c))/2*a;
x2:=(-1*b-sqrt(sqr(b)-4*a*c))/2*a;

这不是很有效 - 而不是一次多次计算判别值。您应首先计算判别值并将其存储到某个变量中:

D := sqr(b)-4*a*c;

之后,您可以在所有表​​达式中使用您的评估值,如下所示:

if (D >= 0) then
...
x1:=(-b+sqrt(D)/(2*a);
x2:=(-b-sqrt(D)/(2*a);

等等。


另外,我不会写-1*b ...而不是在最坏的情况下只使用-b0-b,而不是乘法。这里不需要乘法。


修改

还有一点需要注意:

您的代码:

if (sqr(b)-4*a*c)>=0 then
begin
 ...
end
  else
    if (sqr(b)-4*a*c)<0 then
      write('The is no real root');

你在这里仔细检查if条件。我简化了这个:

if (a) then
    begin ... end
else
    if (not a)
    ...

您检查not a 的位置(在您的代码中它对应于(sqr(b)-4*a*c)<0 - 在这种情况下,条件可能只是假(对于a)而且没有必要仔细检查一下。你应该把它扔掉。