更新时间:2023-02-19 22:45:43
A double 不能代表这样的数字,它太大了.范围大约在-10 308 和10 308 之间.
A double
as defined by IEEE-754 can't represent such a number, it's too large. The bounds are approximately between -10308 and 10308.
您需要使用 BigDecimal
来表示它:一个具有任意字节数的数字来表示数字.
You need to use a BigDecimal
to represent it: a number with an arbitrary number of bytes to represent numbers.
实现此目标的更好方式:
Better way to implement this:
double c = 0.0005d;//initialize c
double r = 0.01d; //initialize r
double a = 0.0006d;//initialize a
BigDecimal abd = new BigDecimal(a); //BigDecimal for a
BigDecimal cbd = new BigDecimal(c); //BigDecimal for c
BigDecimal rbd = new BigDecimal(r); //BigDecimal for r
for (int counter = 1; counter <= t; counter++) {//perhaps other offset for counter?
abd = abd.multiply(new BigDecimal(counter));
cbd = cbd.multiply(rbd).add(abd);
}
这种方法的潜在问题是精度太高:Java将精确地计算所有操作,从而得出具有数千位数字的数字.由于每个运算都会炸掉位数,因此在几次迭代中,简单的加法和乘法运算变得不可行.
A potential problem with this approach is that the precision is too high: Java will calculate all operations exactly resulting in numbers that have thousands of digits. Since every operation blows up the number of digits, within a few iterations, simple addition and multiplication operations become unfeasible.
您可以通过使用可选的 MathContext
参数定义精度来解决此问题:它确定结果的精度.例如,您可以使用 MathContext.DECIMAL128
:
You can solve this by defining a precision using the optional MathContext
parameter: it determines on how precise the result should be. You can for instance use MathContext.DECIMAL128
:
int t = 101835;
double c = 0.0005d;//initialize c
double r = 0.01d; //initialize r
double a = 0.0006d;//initialize a
BigDecimal abd = new BigDecimal(a); //BigDecimal for a
BigDecimal cbd = new BigDecimal(c); //BigDecimal for c
BigDecimal rbd = new BigDecimal(r); //BigDecimal for r
for (int counter = 1; counter <= t; counter++) {//perhaps other offset for counter?
abd = abd.multiply(new BigDecimal(counter),MathContext.DECIMAL128);
cbd = cbd.multiply(rbd,MathContext.DECIMAL128).add(abd,MathContext.DECIMAL128);
}
System.out.println(abd);
System.out.println(cbd);
这给出了:
abd = 3.166049846031012773846494375835059E+465752
cbd = 3.166050156931013454758413539958330E+465752
这大概是正确的,毕竟 a
的结果应该是:
This is approximately correct, after all the result of a
should be:
根据 Wolfram Alpha ,这大约是正确的.
Which is approximately correct according to Wolfram Alpha.
此外,如果是 for
循环,我建议使用 for
,而不要使用 while
.由于 while
倾向于创建另一种类型的无穷大:无限循环;).
Furthermore I would advice to use a for
and not a while
if it is a for
loop. Since while
tends to create another type of infinity: an infinite loop ;).