繁体   English   中英

BigDecimal下溢

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM