1

Cramer のルールを使用して 2 変数の方程式ソルバーを実行しようとしていますが、何らかの理由で Java が答えを四捨五入し続けるため、正しい答えが得られません。

単一の答えを得るための基本的なルールは

((a11*a22)-(a12*a21))!=0) 

そして解決策は

double sol1 = (b1*a22-b2*a12) / (a11*a22-a12*a21);
double sol2 = (b2*a11-b1*a21) / (a11*a22-a12*a21);

しかし、何らかの理由で、1,2,3,4,5,6 の -4.0 と 4.5 ではなく、-4.0 と 4.0 を取得します。

それが役立つ場合、それは問題のあるコードです:

if (((a11*a22)-(a12*a21))!=0) {
   double sol1 = (b1*a22-b2*a12) / (a11*a22-a12*a21);
   double sol2 = (b2*a11-b1*a21) / (a11*a22-a12*a21);
   System.out.println("Single solution: ("+sol1+", "+sol2 +")");
 }
4

3 に答える 3

3

doubleへのキャストに注意してください...

if (((a11*a22)-(a12*a21))!=0) {
   double sol1 = (double)(b1*a22-b2*a12) / (a11*a22-a12*a21);
   double sol2 = (double)(b2*a11-b1*a21) / (a11*a22-a12*a21);
   System.out.println("Single solution: ("+sol1+", "+sol2 +")");
}
于 2012-12-01T16:38:10.193 に答える
2

次のように、操作の前に任意の変数を double として明示的にキャストします。

   double sol1 = ((double)b1*a22-b2*a12) / (a11*a22-a12*a21);
   double sol2 = (b2*a11-b1*a21) / ((double)a11*a22-a12*a21);

または、数字の1つに1.0を掛けて、次のように10進数にします。

   double sol1 = (1.0*(b1*a22-b2*a12)) / (a11*a22-a12*a21);
   double sol2 = (b2*a11-b1*a21) / (1.0*(a11*a22-a12*a21));

これが必要なのは、現在 で操作を実行してintおり、結果としてintに割り当てられているためdoubleです。

分子または関与する変数のいずれかに 1.0 を掛けるか、明示的に double にキャストすると、それは double になり、残りの変数は double に自動的に昇格され、希望どおりの結果がdoubleられます。

于 2012-12-01T16:35:32.613 に答える
2

おそらく、オペランドが整数であるためです。

整数間で演算を実行すると、結果は別の整数になります (これが「丸められる」理由です)。あなたの場合、操作が実行された後、結果は double にキャストされます (したがって、整数の結果は double に変換されます)。結果が double になるように、double 間で操作を実行する必要があります。これは、除算に関係する変数の 1 つの型を double に変更するだけで実行できます (たとえば、b1、a22、a11、b2、または a12): 他の変数は自動的に double に昇格されます。

コード例:

double b1 = /* whatever */;
// ..
if (((a11*a22)-(a12*a21))!=0) {
    double sol1 = (b1*a22-b2*a12) / (a11*a22-a12*a21);
    double sol2 = (b2*a11-b1*a21) / (a11*a22-a12*a21);
    System.out.println("Single solution: ("+sol1+", "+sol2 +")");
}

または、変数の型を double にしたくない場合は、分子または分母 (またはその両方) をキャストできますが、違いはありません:

if (((a11*a22)-(a12*a21))!=0) {
    double sol1 = (double)(b1*a22-b2*a12) / (a11*a22-a12*a21);
    double sol2 = (b2*a11-b1*a21) / (double)(a11*a22-a12*a21);
    System.out.println("Single solution: ("+sol1+", "+sol2 +")");
}

また、分子 (または分母) の計算に関与する変数のいずれかが double の場合、分子全体が double に「変換」されるため、除算の結果は double になります (分子または分母の少なくとも 1 つが double であるため)。 )。ただし、次のようなコードがあるとします。

if (((a11*a22)-(a12*a21))!=0) {
    double sol1 = (double)someOtherIntVariable + (b1*a22-b2*a12) / (a11*a22-a12*a21);
    //...
}

除算はint変数間で実行され、次にdouble変数が追加されるため、機能しません。これには、現在と同じ問題があります

于 2012-12-01T16:38:49.363 に答える