c++decimaloctal

What is the best way to convert unsigned integers to their octal representations and vice versa in C++?


Currently I'm using while loops:

std::string to_octal(unsigned int num)
{
    int place = 1, remainder, octal = 0;
    while (num != 0)
    {
        remainder = num % 8;
        decimal /= 8;
        octal += remainder * place;
        place *= 10;
    }
    return std::to_string(octal);
}

unsigned int to_num(std::string octal)
{
    unsigned int octal_n = std::stoi(octal);
    int place = 1, remainder, num = 0;
    while (num != 0)
    {
        remainder = octal_n % 10;
        octal_n /= 10;
        num += remainder * place;
        place *= 8;
    }
    return num;
}

Which seems inefficient. Is there a better way to do this?


Solution

  • There is no such thing as decimal unsigned int, hexadecimal unsigned int or octal unsigned int. There is only one unsigned int. There is a difference only when you want to print an object of that type to the terminal or a file. From that point of view, the function

    unsigned int decimal_to_octal(unsigned int decimal);
    

    does not make sense at all. It makes sense to use:

    struct decimal_tag {};
    struct hexadecimal_tag {};
    struct octal_tag {};
    
    // Return a string that represents the number in decimal form
    std::string to_string(unsigned int number, decimal_tag);
    
    // Return a string that represents the number in hexadecimal form
    std::string to_string(unsigned int number, hexadecimal_tag);
    
    // Return a string that represents the number in octal form
    std::string to_string(unsigned int number, octal_tag);
    

    and their counterparts.

    // Extract an unsigned number from the string that has decimal representation
    unsigned int to_number(std::string const& s, decimal_tag);
    
    // Extract an unsigned number from the string that has hexadecimal representation
    unsigned int to_number(std::string const& s, hexadecimal_tag);
    
    // Extract an unsigned number from the string that has octal representation
    unsigned int to_number(std::string const& s, octal_tag);
    

    Here's demonstrative program:

    #include <iostream>
    #include <string>
    #include <iomanip>
    #include <sstream>
    
    struct decimal_tag {};
    struct hexadecimal_tag {};
    struct octal_tag {};
    
    // Return a string that represents the number in decimal form
    std::string to_string(unsigned int number, decimal_tag)
    {
       std::ostringstream str;
       str << std::dec << number;
       return str.str();
    }
    
    // Return a string that represents the number in hexadecimal form
    std::string to_string(unsigned int number, hexadecimal_tag)
    {
       std::ostringstream str;
       str << std::hex << number;
       return str.str();
    }
    
    // Return a string that represents the number in octal form
    std::string to_string(unsigned int number, octal_tag)
    {
       std::ostringstream str;
       str << std::oct << number;
       return str.str();
    }
    
    // Extract an unsigned number from the string that has decimal representation
    unsigned int to_number(std::string const& s, decimal_tag)
    {
       std::istringstream str(s);
       unsigned int number;
       str >> std::dec >> number;
       return number;
    }
    
    // Extract an unsigned number from the string that has hexadecimal representation
    unsigned int to_number(std::string const& s, hexadecimal_tag)
    {
       std::istringstream str(s);
       unsigned int number;
       str >> std::hex >> number;
       return number;
    }
    
    // Extract an unsigned number from the string that has octal representation
    unsigned int to_number(std::string const& s, octal_tag)
    {
       std::istringstream str(s);
       unsigned int number;
       str >> std::oct >> number;
       return number;
    }
    
    int main()
    {
       unsigned int n = 200;
       std::cout << "200 in decimal: " << to_string(n, decimal_tag()) << std::endl;
       std::cout << "200 in hexadecimal: " << to_string(n, hexadecimal_tag()) << std::endl;
       std::cout << "200 in octal: " << to_string(n, octal_tag()) << std::endl;
    
       std::cout << "Number from decimal form (200): " << to_number("200", decimal_tag()) << std::endl;
       std::cout << "Number from hexadcimal form (c8): " << to_number("c8", hexadecimal_tag()) << std::endl;
       std::cout << "Number from octal form (310): " << to_number("310", octal_tag()) << std::endl;
    }
    

    and its output:

    200 in decimal: 200
    200 in hexadecimal: c8
    200 in octal: 310
    Number from decimal form (200): 200
    Number from hexadcimal form (c8): 200
    Number from octal form (310): 200