Converting between number bases

Discussion in 'C++' started by Alex Buell, Aug 8, 2006.

  1. Alex Buell

    Alex Buell Guest

    Is there an elegant way of converting strings containing digits
    between different number bases in C++?

    I.e.:
    10 (base 2) = 2 (base 10)
    FF (base 16) = 256 (base 10)
    F (base 16) = 1111 (base 2) etc?

    Thanks,
    Alex
    --
    http://www.munted.org.uk

    Take a nap, it saves lives.
     
    Alex Buell, Aug 8, 2006
    #1
    1. Advertising

  2. Alex Buell wrote:
    > Is there an elegant way of converting strings containing digits
    > between different number bases in C++?
    >
    > I.e.:
    > 10 (base 2) = 2 (base 10)
    > FF (base 16) = 256 (base 10)
    > F (base 16) = 1111 (base 2) etc?


    Convert it to internal rep through 'stringstream' by inputting and
    then output it again, using the other base. Or, you can write your
    own conversion routine, which can be made a bit faster...

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 8, 2006
    #2
    1. Advertising

  3. "Alex Buell" <> wrote:

    > Is there an elegant way of converting strings containing digits
    > between different number bases in C++?


    Below I present excerpts from some earlier posts of mine in this group around
    July 2 to July 5 of this year, in which I give a function which prints any
    integer up to nine quintillion in any base from 2 to 30.

    That's not exactly what you asked for, but it's close. If you can
    write the part that converts from any base to a basic 2's-compliment
    C++ integer variable, then you can use my function to print the
    representation of that integer in the base of your choice.


    //============= BEGIN EXCERPTS FROM EARLIER POSTS =====================

    // July 2-5:

    ....For your enjoyment, a function that expresses any integer with
    absolute value less-than-or-equal-to nine quintillion in any
    base from 2 to 36...

    .... if you don't like the non-std type "long long" you can always
    change it to "long"; but then it could only handle numbers up to
    about 2 billion, instead of 9 quintillion...

    // Put this in a header file:

    namespace YourNamespaceName
    {

    ///////////////////////////////////////////////////////////////////////////
    // //
    // Base //
    // Represent an integer in any base from 2 to 36. //
    // //
    ///////////////////////////////////////////////////////////////////////////

    template<typename T>
    std::string
    Base
    (
    int base, // must be >= 2 and <= 36
    int precision, // must be >= 1 and <= 63
    T number, // must be >= min+5 and <= max-5 for type
    bool leading_zeros = false // does user want leading zeros?
    )
    {
    T const max = std::numeric_limits<T>::max() - 5;
    T const min = std::numeric_limits<T>::min() + 5;
    double largest = pow(base, precision) - 1;
    if
    (
    base < 2 || base > 36 // If base is out-of-range
    || precision < 1 || precision > 63 // or precision is out-of-range
    || number < min || number > max // or number is out-of-range
    || largest > max // or base/precision combo is out-of-range
    || largest < number // or base/precision combo can't express number
    )
    {
    return std::string("***ERROR***"); // then return "***ERROR***".
    }

    std::string repre = std::string("");
    if (number < 0)
    {
    number = -number;
    repre += '-';
    }

    T place = 1;
    for (int i = 1; i <= precision - 1; ++i)
    {
    place *= base;
    }

    T value = 0;
    const char digits[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    bool first_non_zero = false;
    for ( ; place > 0; place /= base)
    {
    value = number / place;
    if (value > 0) first_non_zero = true;
    if (leading_zeros || first_non_zero) repre += digits[value];
    number -= value * place;
    }
    return repre;

    } // end Base()

    } // end namespace YourNamespaceName


    //============= END EXCERPTS FROM EARLIER POSTS =====================



    --
    Cheers,
    Robbie Hatley
    Tustin, CA, USA
    lone wolf intj at pac bell dot net
    (put "[usenet]" in subject to bypass spam filter)
    home dot pac bell dot net slant earnur slant
     
    Robbie Hatley, Aug 8, 2006
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ! aaa
    Replies:
    1
    Views:
    1,116
    ! aaa
    May 28, 2004
  2. ferran
    Replies:
    1
    Views:
    1,135
    Victor Bazarov
    Nov 28, 2003
  3. ! aaa
    Replies:
    4
    Views:
    166
    Jay Tilton
    May 28, 2004
  4. PerlFAQ Server
    Replies:
    0
    Views:
    170
    PerlFAQ Server
    Jan 13, 2011
  5. PerlFAQ Server
    Replies:
    0
    Views:
    142
    PerlFAQ Server
    Mar 28, 2011
Loading...

Share This Page