BigDecimal下溢 [英] BigDecimal Underflow

查看:181
本文介绍了BigDecimal下溢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to render a fractal called the "Lorenz Attractor" with Java. Because double does not work (values out of range), I decided to choose BigDecimals. After 38 iterations my code crashes, it gets me an ArithmeticException (Underflow). Heres some of the code:

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("----------");

这是我得到的输出
我能反对吗?对不起,如果代码不是很好。我还可以提供一些伪代码,告诉我你是否需要它。

This is the output I get. Can I do anything against that? Sorry if the code doesn't look very good. I can also provide some pseudocode on how it should be done, tell me if you need that.

编辑:这是第二行拆分up:

This is the second line split up:

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 更强大,更灵活,它仍然有限制;即比例 int

While BigDecimal is much more powerful and flexible than double it does still have limits; namely its scale is an int:


BigDecimal包含任意精度整数未缩放值和32位整数刻度。

A BigDecimal consists of an arbitrary precision integer unscaled value and a 32-bit integer scale.

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

This means that you cannot represent numbers larger or smaller than are scaled by a factor of more than 2^31. This is a massive (or minuscule) number (10^2^31 being the largest possible multiplier), and for almost any possible use case it's an impractical edge case to run into. By comparison there are "only" approximately 4×10^80 atoms in the universe.

那么如果遇到溢出或下溢错误,这意味着什么?您正在使用的数字的大小非常大或小, BigDecimal 无法支持它们。这完全但肯定意味着你已经犯了某种逻辑错误,而且没有按照你的意图进行操作 - 仔细检查你的数学。

So what does it mean if you're running into Overflow or Underflow errors? The scale of the numbers you're working with are so ludicrously large or small that BigDecimal can't support them. This all-but-certainly means you've made a logic error of some sort, and are aren't doing the operations you intended to - double-check your math.

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

Occasionally the problem is the order of operations - e.g. your result might be a reasonably sized number, but the intermediary steps are unworkable. Computing the binomial coefficient is an example of this. In such cases you need to experiment with other orders of operation that avoid such unreasonable numbers.

这篇关于BigDecimal下溢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆