BigDecimal Underflow

試著忘記壹切 提交于 2019-12-06 10:11:37

问题


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.

EDIT: 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: This is some pseudocode:

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

回答1:


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

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

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.

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.



来源:https://stackoverflow.com/questions/29968205/bigdecimal-underflow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!