user1455655
user1455655

Reputation:

Rounding issue in Java

I'm trying to do a quick 2 vars equation solver using Cramer's rule but for some reason java keeps on rounding my answers so i don't get the right answer.

the basic rule for getting single answer is

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

and the solution should be

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

but for some reason i get -4.0 and 4.0 instead of -4.0 and 4.5 for 1,2,3,4,5,6

that's the problematic code if it helps:

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

Upvotes: 1

Views: 106

Answers (3)

Yogendra Singh
Yogendra Singh

Reputation: 34367

Explicitly cast any of the variables as double before operation as:

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

or just multiply your one of the numbers by 1.0 to make them decimal as:

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

This is required because currently its performing operations on int and resulting an int which is getting assigned to double.

Once you multiply your numerator or any of the participating variables by 1.0 or explicitly cast it to double, it becomes double and then remaining variables are auto promoted to double, which result into double result as desired.

Upvotes: 2

Daniel Castro
Daniel Castro

Reputation: 1290

It's probably because the operands are integers.

When you perform an operation between integers, the result is another integer (which is why it gets 'rounded'). In your case, the result is casted to double after the operation is performed (so the integer result is converted to double). What you need to do is performing the operation between doubles so the result is double. This can be done by simply changing the types of one of the variables involved in the division to double (say b1, a22, a11, b2, or a12): the other variables will be promoted to double automatically.

Example code:

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

Or, if you don't want that your variable's type is double, you can just cast your numerator or denominator (or both, but it won't make a difference):

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

Also, if any of the variables involved in calculating the numerator (or the denominator) is double, the whole numerator gets 'converted' to double, and therefore, the result of division is double (because at least one of numerator or denominator is double). But, if you had some code like this:

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

It wouldn't work, because the division is performed between int variables and then added with a double variable. This would have the same issue as you have now

Upvotes: 2

xagyg
xagyg

Reputation: 9711

Note the casts to 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 +")");
}

Upvotes: 3

Related Questions