views:

614

answers:

8

I've encountered a website that uses a 50-digit decimal integer ID in a URL query string, which seems a little excessive.

The smallest 50-digit decimal number is 1.0 x 10^49, otherwise known as:

1000000000
0000000000
0000000000
0000000000
0000000000
  1. How many bits would the binary representation contain?
  2. How would you approach converting such a large decimal number to binary, taking into consideration the range limit of unsigned 32-bit-integer or 64-bit integers?

I ask out of pure programmer curiosity only - this is not a college question, work problem or interview puzzle!

+4  A: 

Since every decimal digit conveys the same information as lb 10 bits, any 50 digit number will fit into ceil(lb(10)*50) = 167 bits.

Specifically, it's not that hard to convert from decimal to binary, even by hand. Just divide by two, and put the modulus(1 if the last digit was odd, 0 if even) at the end of your binary result. If you need such high numbers in a program, just use your platform's big integer implementation, e.g. BigInteger in Java and just int in python. In the absence of that, look for a numerical library.

Oh, and 10^49 in binary is 163 bit long:

110
1101 0111 1001 1111 1000 0010 0011 0010
1000 1110 1010 0011 1101 1010 0110 0001
1110 0000 0110 0110 1110 1011 1011 0010
1111 1000 1000 1010 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
phihag
A: 

1) 2^10 ~ 10^3 so 10^48 ~ 2^160; 10^49 will be a 164 bit quantity.

2) Use a BigInteger or MPI class (of which there are plenty to be found if your language standard API library doesn't come with one). Knuth has the details.

Steve Gilham
+8  A: 

The minimal binary representation(with integer precision) can be found by taking the log (base 2) of the number. In this case the minimal amount of binary bits would be log(10^49) = 162.77. We need a whole number so we will just call it 163 bits.

If I had to represent that number, and the precision in a floating point representation was insufficient, I would just use some BigInteger library.

Falaina
The interesting part is how could one compute the number of bits without being able to compute log(10^49). Sure, we all have a scientific calculator, bit how could that be done without one?
sharptooth
Logarithm base conversion. See Martin B's answer.
Vilx-
@sharptooth: multiply number of digits in base10 with (log(10) / log(2)), a constant, and you will have your answer in number of bits.
Thomas
If you have BigInt support, but no logarithm, start with the value 2 = 1 bit, and double the value and increase the number of bits, so 2=1, 4=2, 8=3, 16=4, 32=5, etc. and when the value is equal to or higher than your goal, you got the number of bits necessary.
Lasse V. Karlsen
Actually, when "value-1" is equal to or higher than your goal, to be precise, and this is for unsigned values. If signed, add 1 bit.
Lasse V. Karlsen
@sharptooth calculating the numeric value of a logarithm is a relatively tedious task. The first step you would take is to simplify it as much as you can as Martin B did. Though at that point you'd still need to calculate log(2) which could be calculated using one of the algorithms @ http://en.wikipedia.org/wiki/Common_logarithm#Numeric_value
Falaina
10 bits = 1024 is a little more than 3 digits = 1000, which implies that one digit is worth a little less than 10 / 3 = 3.333... bits. 49 * 10 / 3 = 163.333... comes close to the exact result.
starblue
+6  A: 
  1. 49 * log(10) / log(2) = 162.774477, so the binary representation would contain 163 bits.

  2. Use a bigint class and apply the standard algorithm for converting from decimal to binary.

Martin B
+1 for the logarithm base convertion formula. IMHO this is the way to go in this question.
Vilx-
+1  A: 

One could use a suitable longinteger manipulation library for converting such numbers. If using is not allowed reading the source can give useful knowledge of how such things are done efficiently.

Regarding the number of bits you just need to solve the equation:

2N = 1050

take a log2 of both parts:

N = log21050

Now convert log2 to log10:

N = log21050 = log101050/log102 = 50 / log102

Take the next integer (ceil) of N - that's the number of bits required.

sharptooth
A: 

What do you mean exactly by storing number X?

  1. Do you mean storing all the numbers between 0 and X?
  2. Or all the numbers between -X and X?
  3. Or only storing the information: null / X.

My gut feeling is the interviewer might have meant the third one. The answer would be 1 bit.

Grzegorz Oledzki
A: 

I'd use a high-level language that handles big integers for me. Sample irb (Ruby) session:

>> (10**49).to_s
=> "10000000000000000000000000000000000000000000000000"
>> (10**49).to_s(2)
=> "1101101011110011111100000100011001010001110101000111101101001100001111000000110011011101011101100101111100010001010000000000000000000000000000000000000000000000000"
>> (10**49).to_s(2).size
=> 163
Nefrubyr
A: 

50 digit decimal integers range from 10^49 to 10^50-1. 10^49 is 163 bits, and 10^50-1 is 167 bits. If you want the EXACT number of bits, you need to take the logarithm of those big numbers directly, as opposed to just computing the "shortcut" 50*log10(2).

As an alternative, you can convert the number to binary using an arbitrary precision decimal-binary converter and count the bits (BTW, the converter I linked to counts the bits for you).

Rick Regan

related questions