[英]BigDecimal Underflow
我试图用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*(x-y)
ynew=y+h*((-x*z)+28*x-y)
znew=z+h*(x*y-8/3*z)
x=xnew
y=ynew
z=znew
虽然BigDecimal
是更加强大和灵活的比double
它仍然有很大的局限性; 即其scale
是一个int
:
BigDecimal由任意精度的整数无标度值和32位整数标度组成。
这意味着您不能表示大于或小于按比例放大2 ^ 31的数字。 这是一个巨大的数字 (或微小的数字)(10 ^ 2 ^ 31是最大可能的乘数),并且对于几乎所有可能的用例而言,这都是一个不切实际的边缘情况。 相比之下,宇宙中只有“大约” 4×10 ^ 80个原子。
那么,如果您遇到上溢或下溢错误,这意味着什么? 您正在使用的数字的比例太大或太小,以至于BigDecimal
无法支持它们。 可以肯定的是,这意味着您已经犯了某种逻辑错误,并且没有执行您打算执行的操作-请仔细检查数学。
有时问题是操作的顺序-例如,您的结果可能是一个合理大小的数字,但是中间步骤不可行。 计算二项式系数就是一个例子。 在这种情况下,您需要尝试其他操作顺序,以避免出现这种不合理的数字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.