如何强制控制台输出更大的数字

时间:2014-03-21 21:31:39

标签: java infinity

我正在编写一个递归公式,并在函数运行数百次时需要值。在第450到第500次运行时,控制台输出infinity

是否可以强制Java输出更大的值但是用科学记数法?

递归:

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

大约第450次输出:

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

修改

我按照建议使用了BigDecimal

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

然而,现在控制台吐出:

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)

我已经读过BigDecimal应该能够存储大约8Gb内存的值。由于我的笔记本电脑包含16Gb的1600MHz内存,为什么会这样呢?这个数字真的是8Gb的内存吗?

错误前的数字是(SO不会让我格式化):

56448318771238491045438986070422562722375814412748377586799357549587081845130965398544956161588871436829847442988862310610370686259432485701530038671444090445069088383193741454463060427351807692569019541559990842957532377423388218307948475268885262237809144041880563122951075397138587894276020263963236237312

3 个答案:

答案 0 :(得分:4)

一旦值变得足够大,它们就会超过double可以存储的最大值:Double.MAX_VALUE1.7976931348623157E308。当此类操作超过此最大值时,doubleInfinity会生成。

这是由JLS, Section 15.18.2

指定的
  

如果总和的大小太大而无法表示,我们说操作溢出;结果就是无穷无尽的适当标志。

(其他二进制算术运算符有自己的JLS节,他们说同样的事情。)

要获得更大的范围,请使用BigDecimal以任意精度存储结果。

答案 1 :(得分:2)

您可以查看BigDecimal

(这看起来并不是非常递归的,因为Fibonacci算法可以实现。)

答案 2 :(得分:1)

好吧,我不知道该计划的目标是什么,但 如果 只是 想要打印它(而不是在另一个操作中重复使用它),为什么不使用国际系统进行快速记法?这样,您只需要创建一个具有所需范围的if语句。

(这是一个带有值的表的链接: http://ronblond.com/MathGlossary/Division03/International%20System%20of%20Units/PrefixChart.gif

不仅可以解决这个问题(如果您只是想要输出,还有 非精确 ),那么它也会更容易解决。

--- // ---示例(编辑)--- // ---

我们取2222,因此,1,10和1k。如果你在一个角色上将它除以10的倍数,理论上你可以轻松转换它。我们来看看:

      // 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

    }

虽然,这只有在您真正创建一种停止循环的方法时才有效。现在只出现在我身上的东西。