NumberFormatException:无限或NaN [英] NumberFormatException: Infinite or NaN

查看:152
本文介绍了NumberFormatException:无限或NaN的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法,它取n并返回第n个Fibonacci数。在方法实现中,我使用 BigDecimal 来获取第n个Fibonacci数,然后我使用方法 toBigInteger()来获取数字作为一个 BigInteger 对象,这肯定是因为我在我的应用程序中处理大量数字。

I have a method that takes n and returns nth Fibonacci number. Inside the method implementation I use BigDecimal to get the nth Fibonacci number then I use method toBigInteger() to get the number as a BigInteger object and that's surely because I am working with huge numbers in my application.

我一直在变得正确结果直到我通过 1475 作为我的方法的参数。在这种情况下,我得到 NumberFormatException:Infinite或NaN ,没有任何明确的理由。

I keep getting correct results until I pass 1475 as an argument for my method. I get NumberFormatException: Infinite or NaN in this case without any clear reason for me.

你能不能请解释一下为什么我会收到这个例外?

这是我的方法:

BigInteger getFib(int n){
     double phi = (1 + Math.sqrt(5))/2;
     double squareRoot = (Math.sqrt(5)) + (1/2);
     BigDecimal bd = new BigDecimal(Math.floor(Math.pow(phi, n)/(squareRoot)));
     return bd.toBigInteger();
}


推荐答案

您的 Math.pow(phi,n)太大(Infinity),double无法存储它,请改用BigDecimal。

Your Math.pow(p n) is too big(Infinity),double is unable to store it,use BigDecimal instead.

如何流动:

static BigInteger getFib(int n) {
    BigDecimal x1 = new BigDecimal((1 + Math.sqrt(5)) / 2);
    BigDecimal x2 = new BigDecimal((1 - Math.sqrt(5)) / 2);
    return x1.pow(n).subtract(x2.pow(n))
            .divide(new BigDecimal(Math.sqrt(5))).toBigInteger();
}

来自公式:

更新:
以上方式是不正确,因为Math.sqrt(5)没有足够的精度,如评论所说。我试图使用Netown的方法更精确地计算sqrt(5),并发现 x1.pow(n).subtract(x2.pow(n))。divide(...) 非常耗时,在我的电脑中n = 200时大约30秒。

UPDATE: the above way is incorrect,because Math.sqrt(5) does not has enough precision as the comment said. I've tried to culculate sqrt(5) with more precision using Netown's method,and found out that x1.pow(n).subtract(x2.pow(n)).divide(...) is very time-consuming,it spended about 30 seconds for n = 200 in my computer.

我认为缓存的递归方式是更快:

I think the recursive way with a cache is mush faster:

    public static void main(String[] args) {
    long start = System.nanoTime();
    System.out.println(fib(2000));
    long end = System.nanoTime();
    System.out.println("elapsed:"+ (TimeUnit.NANOSECONDS.toMillis(end - start)) + " ms");
}

private static Map<Integer, BigInteger> cache = new HashMap<Integer, BigInteger>();

public static BigInteger fib(int n) {
    BigInteger bi = cache.get(n);
    if (bi != null) {
        return bi;
    }
    if (n <= 1) {
        return BigInteger.valueOf(n);
    } else {
        bi = fib(n - 1).add(fib(n - 2));
        cache.put(n, bi);
        return bi;
    }
}

我的电脑花了7毫秒n = 2000 。

It spend 7 ms in my computer for n = 2000.

这篇关于NumberFormatException:无限或NaN的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆