C中的十进制到八进制

Decimal to octal in C

我刚刚开始教自己K.N.King的C编程:一种现代方法(2ndedn)。

我很享受,但我希望在适当的时候把这个奇怪的问题贴在这里征求意见,因为不幸的是,我没有导师,有些人会提出更多的问题,然后他们会回答!

我在做一个关于取一个输入的整数并以八进制显示它的问题。它说有一个简单的方法来做它,但在书的后面。我提出了以下几点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 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);

它可以工作,但我不擅长数学,我想知道是否有一种更有效的方法来做这件事,或者我做了唯一可能的方法…

如果其他人有这本书的话,那就是第4季度的71页。

谢谢你的时间。安得烈

另外,我的确在搜索引擎中搜索过,但找不到任何东西是这样"慢"地做的!


每个人都说,有一种内置的方法可以用printf实现这一点,这是正确的。但是你自己做呢?

首先想到的是一个八进制数字正好是三位。因此,您可以这样进行转换:

  • 回路while n != 0
  • n的最左边3位隔离到d中,并打印d
  • 左移n3位

代码很简单,但我并没有提供它,所以您可以自己做(您需要熟悉位和移位运算符才能做到这一点)。


简单的方法可能是使用printf()%o格式说明符:

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


其他人已经发布了真正的生产代码答案,现在我从您的评论中看到您还没有完成循环。也许你的书在教你递归:

1
2
3
4
5
6
7
void print_oct(int n)
{
    if (n != 0) {
        print_oct(n / 8);
        printf("%d", n % 8);
    }
}

这适用于n>0。


1
2
3
4
5
6
7
8
9
10
11
12
/* 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;
}

通过循环,您可以将五条非常相似的线卷起,如下所示:

1
2
3
4
for (int d = 8 * 8 * 8 * 8; d > 0; d /= 8)
    printf("%d", n / d % 8);
printf("
"
);

d将从8 * 8 * 8 * 8开始,这是您用于n2的除数,然后依次通过8 * 8 * 88 * 881,这是n6的除数,一路打印每个数字。

一个好的编译器实际上会通过将它展开为五行来优化它,这样您将得到与开始时几乎相同的东西。把它写成循环的好处是你不能只在其中一行中犯错误。

编译器还将负责用3位的移位替换8的除法。二者都给出了相同的二进制结果,但后者更快。


用C语言将十进制转换为八进制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<stdio.h>
#include<conio.h>
void main()
{
    A:
    long int n,n1,m=1,rem,ans=0;
    clrscr();
    printf("
Enter 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("
Your Decimal No is :: %ld"
,n1);
    printf("
Convert into Octal No is :: %ld"
,ans);

    printf("

Press 0 to Continue..."
);
    if(getch()=='0')
        goto A;
    printf("


\tThank You"
);
    getch();
}


现有的答案不够清楚,我不喜欢。这是我的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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 }
"
, indecimal, output);
  fflush(stdout);

  return 0;
}

结果:

1
{ DEC:     1337, OCT:     2471 }


由于只介绍了基本的内容,所以您不希望(至少在这一点上)使用函数、循环、位运算符、%o格式说明符以及所有这些内容。以下是我的基本解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
"
, o);

请注意,由于输出中不需要n,因此您可以为每个步骤修改(分割)它(从而节省了分割,这是计算上的,而且比较昂贵)。你在32767之前是安全的(八进制:77777,因为32768是第一个数字(8*8*8*8*8=8^5=(2^3)^5=2^15),需要六位八进制数字:100000

这个o变量并不是真正需要的,更重要的是,当int有16位符号(在某些古代系统上)时,它将不起作用,因此从这一点来看,最好只打印单独的数字。


printf中使用%o格式说明符

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