C++ Changing a decimal to octal, output backwards

10,033

Solution 1

You need to take a sum and then print the final result, something like

int n=0;
while (octal > 0) {
  total += (pow(10,n++))*(octal % 8);
  octal /= 8;
}
cout << total << endl;

Just printing the digits will print them in reverse order since you are printing the smallest bits first.

As noted in the comments, the mechanism above will only work for converting to bases smaller than 10.

Solution 2

You can use std::oct to print number in octal notation.

int n = 123;
std::cout << std::oct << n << std::endl;

Similarly you can print number in different notations like decimal - std::dec and hexadecimal - std::hex.

Those input/output manipulators allow user to parse string numbers in various notations.

int n;
std::istringstream("24") >> std::hex >> n;
std::cout << n << std::endl;  // n is 36 (decimal)

Solution 3

Here are two handy functions which might be useful. They return string for each of the conversions. On similar lines to igleyy's answer.

string toOctalFromDecimal (int num) {
    ostringstream o;
    o << std::oct << num;
    return o.str();
}

string toDecimalFromOctal (int num) {
    std::ostringstream o;
    int x;

    std::istringstream(to_string(num)) >> std::oct >> x;
    o << std::dec << x;
    return o.str();
}

Solution 4

You are doing fine but you have to print the remainders in reverse order to get the correct answer . For e.g. if ans is 17 then decimal equivalent will be 1*8^1+7*8^0 . unit digit will be the remainder obtained by dividing the number by 8 , next digit to the left will be the remainder obtained by dividing the number by 8^2 and so on. So if the number in octal is of n digit then the most significant digit will be the remainder obtained by dividing the number by 8^n.That is why you have to print the remainder in reverse order.

Solution 5

A solution using an array for temporary storage:

int octal, total = 0, length=0;
char storage[12];   /* 11 octal digits add up to > 1 billion */
octal = 123;
while (octal > 0)
{
  storage[length] = octal % 8;
  octal /= 8;
  length++;
}
while (--length >= 0)
  printf ("%d", storage[length]);
printf ("\n");

(I happened to be in C mode, hence the printfs. Change to cout where required.)

The most important point is that you are bound by the storage size. You can set it to a reasonable size -- the largest positive octal size you can put in an integer is 017777777777 --, and even an unreasonable size is acceptable (you can set it to 20, which will only waste 8 additional bytes; these days, that's nothing). The storage size is determined by how big the representation of your number is in octal, for the largest number you can enter.

Suppose you change both 8s to 2; then you can use this same routine for binary output. But at that point, the number of output characters increases to 31! (One less than the [likely] number of bits in your int, because the last bit would toggle the number to negative. You need separate code to handle negative numbers.)

It works as-is for all bases <=10 (including "base 10" itself). If you want to extend the same code to handle bases >10, such as "duodecimal" (base 12) or hexadecimal (base 16), you need to change the printf line. This will make your code work up to base 36 ("sexatrigesimal"). Per convention, "digits" higher than 9 are written A,B,C and so on:

while (--length >= 0)
  printf ("%c", storage[length] < 10 ? storage[length]+'0' : storage[length]+'A'-10);

(As I'm making this up as I write, I used the ternary operator ?..:.. for convenience, rather than a separate if..else, which needs more typing. (OTOH, adding the comment negates the gain. Oh well -- at least you learned about the ternary operator, as well as the names for a couple of number bases.))


Another solution is to use recursion. This is a useful method because it doesn't need to preallocate some space in memory -- instead, it relies on the internal call stack.

The principle is that you write a function that only prints the last digit of your number -- but before it does that, unless the remainder is 0, it calls itself with the remainder of the number.

So the function calls itself, then prints the number it should. Because it first calls itself, the called version prints the number it should -- the one to the left of the digit in the "original" function. And so on and so forth, until there is no digit remaining to be printed. From that point on, the last called function prints its number (which is the leftmost digit), returns to the function it was called from, which in turn prints its number (one more to the right), all the way down to the original call.

Recursion is a pretty cool skill to master, so do try this!

Share:
10,033
user2970001
Author by

user2970001

Updated on June 14, 2022

Comments

  • user2970001
    user2970001 almost 2 years

    So I wrote this small application that will convert a decimal to octal, and it is outputting the right answer only it's backwards. An example would be that if the answer to the conversion was 17, the application would display it as 71. Any help would be much appreciated.

    ;
        int _tmain(int argc, _TCHAR* argv[])
    {   
    int octal, total = 0;
        cout<< "please enter a decimal: ";
        cin >> octal;
        while(octal > 0)
        {
                    total = octal % 8;
            octal /= 8;
            cout << total;
        }
        cout << endl;
            _getche(); 
            return 0;
    }
    
  • VoidStar
    VoidStar over 10 years
    Did'nt you forget to octal /= 8? Otherwise the loop will never stop
  • Jongware
    Jongware over 10 years
    Nice solution, but this converts the input to a decimal notation. The same algorithm would not work for hexadecimal.
  • abiessu
    abiessu over 10 years
    Typing faster than my mental code writer could follow... Thanks for the heads up
  • user2970001
    user2970001 over 10 years
    Can I ask what the expt is?
  • abiessu
    abiessu over 10 years
    @user2970001: it is the function that returns the value of 10 to the power n. I forget, the name of that function might actually be pow in C++...