1

In this code:

public class PiCalc {
    public static void main(String[] args) {
        double pi = 1.0;
        int n = 3;
        int denominator = 3;
        while (n<10) {
            if (n%2 == 0) {
                pi += 1/denominator;
            }
            else {
                pi -= 1/denominator;
            }
            n++;
            denominator += 2;
        }
        System.out.println(4*pi + "," + n + "," + denominator);
    }
}

The output is: 4.0,10,17

So, variables n and denominator are updating as I want, but pi isn't. Can anyone tell me why?

0

3 Answers 3

3

read up on "int division" as that's what you're doing:

1 / (some int bigger than 1) returns 0

A statement where an int divides an int must return an int, so it rounds towards 0 always.

Change it to

1.0 / denominator

or

(double) 1 / denominator

so that you're doing double division.

Sign up to request clarification or add additional context in comments.

Comments

2

For best practices' sake, you should not be casting denominator from int to double constantly--you are only using it as a double, so it should be a double typed variable. Casting ints to doubles (or back) is not free. Making denominator into a double will be faster and simpler to understand:

public class PiCalc {
    public static void main(String[] args) {
        double pi = 1.0;
        double denominator = 3.0;
        int n = 3;
        while (n<10) {
            if (n%2 == 0) {
                pi += 1.0/denominator;
            }
            else {
                pi -= 1.0/denominator;
            }
            n++;
            denominator += 2.0;
        }
        System.out.println(4*pi + "," + n + "," + denominator);
    }
}

For that matter, if you are going to make the loop run for more than a few cycles (to get a really accurate pi), you could further increase performance by ditching the if:

public class PiCalc {
    public static void main(String[] args) {
        double pi = 1.0;
        double denominator = 3.0;
        int n = 3;
        while (n<10000) /* get a really accurate PI */ {
            pi -= 1.0/denominator;
            n++;
            denominator += 2.0;

            pi += 1.0/denominator;
            n++;
            denominator += 2.0;
        }
        System.out.println(4*pi + "," + n + "," + denominator);
    }
}

4 Comments

I disagree. The denominator should be in fact an int because mathematically, that's what it in fact is. If you make it a double, and the iteration gets large enough, the accuracy of its value is likely to shift. Better to leave denominator an int and change it (or the numerator) to double only when doing division.
Doubles can represent any value an integer can represent with perfect precision. They have 53 mantissa bits!! Think about it.
Still, logically, theoretically etc, the number is a whole number. If you have to do recursive calculations or lots of looping to say calculate PI to a close precision, the accuracy drift will matter.
It only ever participates in a floating point calculation. There is absolutely no accuracy benefit for storing it as integer (doubles can represent the full integer range perfectly). But, this loop is slower if you need to constantly convert an integer to double, and the integer will wrap around FAR before a double would see any accuracy issues. I think you are tilting at windmills here.
1

1/denominator is always going to equate to 0 because both are type int - like somebody else mentioned read up on int division. You probably want to cast both to double to match your pi variable. So I would change the if block to something like this.

if (n%2 == 0) {
    pi += 1d/(double)denominator;
} else {
    pi -= 1d/(double)denominator;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.