Elliot
Elliot

Reputation: 9

Trying to answer a math puzzle but my program will not exit out of this loop

I came across a math problem the other day and decided to write some Java code to figure out the answer. Except my code does not work for some odd reason.

Here is the problem:

Top Left + Top Right = 8, Top Left + Bottom Left = 13, Bottom Left - Bottom Right = 6, Top Right + Bottom Right = 8

Here is my code:

public class Java {
    public static void main(String[] args) {
        double tLeft = 0;
        double tRight = 0;
        double bLeft = 0;
        double bRight = 0;

        while (bLeft - bRight != 6) {
            tLeft += 0.1;
            tRight = 8 - tLeft;
            bLeft = 13 - tLeft;
            bRight = 8 - tRight;
        }
        System.out.printf("Top Left = %f\nTop Right = %f\nBottom Left = %f\nBottom Right = %f\n\n", tLeft, tRight, bLeft, bRight);
    }
}

This will loop through all possible variations of the Top Left number and give me numbers based off of that. Yes I know it is very clumsy and bad code, but I am still learning!

The problem here though is that my IDE (Eclipse) will just loop infinitely and will not exit out of the loop and print the answer. If I change tLeft to be declared as equal to 3 instead of 0, I get my answer, but if I go even further and declare it as 2.7 instead of 3, Eclipse decides to loop infinitely again.

My question to you all is exactly why and when does Eclipse decide to infinitely loop and how can I prevent it in order to get the answer I want?

P.S. the answers to the math problem are:

Top Left = 3.5

Top Right = 4.5

Bottom Left = 9.5

Bottom Right = 3.5

Thank you in advance!

Upvotes: 0

Views: 212

Answers (2)

rslemos
rslemos

Reputation: 2730

Change your while condition to:

while (abs(bLeft - bRight - 6) < error)

error is the precision you are willing to accept.

On another approach you could avoid floating point altogether, by scaling up your numbers and using integers:

public static void main(String[] args) {
    int tLeft = 0;
    int tRight = 0;
    int bLeft = 0;
    int bRight = 0;

    while (bLeft - bRight != 60) {
        tLeft += 1;
        tRight = 80 - tLeft;
        bLeft = 130 - tLeft;
        bRight = 80 - tRight;
    }
    System.out.printf("Top Left = %f\nTop Right = %f\nBottom Left = %f\nBottom Right = %f\n\n", tLeft/10.0, tRight/10.0, bLeft/10.0, bRight/10.0);
}

Upvotes: 0

APerson
APerson

Reputation: 8422

If you inspect the value of bLeft - bRight, due to floating point error it'll print out 5.9999999 when it should be precisely 6.

One way to avoid this is checking if the difference is smaller than some epsilon. Since the values are changing by 0.1 each iteration, I picked 0.05. Then the guard of the while statement becomes:

while (bLeft - bRight - 6 < 0.05) {

Another way to avoid this problem is to use BigDecimal, which uses more precise floating point math.

A similar answer (specifically Eric Weilnau's answer to a related question) recommends The need for BigDecimal to illustrate why BigDecimal helps here.

Upvotes: 1

Related Questions