BigDecimal下溢

我试图用Java渲染一个名为“Lorenz Attractor”的分形图。 因为double不起作用(值超出范围),所以我决定选择BigDecimals。 经过38次迭代后,我的代码崩溃,它让我得到一个ArithmeticException(Underflow)。 下面是一些代码:

 BigDecimal xnew = this.x.add(this.hBig.multiply(BigDecimal.TEN).multiply(this.x.add(this.y.negate()))); //This is the line that crashes BigDecimal ynew = this.y.add(this.hBig.multiply(this.x.negate().multiply(this.z)).add(ZWENTYEIGHT.multiply(this.x.add(this.y.negate())))); BigDecimal znew = this.z.add(this.hBig.multiply(this.x.multiply(this.y).add(FRAC.multiply(this.z).negate()))); this.x = xnew; this.y = ynew; this.z = znew; System.out.println("X="+this.x); System.out.println("Y="+this.y); System.out.println("Z="+this.z); System.out.println("----------"); 

这是我得到的输出 。 我可以做任何反对吗? 对不起,如果代码不是很好。 我也可以提供一些关于应该怎么做的伪代码,告诉我你是否需要它。

编辑:这是分裂的第二行:

 BigDecimal temp = ZWENTYEIGHT.multiply(this.x.add(this.y.negate())); BigDecimal temp2 = this.x.negate().multiply(this.z); BigDecimal temp3 = this.hBig.multiply(temp2); //This crashes. BigDecimal temp4 = temp3.add(temp); BigDecimal ynew = this.y.add(temp4); 

EDIT2:这是一些伪代码:

 do 4000 times xnew=x+h*10*(xy) ynew=y+h*((-x*z)+28*xy) znew=z+h*(x*y-8/3*z) x=xnew y=ynew z=znew 

虽然BigDecimaldouble强大且灵活,但它仍然有限制; 即它的scale是一个int

BigDecimal由任意精度整数非标度值和32位整数标度组成。

这意味着您不能表示大于或小于按比例大于2 ^ 31的数字的数字。 这是一个巨大的 (或微小的)数字(10 ^ 2 ^ 31是最大可能的乘数),对于几乎任何可能的用例,它都是一个不切实际的边缘情况。 相比之下,宇宙中“仅”约有4×10 ^ 80个primefaces。

那么,如果您遇到溢出或下溢错误,这意味着什么? 你正在使用的数字的规模是如此大或小,以至于BigDecimal无法支持它们。 这种情况肯定意味着您已经犯了某种逻辑错误,并且没有按照您的意图进行操作 – 仔细检查您的数学运算。

偶尔问题是操作的顺序 – 例如,您的结果可能是一个合理大小的数字,但中间步骤是不可行的。 计算二项式系数就是一个例子。 在这种情况下,您需要尝试避免此类不合理数字的其他操作顺序。