Reputation: 315
So I'm trying to divide two BigIntegers 22 and 7. In other words, I'm trying to store the first few decimals of b1.divide(b2)
[where b1 = new BigInteger("22")
, and b2 = new BigInteger("7")
] into some datatype. However, if I use a BigDecimal
, it shows an irrepresentable number error, while it doesn't even work for doubles. What should I do? For your convenience, here's the code:
BigInteger b1 = new BigInteger("22");
BigInteger b2 = new BigInteger("7");
BigInteger b3 = b1.divide(b2);
System.out.println(b3);
And here's what shows up in the console:
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decima
l expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(Unknown Source)
at Divider.main(Divider.java:13)
Upvotes: 5
Views: 11472
Reputation: 48258
Since big integers are thought for BIG NUMBERS dont use double (maybe it too big for 64 bits space...) instead use BigDecimal which can take in the constructor a BigInteger too:
BigDecimal b3 = new BigDecimal("22").divide(new BigDecimal("7"), 3, RoundingMode.HALF_EVEN);
System.out.println(b3);
Upvotes: -1
Reputation: 1598
Using BigInteger.divide(...)
will give BigInteger
only, so you will loose the precision of the output if you use this method directly. Below are some solutions.
Solution 1 (using BigInteger
):
BigInteger b1 = new BigInteger("22");
BigInteger b2 = new BigInteger("7");
double d = b1.doubleValue() / b2.doubleValue();
System.out.println(d);
Solution 2 (using BigDecimal
, already defined precision)
BigDecimal b1 = new BigDecimal("22");
BigDecimal b2 = new BigDecimal("7");
BigDecimal b3 = b1.divide(b2, MathContext.DECIMAL32);
System.out.println(b3);
Solution 3 (using BigDecimal
, self controlled precision)
Refer solution given by Jason Hoetger
Upvotes: 13
Reputation: 408
The error you were seeing for BigDecimal is explained well here: ArithmeticException: "Non-terminating decimal expansion; no exact representable decimal result"
By adding precision and rounding off, the issue can be handled. a.divide(b, 2, RoundingMode.HALF_UP) where 2 is precision and RoundingMode.HALF_UP is rounding mode. https://docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html
Your current code with BigIntegers works on Java7.
And to save the result in a double for both BigDecimal and BigInteger:
double b4 = b1.divide(b2,2).doubleValue();
double b4 = b1.divide(b2).doubleValue();
So, BigDecimal:
BigDecimal b1 = new BigDecimal("22");
BigDecimal b2 = new BigDecimal("7");
BigDecimal b3 = b1.divide(b2,2,RoundingMode.HALF_UP);
double b4 = b1.divide(b2,2).doubleValue();
double b5 = b1.divide(b2,2,RoundingMode.HALF_UP).doubleValue();
BigInteger:
BigInteger b1 = new BigInteger("22");
BigInteger b2 = new BigInteger("7");
BigInteger b3 = b1.divide(b2);
double b4 = b1.divide(b2).doubleValue();
Upvotes: 0
Reputation: 15674
Assuming that you are indeed using BigDecimal
(and not BigInteger
): A BigDecimal
is meant to provide a precise decimal value in a way that floating point cannot. However, when dividing 22/7, that has a repeating decimal and thus cannot be represented as-is in a BigDecimal
.
In this case, you need to specify to how many decimal places you wish to round, and how you wish to round (up, down, or nearest). So to round to three decimal places, you will want:
BigDecimal b3 = b1.divide(b2, 3, RoundingMode.HALF_EVEN);
Upvotes: 0
Reputation: 498
If I understand you correctly, you're trying to divide BigInteger b1 by b2 and store it in a BigInteger. However, the quotient of two integers is an integer.
3.14286 (rounded) is not an integer.
You can use BigDecimal
instead:
BigInteger b1 = new BigInteger("22");
BigInteger b2 = new BigInteger("7");
BigDecimal b3 = new BigDecimal(b1.divide((double)b2));
System.out.println(b3);
Upvotes: 0
Reputation: 8127
BigInteger.divide() returns a BigInteger, so you're not going to be able to get "the first few decimals" of any result of BigInteger.divide() unless it is actually an integer.
If b1
and b2
absolutely must be BigIntegers, you can create a BigDecimal from your BigInteger, then use BigDecimal.divide(). You'll need specify the scale of the result in order to control the number of decimal places, as well as a MathContext to determine how to round the answer. For example:
BigInteger b1 = new BigInteger("22");
BigInteger b2 = new BigInteger("7");
BigDecimal quotient = new BigDecimal(b1)
.divide(new BigDecimal(b2), 3, RoundingMode.HALF_EVEN);
System.out.println(quotient);
Results in:
3.143
Upvotes: 3
Reputation: 1
BigInteger's divide method returns a BigInteger whose value is {@code (this / val)}.Y
Upvotes: 0
Reputation: 1114
Here is how to get double value,
BigInteger b1 = new BigInteger("22");
BigInteger b2 = new BigInteger("7");
double b3 = b1.divide(b2).doubleValue();
System.out.println(b3);
Upvotes: -1