4

I know there are methods shiftLeft(int n) and shiftRight(int n) for BigInteger class which only takes int type as an argument but I have to shift it by a long variable. Is there any method to do it?

Subodh Joshi
  • 12,717
  • 29
  • 108
  • 202
Mani Sankar
  • 800
  • 1
  • 9
  • 19
  • are you sure you want to do it? is your long number really a number which is outside int range? – Raman Shrivastava Sep 12 '15 at 20:33
  • Maybe I'm naive but I think even "just" shifting by Integer.MAX_VALUE is probably a huge undertaking. Please tell me you also need `long` exponents for `pow()`. – musiKk Sep 12 '15 at 20:33
  • yes the long variable might go up to 10^10 @RamanShrivastava – Mani Sankar Sep 12 '15 at 20:34
  • What are you using this for? Hopefully there's an alternative approach – harold Sep 12 '15 at 20:46
  • If your values are sparse (have few bits set) you could represent values using a `Set`, or even a `Set`. I don't know if there are any libraries out there with an integer class that does something like this. – Paul Boddington Sep 12 '15 at 20:50
  • @harold to solve a problem in competitive coding website, where i have to divide the final result by power of 2 and the power can be up to 10^10. May be naive approach doesn't work, should try another approach. – Mani Sankar Sep 12 '15 at 20:54
  • 2
    If it's a coding challenge you can be certain that the naive approach isn't what they are expecting. i.e it's a challenge. Is it something like, what are the last 8 digits of 2^(10^10) for example? – Peter Lawrey Sep 12 '15 at 20:58
  • yes you are right @PeterLawrey but at least I learned a new thing today. Thank you very much for the information. – Mani Sankar Sep 12 '15 at 21:01
  • https://www.codechef.com/SEPT15/problems/CODECRCK this is the problem if you want to look into. Don't reveal the logic I am still trying it ;) @PeterLawrey – Mani Sankar Sep 12 '15 at 21:04

3 Answers3

6

BigInteger can only have Integer.MAX_VALUE bits. Shifting right by more than this will always be zero. Shift left any value but zero will be an overflow.

From the Javadoc

 * BigInteger constructors and operations throw {@code ArithmeticException} when
 * the result is out of the supported range of
 * -2<sup>{@code Integer.MAX_VALUE}</sup> (exclusive) to
 * +2<sup>{@code Integer.MAX_VALUE}</sup> (exclusive).

If you need more than 2 billion bits to represent your value, you have a fairly usual problem, BigInteger wasn't designed for.

If you need to do bit manipulation on a very large scale, I suggest having an BitSet[] This will allow up to 2 bn of 2 bn bit sets, more than your addressable memory.

yes the long variable might go up to 10^10

For each 10^10 bit number you need 1.25 TB of memory. For this size of data, you may need to store it off heap, we have a library which persist this much data in a single memory mapping without using much heap, but you need to have this much space free on a single disk at least. https://github.com/OpenHFT/Chronicle-Bytes

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 2 gigs of memory to represent a single integer... huh, yeah, must be unusual – Dici Sep 12 '15 at 20:46
  • @Dici 2 bn bits is actually 256 MB, but to do anything with it quickly adds up. a = b + 2 * c, already you have 1 GB. if you did a `a * b` using 1 bn bit numbers it would complete in `O(n^2)` time, assuming the machine ran that long, ;) – Peter Lawrey Sep 12 '15 at 20:51
  • 1
    Mmm yeah it's gigs of bits but usually we talk in bytes, true – Dici Sep 12 '15 at 20:54
  • 1
    `Shifting left by more than this will always be zero. Shift right any value but zero will be an overflow.` Left <-> Right need swapping. – biziclop Sep 12 '15 at 21:04
  • @biziclop you are right and I should go to bed. Thank you. – Peter Lawrey Sep 12 '15 at 21:06
4

BigInteger does not support values where long shift amounts would be appropriate. I tried

BigInteger a = BigInteger.valueOf(2).pow(Integer.MAX_VALUE);

and I got the following exception:

Exception in thread "main" java.lang.ArithmeticException: BigInteger would overflow supported range.

Paul Boddington
  • 37,127
  • 10
  • 65
  • 116
0

Since 2 ^ X is equal to 10 ^ (X * ln(2) / ln(10)), we can calculate for X = 10 ^ 10:

2 ^ (10 ^ 10) = 10 ^ 3,010,299,956.63981195...
              = 10 ^ 3,010,299,956 * 10 ^ 0.63981195...
              = 4.3632686... * 10 ^ 3,010,299,956

Meaning 4 followed by more than 3 billion more digits.

That's a very large number and will take some doing storing that to full precision.

Andreas
  • 154,647
  • 11
  • 152
  • 247