Reputation: 3
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
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
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
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