Reputation: 1958
I'm trying to calculate the following:
(1 - (1/365)) * (1 - (2/365) = 0.99727528617
I would like to store the entire decimal. Here is my code, but it is giving me an answer of 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());
Output:
P(3) = 1
Upvotes: 1
Views: 2825
Reputation: 4329
From the 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.
To fix, you need to do something like this:
// numberator / denominator (round down)
probT = BigDecimal.valueOf(numerator).divide(BigDecimal.valueOf(denominator), 10,RoundingMode.DOWN);
where 10 is precision(decimal places precision) and RoundingMode.DOWN is rounding mode
Upvotes: 2
Reputation: 137064
That's because the division you are computing is made with a scale of 0. Quoting the method divide(divisor, roundingMode)
Javadoc:
Returns a
BigDecimal
whose value is(this / divisor)
, and whose scale isthis.scale()
.
In this case, this.scale()
refers to the scale of the numerator, which is 0 because the numerator is BigDecimal.valueOf(n)
, with n
being an integer.
You need to change this division to use divide(divisor, scale, roundingMode)
instead and specify the scale you want.
Upvotes: 6