Rapid Readers
Rapid Readers

Reputation: 315

In java, how do I divide two BigIntegers and store the value in a double?

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

Answers (8)

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

Amber Beriwal
Amber Beriwal

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

Sid
Sid

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

Joe C
Joe C

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

Justin Singh-M.
Justin Singh-M.

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

Jason Hoetger
Jason Hoetger

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

marlon
marlon

Reputation: 1

BigInteger's divide method returns a BigInteger whose value is {@code (this / val)}.Y

Upvotes: 0

Md Samiul Alim Sakib
Md Samiul Alim Sakib

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

Related Questions