java.lang.NumberFormatException 与 BigDecimal java

java.lang.NumberFormatException with BigDecimal java

我实现了这个短代码来计算第 (n) 个斐波那契数,但是当它变得太大时,我的 BigDecimal 似乎不再起作用了。我得到以下堆栈跟踪:

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)

这是我的代码:

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))));

}

和打印 class:

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

long startTime2 = System.currentTimeMillis();

第 23 行:

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

有人知道如何解决这个问题吗?

检查 args[0] 的值是多少,如果它不是整数或为空或为 null 那么程序可能会导致 NumberFormatException

更新: 当数字很大时,> 500 可能是计算后的 NaN(Not a number),BigDecimal 不支持。请参阅以下问题来处理 NaN。 Java: BigDecimal and Double.NaN

BigDecimal是无界的,但是你发起它的double值:

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

可能是NaN,导致这个异常。

您可以使用 BigDecimal.pow 代替 Math.pow

如果提取用于初始化 BigDecimal 的值,当 input 足够大(例如 500)时,您会发现该值为 NaN,如下所示:

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);
    }
}

为了解决这个问题,BigDecimal 中还有 4 个基本操作:plussubtractmultiplydivide,甚至 pow,所以使用下面的代码可能会解决这个问题:

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;
    }
}