开发者

Decimal to octal in C

I have just begun teaching myself C out of K.N King's C Programming: A Modern Approach (2ndEdn).

I'm enjoying it, but am hoping to post the odd question here for advice if appropriate because unfortunately I don't have a tutor and some bits raise more questions then they answer!

I'm doing a question on taking an integer entered and displaying it in octal. It says there is an easy way to do it, but that comes later in the book. I have come up with the following:

// Convert a number to octal

int n, n2, n3, n4, n5, n6;

printf("Enter a number between 0 and 32767: ");

scanf("%d", &n);

n6 = n % 8;
n5 = (n / 8) % 8;
n4 = ((n / 8) / 8) % 8;
n3 = (((n / 8) / 8) / 8) % 8;
n2 = ((((n / 8) / 8) / 8) / 8) % 8;

printf("%d%d%d%d%d", n2, n3, n4, n5, n6);

It works OK, but I'm开发者_如何学Python not good at math and was wondering if there is a more efficient way of doing this or have I done it the only way possible...

If anyone else has the book it's Q4 p.71.

Thanks for your time. Andrew

P.S I did look in the search engine but couldn't find anything that was doing it this 'slower' way!


Everyone is right in saying that there's a built-in way to do that with printf. But what about doing it yourself?

The first thing that came to mind is that one octal digit is exactly three bits. Therefore you can do the conversion this way:

  • Loop while n != 0
  • Isolate the leftmost 3 bits of n into d and print d
  • Shift n 3 bits to the left

The code is trivial, but I 'm not providing it so you can do it yourself (you will need to be familiar with the bitwise and shift operators in order to do it).


The easy way is probably to use printf()'s %o format specifier:

scanf("%d", &n);
printf("%o", n);


Others have posted the real, production code answer, and now I see from your comments that you haven't done loops yet. Perhaps your book is trying to teach you about recursion:

void print_oct(int n)
{
    if (n != 0) {
        print_oct(n / 8);
        printf("%d", n % 8);
    }
}

This works for n > 0.


With loops you can roll up your five very similar lines like this:

for (int d = 8 * 8 * 8 * 8; d > 0; d /= 8)
    printf("%d", n / d % 8);
printf("\n");

d will start at 8 * 8 * 8 * 8, which is the divisor you use for n2 and then step through 8 * 8 * 8, 8 * 8, 8 and finally 1, which is the divisor for n6, printing each digit along the way.

A good compiler will actually optimize this by unrolling it back into five lines, so you'll get almost the same thing you started with. The advantage of writing it as a loop is that you can't make a mistake in just one of the lines.

The compiler will also take care of replacing divisions by 8 with shifts by 3 bits. Both give the same result in binary, but the latter is faster.


/* Converts a positive base_10 into base_b */
int DecimalToBase(int n, int b)
{
    int rslt=0, digitPos=1;
    while (n)
    {
        rslt += (n%b)*digitPos;
        n /= b;
        digitPos *= 10;
    }
    return rslt;
}


Use %o format specifier inside printf

printf("Enter a number between 0 and 32767: ");
scanf("%d", &n);
printf("%o", n);


Since only basics are introduced you don't want (at least at this point) to use functions, loops, bitwise operators, %o format specifier and all that stuff. Here is my basic solution:

int n, d1, d2, d3, d4, d5, o;

printf("Enter a number between 0 and 32767: ");
scanf("%d", &n);

d5 = n % 8;
n /= 8;
d4 = n % 8;
n /= 8;
d3 = n % 8;
n /= 8;
d2 = n % 8;
n /= 8;
d1 = n % 8;

o = 10000 * d1 + 1000 * d2 + 100 * d3 + 10 * d4 + d5;

printf("In octal, your number is: %.5d\n", o);

Note that since n is not needed in output, you can modify (divide) it for every step (thus saving divides, which are computationally and relatively expensive). You are safe up to 32767 (in octal: 77777), as 32768 (8*8*8*8*8 = 8^5 = (2^3)^5 = 2^15) is the first number, that requires six digits in octal: 100000.

This o variable is not really needed, morever it will not work when int is signed 16-bit (on some ancient system), so from this point it's better to just print separate digits.


Existing answers aren't clean enough for my liking. Here's mine:

#include <stdio.h>

#define OCTALBASE    8
#define OCTALSIZE    8

int main(int argc, char **argv) {
  int indecimal = 1337;
  char output[OCTALSIZE + 1];
  output[OCTALSIZE] = '\0';

  int outindex = OCTALSIZE;
  int outdigit = 0;
  int outvalue = indecimal;
  while (--outindex >= 0) {
    outdigit = outvalue % OCTALBASE;
    if (outvalue > 0 || outdigit > 0)
      { output[outindex] = '0' + outdigit; }
    else { output[outindex] = ' '; }
    outvalue /= OCTALBASE;
  }

  fprintf(stdout, "{ DEC: %8d, OCT: %s }\n", indecimal, output);
  fflush(stdout);

  return 0;
}

Result:

{ DEC:     1337, OCT:     2471 }


Convert Decimal to Octal in C Language

#include<stdio.h>
#include<conio.h>
void main()
{
    A:
    long int n,n1,m=1,rem,ans=0;
    clrscr();
    printf("\nEnter Your Decimal No :: ");
    scanf("%ld",&n);

    n1=n;
    while(n>0)
    {
        rem=n%8;
        ans=(rem*m)+ans;
        n=n/8;
        m=m*10;
    }

    printf("\nYour Decimal No is :: %ld",n1);
    printf("\nConvert into Octal No is :: %ld",ans);

    printf("\n\nPress 0 to Continue...");
    if(getch()=='0')
        goto A;
    printf("\n\n\n\tThank You");
    getch();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜