3

I came across an interesting math problem that would require me to do some artithmetic with numbers that have more than 281 digits. I know that its impossible to represent a number this large with a system where there is one memory unit for each digit but wondered if there were any ways around this.

My initial thought was to use a extremely large base instead of base 10 (decimal). After some thought I believe (but can't verify) that the optimal base would be the square root of the number of digits (so for a number with 281 digits you'd use base 240ish) which is a improvement but that doesn't scale well and still isn't really practical.

So what options do I have? I know of many arbitrary precision libraries, but are there any that scale to support this sort of arithmetic?

Thanks o7

EDIT: after thinking some more i realize i may be completely wrong about the "optimal base would be the square root of the number of digits" but a) that's why im asking and b) im too tired to remember my initial reasoning for assumption.

EDIT 2: 1000,000 in base ten = F4240 in base 16 = 364110 in base 8. In base 16 you need 20 bits to store the number in base 8 you need 21 so it would seem that by increasing the base you decrees the total number of bits needed. (again this could be wrong)

Letseatlunch
  • 2,432
  • 7
  • 28
  • 33
  • What operations would you be performing on these numbers? – templatetypedef Feb 08 '12 at 04:29
  • @templatetypedef just simple addition/subtraction and multiplication/division (and yes i realize even with FFT i'd be only a little less than linearly slow) – Letseatlunch Feb 08 '12 at 04:31
  • 2
    "that the optimal base would be the square root of the number of digits" optimal for what? The amount of information that you will need to store will be the same regardless of the base that you use. – Sunny88 Feb 08 '12 at 04:32
  • Can you describe that problem in more detail? Perhaps there's a better approach to solving it. – templatetypedef Feb 08 '12 at 04:33
  • 3
    2^81 decimal digits require approximately 2^269 bits to represent exactly. I don't think there are any shortcuts, unless you know some significant portion of the digits will be zero. – Mark Ransom Feb 08 '12 at 04:48
  • @Sunny88 "The amount of information that you will need to store will be the same regardless of the base that you use." i don't think this is true based on my argument in "edit 2" – Letseatlunch Feb 08 '12 at 05:02
  • 3
    Regarding edit 2, whether you write the number out using base 8 or base 16 doesn't affect how many bits it actually takes up, because they both translate back into binary in the same way, and binary is how these numbers are actually stored. The hexadecimal representation becomes `1111 0100 0010 0100 0000` and the octal one becomes `011 110 100 001 001 000 000`. The latter has a leading zero because of how you've chosen to group those bits, but the leading zero doesn't need to be stored. – David Z Feb 08 '12 at 06:00
  • @MarkRansom To store 2^81 decimal digits does not require 2^269 bits. Every digit can be stored by at most 4 bits, so the number is at most 4*(2^81), or 2^83, not 2^269. – Sunny88 Feb 08 '12 at 08:10
  • @Sunny88, thanks - it was late when I wrote that, it's my only excuse. Still 2^83 is far too many bits to fit in memory. – Mark Ransom Feb 08 '12 at 14:25

3 Answers3

3

This is really a compression problem pretending to be an arithmetic problem. What you can do with such a large number depends entirely on its Kolmogorov complexity. If you're required to do computations on such a large number, it's obviously not going be arrive as 2^81 decimal digits; the Kolmogorov complexity would too high in that case and you can't even finish reading the input before the sun goes out. The best way to deal with such a number is via delayed evaluation and symbolic rational types that a language like Scheme provides. This way a program may be able to answer some questions about the result of computations on the number without actually having to write out all those digits to memory.

Kyle Jones
  • 5,492
  • 1
  • 21
  • 30
1

I think you should just use scientific notation. You will lose precision, but you can not store numbers that large without losing precision, because storing 2^81 digits will require more than 10^24 bits(about thousand billion terabytes), which is much more that you can have nowadays.

Sunny88
  • 2,860
  • 3
  • 24
  • 25
  • where do you get 10^24 bits from? – Letseatlunch Feb 08 '12 at 04:44
  • @Letseatlunch 24 is log(2^84), actually it is 25, but it is still more than 24. I just changed 2^84 into base 10 notation. – Sunny88 Feb 08 '12 at 04:48
  • @Sunny88: To store 2^81 decimal digits you'll need 2^269 bits. To store 2^81 bits you'll need 2^81 bits, even if they can be represented by 10^24 decimal digits. Digit takes more than one bit. Keep that in mind. – SigTerm Feb 08 '12 at 07:25
  • 1
    @SigTerm To store 2^81 decimal digits does not require 2^269 bits. Every digit can be stored by at most 4 bits, so the number is at most 4*(2^81), or 2^83, not 2^269. – Sunny88 Feb 08 '12 at 08:04
1

that have more than 2^81 digits

Non-fractional number with 2^81 bits, will take 3*10^11 terabytes of data. Per number.

That's assuming you want every single digit and data isn't compressible.

You could attempt to compress the data storing it in some kind of sparse array that allocates memory only for non-zero elements, but that doesn't guarantee that data will be fit anywhere.

Such precision is useless and impossible to handle on modern hardware. 2^81 bits will take insane amount of time to simply walk through number (9584 trillion years, assuming 1 byte takes 1 millisecond), never mind multiplication/division. I also can't think of any problem that would require precision like that.

Your only option is to reduce precision to first N significant digits and use floating point numbers. Since data won't fit into double, you'll have to use bignum library with floating point support, that provides extremely large floating point numbers. Since you can represent 2^81 (exponent) in bits, you can store beginning of a number using very big floating point.

1000,000 in base ten

Regardless of your base, positive number will take at least floor(log2(number))+1 bits to store it. If base is not 2, then it will take more than floor(log2(number))+1 bits to store it. Numeric base won't reduce number of required bits.

SigTerm
  • 26,089
  • 6
  • 66
  • 115