Question

I am writing a recursive formula and require values when the function has run hundreds of times. At near the 450th - 500th run, the console outputs infinity.

Is it possible to force Java to output a larger value but in scientific notation?

Recursion:

public static void main(String[] args) {
    for (int i = 0; i < 500; i++) {
        System.out.println(Math.pow(3 + 2 * Math.sqrt(2), i)
                + Math.pow(3 - 2 * Math.sqrt(2), i));
    }
}

Output at roughly 450th run:

2.4705373096084562E302
1.4399346668019402E303
8.392554269850795E303
4.891539095230283E304
2.8509979144396616E305
1.661683357711494E306
9.685000354824998E306
5.644831877123849E307
Infinity
Infinity
Infinity
Infinity
Infinity
Infinity
Infinity
Infinity
Infinity

Edit

I have used BigDecimal, as recommended.

    for (int i = 0; i < 500; i++) {
        BigDecimal n = new BigDecimal(Math.pow(3 + 2 * Math.sqrt(2), i)
                + Math.pow(3 - 2 * Math.sqrt(2), i));
        System.out.println(n);
    }

However, now the console spits out :

Exception in thread "main" java.lang.NumberFormatException: Infinite or NaN
at java.math.BigDecimal.<init>(BigDecimal.java:808)
at mathC.Recursion2.main(Recursion2.java:9)

I have read that BigDecimal should be able to store a value that is roughly 8Gb of memory. Since my laptop contains 16Gb of 1600MHz memory, why is this happening? Is this number really 8Gb of memory?

The number before the error is (SO won't let me format this):

56448318771238491045438986070422562722375814412748377586799357549587081845130965398544956161588871436829847442988862310610370686259432485701530038671444090445069088383193741454463060427351807692569019541559990842957532377423388218307948475268885262237809144041880563122951075397138587894276020263963236237312

Was it helpful?

Solution 2

You could have a look at BigDecimal.

(That doesn't look very recursive, as Fibonacci algorithms go.)

OTHER TIPS

Once the values get large enough, they exceed the maximum value that a double can store: Double.MAX_VALUE, or 1.7976931348623157E308. When such an operation exceeds this maximum value, then the double value Infinity results.

This is specified by the JLS, Section 15.18.2:

If the magnitude of the sum is too large to represent, we say the operation overflows; the result is then an infinity of appropriate sign.

(Other binary arithmetic operators have their own JLS Section, and they say the same thing.)

To get a bigger range, use a BigDecimal to store results with arbitrary precision.

Well, I don't know what the goal of the program is, but if you just want it to print it (instead of re-using it in another operaton), why not using the International System for quick notation? That way, you only have to create an if statement with the desired range.

(Here's a link to a table with the values : http://ronblond.com/MathGlossary/Division03/International%20System%20of%20Units/PrefixChart.gif)

Not only it solves that issue (once again, if you merely want the output, and a non-exact one), but it's also easier on the eye.

---//--- Example (Edit) ---//---

Let's take 2222, thus, 1,10 and 1k. If on a cicle you divide it by a multiple of 10, you can in theory easily convert it. Let's see:

      // For cicle here with an increasing i. n is how many times you've divided
     if (i>999 && i<10000){    // if you have i=2222

    i=(i/(n*10));   // in this case, n=100 , thus the  integer i = 2
    System.out.println(i + "k");  // 2222 is aproximatly 2k

    }

Although, this would only work if you could actually create a way to stop the loop. Something that has only came up to me now.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top