Abhee
Abhee

Reputation: 29

Java BigInteger Returning Incorrect Value

I am trying to generate n digit number with all ones using BigInteger.

for(int i=0;i<n;i++){
    genL = genL.add(BigDecimal.valueOf(Math.pow(10,i)).toBigInteger());
    System.out.println(i + " "+ genL);
            }

I am expecting all ones in the output result sequence. But I am getting the below output. Zero is getting inserted for i = 23 and 24. Is there anything I am missing out?

0 1

1 11

2 111

3 1111

4 11111

5 111111

6 1111111

7 11111111

8 111111111

9 1111111111

10 11111111111

11 111111111111

12 1111111111111

13 11111111111111

14 111111111111111

15 1111111111111111

16 11111111111111111

17 111111111111111111

18 1111111111111111111

19 11111111111111111111

20 111111111111111111111

21 1111111111111111111111

22 11111111111111111111111

23 111111111111111101111111

24 1111111111111111101111111

Upvotes: 2

Views: 536

Answers (4)

Stephen C
Stephen C

Reputation: 718758

Is there anything I am missing out?

Yea. Math.pow(10,i) is returning a double and that only has 53 bits of precision.


You could rewrite your code to use the BigInteger.pow method instead.

However, an (IMO) simpler version would be

genL = BigInteger.ZERO;
for (int i = 0; i < n; i++) {
    genL = genL.mult(BigInteger.TEN) + BigInteger.ONE;
    System.out.println(i + " " + genL);
}

Or if you only care about what the output looks like, just use a string builder / string concatenation; e.g.

genL = new StringBuilder();
for (int i = 0; i < n; i++) {
    genL.append("1");
    System.out.println(i + " " + genL);
}

Upvotes: 10

Eran
Eran

Reputation: 393781

It would be much simpler (and more efficient) to create your BigInteger with the BigInteger(String val) constructor:

new BigInteger("111111111111111111111111111111"); // as many 1s as you want

Or, to generalize:

char[] ones = new char[n];
Arrays.fill(ones,'1');
BigInteger genL = new BigInteger(new String (ones));

Upvotes: 1

AMIL.Y
AMIL.Y

Reputation: 46

You should be using my code as follows, works like a charm!

    BigInteger i = new BigInteger("0");
    BigInteger ten = new BigInteger("10");
    BigInteger one = new BigInteger("1");
    for (int j = 0; j < 64; j++) {
        i = i.multiply(ten).add(one);
        System.out.println(i);
    }

Upvotes: 0

Montri M
Montri M

Reputation: 1766

Math.pow return a double value, which couldn't guarantee an exact accuracy for large number.

In this case, Math.pow(10, 23) returns 1.0000000000000001E23, which when converted to BigInteger, it becomes 100000000000000010000000, thus causing that 0 in the middle.

I'd suggested that you replaced Math.pow(10, i) with BigInteger.TEN.pow(i) instead.

Upvotes: 1

Related Questions