views:

92

answers:

3

Question

Let's say I have a string or array which represents a number in base N, N>1, where N is a power of 2. Assume the number being represented is larger than the system can handle as an actual number (an int or a double etc).

How can I convert that to a decimal string?

I'm open to a solution for any base N which satisfies the above criteria (binary, hex, ...). That is if you have a solution which works for at least one base N, I'm interested :)


Example:

Input: "10101010110101"

-

Output: "10933"
+1  A: 

It depends on the particular language. Some have native support for arbitrary-length integers, and others can use libraries such as GMP. After that it's just a matter of doing the lookup in a table for the digit value, then multiplying as appropriate.

Ignacio Vazquez-Abrams
+1  A: 

This is from a Python-based computer science course I took last semester that's designed to handle up to base-16.

import string

def baseNTodecimal():
    # get the number as a string
    number = raw_input("Please type a number: ")
    # convert it to all uppercase to match hexDigits (below)
    number = string.upper(number)
    # get the base as an integer
    base = input("Please give me the base: ")
    # the number of values that we have to change to base10
    digits = len(number)
    base10 = 0
    # first position of any baseN number is 1's
    position = 1
    # set up a string so that the position of
    # each character matches the decimal
    # value of that character
    hexDigits = "0123456789ABCDEF"
    # for each 'digit' in the string
    for i in range(1, digits+1):
        # find where it occurs in the string hexDigits
        digit = string.find(hexDigits, number[-i])
        # multiply the value by the base position
        # and add it to the base10 total
        base10 = base10 + (position * digit)
        print number[-i], "is in the " + str(position) + "'s position"
        # increase the position by the base (e.g., 8's position * 2 = 16's position)
        position = position * base
    print "And in base10 it is", base10

Basically, it takes input as a string and then goes through and adds up each "digit" multiplied by the base-10 position. Each digit is actually checked for its index-position in the string hexDigits which is used as the numerical value.

Assuming the number that it returns is actually larger than the programming language supports, you could build up an array of Ints that represent the entire number:

[214748364, 8]

would represent 2147483648 (a number that a Java int couldn't handle).

David Antaramian
Looks really cool. Hoewver I can't see where you're doing the array stuff. Can you comment the code? (I don't know python)
Cam
@incrediman: There is no array stuff. Python supports arbitrary-length integers natively. And arbitrary bases from 2 to 36 as well, via `int()`.
Ignacio Vazquez-Abrams
Figures. I was pretty sure that was how this was working, as there are no string or array operations in the code from what I can see, but I did run it and it was successful. I thought maybe `+` was doing the array or string operation, but apparently not. I guess this isn't as useful as I thought.
Cam
There is no array stuff in my code. I was just stating that as an example of you could support very large decimal numbers in languages that can't support integers larger than a certain value. As Ignacio mentioned, Python has very good support for large decimal numbers.
David Antaramian
Well maybe I simply misunderstood what you meant. I guess I don't understand how turning it into an array _after_ using it as an int is any help.
Cam
Python was just the example I had on hand. In any language where arbitrary-length integers are unsupported, you would have to test whether the result (the line `base10 = base10 + (position * digit)` in my code) would overflow an `int` or `decimal` and accommodate as necessary. How you do that depends on how you intend to use this large number later. If it's for output, you could just build up a string since the presentation is what matters. Otherwise, you would probably have to define your own structure that breaks down the number into smaller numbers (hence my array suggestion).
David Antaramian
Fair 'nough :) ... Unfortunately my environment doesn't have arbitrary-length numbers. In any case though it's an interesting bit of code!
Cam
A: 

That's some php code I've just written:

function to_base10($input, $base)
{
  $result = 0;
  $length = strlen($input);
  for ($x=$length-1; $x>=0; $x--)
    $result += (int)$input[$x] * pow($base, ($length-1)-$x);
  return $result;
}

It's dead simple: just a loop through every char of the input string

This works with any base <10 but it can be easily extended to support higher bases (A->11, B->12, etc)

edit: oh didn't see the python code :) yeah, that's cooler