2012-04-20 14 views
2

最初のC#プログラムを書きました。C#2次方程式ソルバーに問題がある

2次方程式を解く簡単なコードです。

一部の機能(-6x2-6x + 12など)で完全に動作しますが、他のもの(4x2-20x + 25)では丸め誤差があると思われます。

私はC#のことがまったく新しく、問題は見えません。誰かがこのコードをデバッグする手助けをすることができますか?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication7 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      int a, b, c; 
      int d; 
      double x1, x2; 
      entA: Console.Write("a?"); 
      try 
      { 
       a = Convert.ToInt32(Console.ReadLine()); 
      } 
      catch 
      { 
       /*If a=0, the equation isn't quadratic*/ 
       Console.WriteLine("Invalid input"); 
       goto entA; 
      } 
      entB: Console.Write("b?"); 
      try 
      { 
       b = Convert.ToInt32(Console.ReadLine()); 
      } 
      catch 
      { 
       Console.WriteLine("Invalid input"); 
       goto entB; 
      } 
      entC: Console.Write("c?"); 
      try 
      { 
       c = Convert.ToInt32(Console.ReadLine()); 
      } 
      catch 
      { 
       Console.WriteLine("Invalid input"); 
       goto entC; 
      } 
      /*Calculating a discriminant*/ 
      d = b * b - 4 * a * c; 
      if (d == 0) 
      { 
       x1 = x2 = -b/(2 * a); 
       Console.WriteLine("The only solution is x={0}.", x1); 
       Console.ReadLine(); 
      } 
      else if (d < 0) /*If d<0, no solutions are possible*/ 
      { 
       Console.WriteLine("There are no possible solutions"); 
       Console.ReadLine(); 
      } 
      else /*If d>0, there are two possible solutions*/ 
      { 
       x1 = (-b - Math.Sqrt(d))/(2 * a); 
       x2 = (-b + Math.Sqrt(d))/(2 * a); 
       Console.WriteLine("x1={0} and x2={1}.", x1, x2); 
       Console.ReadLine(); 
      } 
     } 
    } 
} 

ここで更新されたコードです:

 
    namespace ConsoleApplication7 
    { 
    class Program 
    { 
     static int ObtainInput(string prompt, bool canBeZero) 
     { 
      double a = ObtainInput("A? ", false); 
      double b = ObtainInput("B? ", true); 
      double c = ObtainInput("C? ", true); 
      double d; 
      double x1, x2; 
      while (true) // loop forever! 
      { 
       Console.Write(prompt); 
       string input = Console.ReadLine(); 
       int result; 
       bool success = int.TryParse(input, out result); 
       if (success && (canBeZero || result != 0)) 
        return result; 
       Console.WriteLine("Invalid input!"); 
      } 
      /Calculating a discriminant/ 
      d = b * b - 4 * a * c; 
      if (d == 0) 
      { 
       x1 = x2 = -b/(2 * a); 
       Console.WriteLine("The only solution is x={0}.", x1); 
       Console.ReadLine(); 
      } 
      else if (d < 0) /If d<0, no solutions are possible/ 
      { 
       Console.WriteLine("There are no possible solutions"); 
       Console.ReadLine(); 
      } 
      else /If d>0, there are two possible solutions/ 
      { 
       x1 = (-b - Math.Sqrt(d))/(2 * a); 
       x2 = (-b + Math.Sqrt(d))/(2 * a); 
       Console.WriteLine("x1={0} and x2={1}.", x1, x2); 
       Console.ReadLine(); 
      } 
     } 
    } 
    } 

+0

C#では、誰もgotosを使用しません。地獄、私はそれが存在することを知っていましたが、構文は私にニュースです。 –

+0

すべての 'int '値(' a、b、c、d')を 'double'に変更してもう一度やり直してください。 '(-b /(2 * a)) 'のようなものは、' a'と 'b'が' int'のときは "整数除算"を行います。これは重大な丸め誤差です。 –

+0

@Baboon私は彼らを見たとき、私は同じ反応を示しました。 – NominSim

答えて

19

最初のC#プログラムを書きました。

驚くばかりです。今、悪い習慣に陥ることのない素晴らしい時間です:

entA: Console.Write("a?"); 
try { a = Convert.ToInt32(Console.ReadLine()); } 
catch 
{ /*If a=0, the equation isn't quadratic*/ 
    Console.WriteLine("Invalid input"); 
    goto entA;    
} 

問題がたくさんあります。最初に、失敗する可能性のあるものの周りにtry-catchを置くのではなく、int.TryParseを使用してください。

第2に、コメントはコードの動作と一致しません。コードは、結果が整数かどうかを判断します。コメントは、それがゼロをチェックすると言う。

第3に、ループを表現しようとしているときにgotoを使用しないでください。

第4に、重複したコードをすべて見てください!あなたは同じコードを3回繰り返し、軽微なバリエーションを持っています。

自分ヘルパーメソッドください:

static int ObtainInput(string prompt, bool canBeZero) 
{ 
    while(true) // loop forever! 
    { 
     Console.Write(prompt); 
     string input = Console.ReadLine(); 
     int result; 
     bool success = int.TryParse(input, out result); 
     if (success && (canBeZero || result != 0)) 
      return result; 
     Console.WriteLine("Invalid input!"); 
    } 
} 

そして今、あなたのメインラインは、次のとおりです。

int a = ObtainInput("A? ", false); 
int b = ObtainInput("B? ", true); 
int c = ObtainInput("C? ", true); 

あなたのバグしかしここにある:

x1 = x2 = -b/(2 * a); 

あなたは整数で算術演算を行いますおよびである場合、は倍精度に変換されます。つまり、分割を行い、最も近い整数に丸めて、doubleに変換します。最初から二重に(または、小数点以下で)実行します。

つまり、a、b、およびcは整数であってはなりません。

+0

また、 'x1 =(-b-Math.Sqrt(d))/(2 * a);にバグがあります。 –

+0

このように数学に' decimal'を使うのは意味がありますか?特に、 'decimal'に' Math.Sqrt() 'のオーバーロードがないためです。 – svick

+0

@スウィック:そうではありません。しかしintよりも優れています。 :-) –

3

X1とX2に割り当てるときは、整数の除算をやっているが、 (2から2.0に変更して二重除算に変更して二重の結果を得ることができます)

a、b、c、dの値をdoubleに変更することもできます人々は係数の非整数値を入力することができます。

3

int a、b、c; int d;

まず、整数の代わりに1/3 = 0なので、intの代わりにdoubleを使用してみてください。

関連する問題