我正在编写一个递归公式,并在函数运行数百次时需要值。在第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
答案 0 :(得分:4)
一旦值变得足够大,它们就会超过double
可以存储的最大值:Double.MAX_VALUE
或1.7976931348623157E308
。当此类操作超过此最大值时,double
值Infinity
会生成。
如果总和的大小太大而无法表示,我们说操作溢出;结果就是无穷无尽的适当标志。
(其他二进制算术运算符有自己的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
}
虽然,这只有在您真正创建一种停止循环的方法时才有效。现在只出现在我身上的东西。