1

我正在尝试使用 Cramer 的规则做一个快速的 2 vars 方程求解器,但由于某种原因,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.0 而不是 -4.0 和 4.5

如果有帮助,那就是有问题的代码:

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

注意演员表加倍......

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 sol1 = ((double)b1*a22-b2*a12) / (a11*a22-a12*a21);
   double sol2 = (b2*a11-b1*a21) / ((double)a11*a22-a12*a21);

或者只是将您的数字之一乘以 1.0 以使它们成为十进制:

   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

这可能是因为操作数是整数。

当您在整数之间执行运算时,结果是另一个整数(这就是它被“四舍五入”的原因)。在您的情况下,执行操作后将结果转换为双精度(因此整数结果转换为双精度)。您需要做的是在双精度之间执行操作,因此结果是双精度。这可以通过简单地将除法中涉及的变量之一的类型更改为双精度(例如 b1、a22、a11、b2 或 a12)来完成:其他变量将自动提升为双精度。

示例代码:

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 +")");
}

此外,如果计算分子(或分母)所涉及的任何变量为双精度,则整个分子将“转换”为双精度,因此除法的结果为双精度(因为分子或分母中至少有一个是双精度)。但是,如果你有这样的代码:

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 回答