4

I am looking for a Java library that can handle truly huge numbers or suggestions as to how to implement this myself. We are talking way beyond BigInteger. How about 2^39614081257132168796771974655+1 for example.

Clearly I could, theoretically, make use of a TreeSet<BigInteger>, one entry per bit and do all the math old-school but I am looking for something that can actually do some real maths with these numbers using built-in math hardware. I don't expect anything truly fast but I would very much like to get close.

It is likely that the number of set bits may be quite small - I am representing G2 polynomials.

Does anyone know of anything out there?

I suspect a feature of the package must be a setBit(BigInteger i).

Added

Thanks for the suggestion of Apfloat. Sadly the following is not possible. It complains that the second parameter must be a long.

    Apint two = new Apint(2);
    Apint big = new Apint("39614081257132168796771974655");
    ApintMath.pow(two, big);

Please note that I am also open to suggestions as to how to do this myself.

Added - to attempt a reopen.

Please see user2246674's post reminding us how staggeringly enormous these numbers are - I can assure you we are not talking about some ordinary math library here, we are talking some serious Math.pow(age-of-the-universe,atoms-in_the_galaxy) kind of numbers - we are certainly not looking for mere opinionated answers.

Community
  • 1
  • 1
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • This is a "shopping list" question, which is not a good fit for Stack Overflow. (Please see http://meta.stackexchange.com/questions/158809/why-are-shopping-list-questions-bad) – tckmn Jun 17 '13 at 23:31
  • Added *or suggestions as to how to implement this myself*. – OldCurmudgeon Jun 17 '13 at 23:34
  • I added "in notation" to the title and emphasis on HUGE - clearly integers of this size *cannot* be feasibly represented in standard integer encodings. So, while it may be a "shopping question", it is also asking for a *very focused library or approach*. – user2246674 Jun 17 '13 at 23:34
  • @user2246674 - Not sure if you have the English right - could you revisit please? – OldCurmudgeon Jun 17 '13 at 23:36
  • @user2246674 - drastically simplified - good? – OldCurmudgeon Jun 17 '13 at 23:40
  • @OldCurmudgeon Consider searching for math libraries that can "solve algebraic equations" (i.e. like matlab); there might be some relevant results. – user2246674 Jun 17 '13 at 23:45
  • A `TreeSet` sounds good to me, quite honestly. – Louis Wasserman Jun 17 '13 at 23:58
  • Which is why apfloat is what is needed in OP's case – fge Jun 18 '13 at 00:04
  • @LouisWasserman - It does indeed work but it is hideously slow for almost any real application. – OldCurmudgeon Jun 18 '13 at 10:59
  • Interesting question. Are you still using Apint? ...Writing a library for bit-wise sparse big number would be a nice project! – mike Sep 10 '13 at 16:09
  • @mike - I experimented with Apint, it didn't help. I have started to tinker with a sparse huge number library but it won't be ready soon - this is a home project for me. – OldCurmudgeon Sep 10 '13 at 16:31

2 Answers2

8

This isn't an answer; it is here because I think it's important to realize how insanely big such a number is and why a standard arbitrary precision math library will not work - ever.

The library must have support to directly deal with higher-order equations (such as that which powers Wolfram|Alpha). I believe this is a good question to have on SO specifically because numbers of this magnitude must be treated special.


A standard bit encoding won't work here - if this were possible then BigInteger would also likely suffice (as would Apfloat which was mentioned). The fundamental problem is that 2^39614081257132168796771974655 is huge. Like, really, really big. It only makes sense to deal with numbers of this size using equations!

Let's reason how much a standard one's or two's complement encoding takes by looking at the storage required for several common maximum integer values:

  • 2^8 takes 8 bits; or 1 byte (8/8)
  • 2^32 takes 32 bits; or 4 bytes (32/8)
  • 2^64 takes 64 bits; or 8 bytes (64/8)

Thus, 2^39614081257132168796771974655 requires 39614081257132168796771974655/8 (or ~5x10^27) bytes of memory if using a similar encoding.

A terabyte of memory is only 1x10^12 bytes: it requires more than a QUADRILLION TERABYTES to use a standard encoding on a number of this magnitude.

user2246674
  • 7,621
  • 25
  • 28
  • 1
    Good narrative - the ironic part of it all is that 2^39614081257132168796771974655 has just **one** bit set in it. Every single other bit of your quadrillion terabytes is actually zero!! – OldCurmudgeon Jun 18 '13 at 20:16
2

You can do math on this, but only symbolic based calculation, i.e. you cannot reduce this to a real number, you can only process this an expression.

Can you give some example of the operations you want to perform?

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • I want to test [primitivity](http://www.theory.cs.uvic.ca/~cos/inf/neck/PolyInfo.html) of a 96bit G(2) polynomial. – OldCurmudgeon Jun 18 '13 at 10:01
  • For that you need an algaberic library so you don't need to evaluate the value and you will need some smart mathematics to avoid a brute force search e.g. you need something like `(a^n + b^n)` where n is odd = `(a + b)*sumOf(i from 0 to n, - * -1 ^ i * a^i * b^(n-1-i))` which means since your power is odd, you can apply this and it can be factorised. – Peter Lawrey Jun 18 '13 at 12:51
  • Thanks for the suggestions. The nice thing about working in G(2) is that most of the standard math functions have binary equivalents. E.G add/sub are actually **both** xor if you hold the poly as bits. – OldCurmudgeon Jun 18 '13 at 18:12
  • 1
    Excellent intro [here](http://www.ee.unb.ca/tervo/ee4253/poly.shtml). – OldCurmudgeon Jun 18 '13 at 18:20