Jlan
Jlan

Reputation: 3

java.lang.NumberFormatException with BigDecimal java

I implemented this short code to calculate the (n)th Fibonacci number, but when it gets too big, my BigDecimal doesn't seem to work anymore. I get the following stacktrace:

Exception in thread "main" java.lang.NumberFormatException
  at java.math.BigDecimal.<init>(BigDecimal.java:494)
    at java.math.BigDecimal.<init>(BigDecimal.java:383)
    at java.math.BigDecimal.<init>(BigDecimal.java:806)
    at java.math.BigDecimal.valueOf(BigDecimal.java:1274)
    at Fibonacci.next2(Fibonacci.java:42)
    at FibonacciPrint.main(FibonacciPrint.java:23)

Here is my code:

int index;

public Fibonacci(int index){
    this.index=index;
}

public  BigDecimal next2(){
    System.out.print(index + " ");

    return BigDecimal.valueOf(((Math.pow(1 + Math.sqrt(5), index)- 
                                Math.pow(1-Math.sqrt(5),index))
                                /(Math.pow(2,index)* Math.sqrt(5))));

}

and the print class:

Fibonacci f2 = new Fibonacci(Integer.parseInt(args[0]));

long startTime2 = System.currentTimeMillis();

line 23:

    System.out.println(f2.next2());
    long endTime2 = System.currentTimeMillis();
    System.out.println("Total execution time: " + (endTime2-startTime2) + "ms");

Does anyone have an idea how to fix this?

Upvotes: 0

Views: 9822

Answers (3)

xingbin
xingbin

Reputation: 28289

BigDecimal is unbounded, but the double value you initiate it:

((Math.pow(1 + Math.sqrt(5), index) -
                Math.pow(1 - Math.sqrt(5), index))
                / (Math.pow(2, index) * Math.sqrt(5)));

might be NaN, which cause this exception.

You can use BigDecimal.pow instead Math.pow.

Upvotes: 4

Deb
Deb

Reputation: 2972

Check what is the value of args[0] if it not an integer or is empty or is null then the programme can cause NumberFormatException

Update: When the number is big, > 500 it is probablly the NaN(Not a number) after computing, which BigDecimal doesn't support. Please see the following question to handle NaN. Java: BigDecimal and Double.NaN

Upvotes: 0

kezhenxu94
kezhenxu94

Reputation: 156

If you extract the value that you used to initialize BigDecimal you can find that the value is NaN when input is large enough (say 500), like this:

class Fibonacci {
    int index;

    public Fibonacci(int index) {
        this.index = index;
    }

    public BigDecimal next2() {
        System.out.print(index + " ");

        double v = (Math.pow(1 + Math.sqrt(5), index) - Math.pow(1 - Math.sqrt(5), index)) / (Math.pow(2, index) * Math.sqrt(5));

        System.out.println(v); // <---- Here

        return BigDecimal.valueOf(v);
    }
}

To fix this, there are also 4 basic operations in BigDecimal: plus, subtract, multiply, divide, and even pow, so use the following code may fix this problem:

class Fibonacci {
    int index;

    public Fibonacci(int index) {
        this.index = index;
    }

    public BigDecimal next2() {
        System.out.print(index + " ");

        BigDecimal v = BigDecimal.valueOf(1 + Math.sqrt(5)).pow(index).subtract(BigDecimal.valueOf(1 - Math.sqrt(5)).pow(index)).divide(BigDecimal.valueOf(2).pow(index).multiply(BigDecimal.valueOf(Math.sqrt(5))), RoundingMode.CEILING);

        System.out.println(v);

        return v;
    }
}

Upvotes: 1

Related Questions