BigDecimal 除法四舍五入
BigDecimal division is rounding up
我正在尝试计算以下内容:
(1 - (1/365)) * (1 - (2/365) = 0.99727528617
我想存储整个小数点。这是我的代码,但它给我的答案是 1:
public BigDecimal probability(int t){
BigDecimal probT; // holds our probability of a single (1-(t/365))
BigDecimal result; // holds our result
result = BigDecimal.ONE; // initialize result to 1
// for 1 to t-1
for (int n = 1; n < t; n++){
int numerator = n; // numerator the value of n
int denominator = 365; // denominator 365
// numberator / denominator (round down)
probT = BigDecimal.valueOf(numerator).divide(BigDecimal.valueOf(denominator), RoundingMode.DOWN);
// 1-answer
probT = BigDecimal.ONE.subtract(probT);
// multiply the probabilities together
result = result.multiply(probT);
}
return result;
}
BigDecimal ans2 = bc.probability(3);
System.out.println("P(3) = " + ans2.toString());
输出:
P(3) = 1
那是因为你正在计算的除法是用 0 的比例进行的。引用方法 divide(divisor, roundingMode)
Javadoc:
Returns a BigDecimal
whose value is (this / divisor)
, and whose scale is this.scale()
.
这里this.scale()
指的是分子的小数位数,因为分子是BigDecimal.valueOf(n)
所以为0,n
是整数
您需要将此除法更改为使用 divide(divisor, scale, roundingMode)
并指定您想要的比例。
来自java doc
When a MathContext object is supplied with a precision setting of 0
(for example, MathContext.UNLIMITED), arithmetic operations are exact,
as are the arithmetic methods which take no MathContext object. (This
is the only behavior that was supported in releases prior to 5.)
As a corollary of computing the exact result, the rounding mode
setting of a MathContext object with a precision setting of 0 is not
used and thus irrelevant. In the case of divide, the exact quotient
could have an infinitely long decimal expansion; for example, 1
divided by 3.
If the quotient has a nonterminating decimal expansion and the
operation is specified to return an exact result, an
ArithmeticException is thrown. Otherwise, the exact result of the
division is returned, as done for other operations.
要修复,您需要执行以下操作:
// numberator / denominator (round down)
probT = BigDecimal.valueOf(numerator).divide(BigDecimal.valueOf(denominator), 10,RoundingMode.DOWN);
其中10是精度(小数位精度),RoundingMode.DOWN是舍入方式
我正在尝试计算以下内容:
(1 - (1/365)) * (1 - (2/365) = 0.99727528617
我想存储整个小数点。这是我的代码,但它给我的答案是 1:
public BigDecimal probability(int t){
BigDecimal probT; // holds our probability of a single (1-(t/365))
BigDecimal result; // holds our result
result = BigDecimal.ONE; // initialize result to 1
// for 1 to t-1
for (int n = 1; n < t; n++){
int numerator = n; // numerator the value of n
int denominator = 365; // denominator 365
// numberator / denominator (round down)
probT = BigDecimal.valueOf(numerator).divide(BigDecimal.valueOf(denominator), RoundingMode.DOWN);
// 1-answer
probT = BigDecimal.ONE.subtract(probT);
// multiply the probabilities together
result = result.multiply(probT);
}
return result;
}
BigDecimal ans2 = bc.probability(3);
System.out.println("P(3) = " + ans2.toString());
输出:
P(3) = 1
那是因为你正在计算的除法是用 0 的比例进行的。引用方法 divide(divisor, roundingMode)
Javadoc:
Returns a
BigDecimal
whose value is(this / divisor)
, and whose scale isthis.scale()
.
这里this.scale()
指的是分子的小数位数,因为分子是BigDecimal.valueOf(n)
所以为0,n
是整数
您需要将此除法更改为使用 divide(divisor, scale, roundingMode)
并指定您想要的比例。
来自java doc
When a MathContext object is supplied with a precision setting of 0 (for example, MathContext.UNLIMITED), arithmetic operations are exact, as are the arithmetic methods which take no MathContext object. (This is the only behavior that was supported in releases prior to 5.)
As a corollary of computing the exact result, the rounding mode setting of a MathContext object with a precision setting of 0 is not used and thus irrelevant. In the case of divide, the exact quotient could have an infinitely long decimal expansion; for example, 1 divided by 3.
If the quotient has a nonterminating decimal expansion and the operation is specified to return an exact result, an ArithmeticException is thrown. Otherwise, the exact result of the division is returned, as done for other operations.
要修复,您需要执行以下操作:
// numberator / denominator (round down)
probT = BigDecimal.valueOf(numerator).divide(BigDecimal.valueOf(denominator), 10,RoundingMode.DOWN);
其中10是精度(小数位精度),RoundingMode.DOWN是舍入方式