C中的十进制转八进制

5

我刚开始自学C语言,使用的是K.N King的《C Programming: A Modern Approach (2ndEdn)》。我很喜欢这本书,但如果有疑问的话,我希望能在这里发帖寻求建议,因为不幸的是我没有导师,而且有些部分引发了更多的问题!

我正在做一个关于将输入的整数显示为八进制的问题。书上说有一种简单的方法,但那会在后面的章节中介绍。我想出了以下解决方案:

// 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页。

感谢您的时间。 安德鲁

附言:我查了搜索引擎,但没有找到任何以“较慢”的方式进行此操作的内容!

9个回答

6
每个人都说使用printf有一种内置方法可以这样做。但是你自己怎么做呢?
首先想到的是一个八进制数字正好是三个比特。因此,您可以按照以下方式进行转换:
  • 循环while n != 0
  • n的最左边的3个比特隔离到d中并打印d
  • n向左移动3个比特
代码很简单,但我不会提供它,所以您可以自己做(您需要熟悉位运算和移位运算符)。

这将会倒序打印数字。 - aaz
@aaz: 哎呀 -- 不是那个“left” :) - Jon
谢谢Jon。我已经记下来了,等到需要的时候再回来看。我距离循环还有两章,距离位运算符和移位运算符还有14章! - aussie_aj
你应该转换为无符号类型。因为在 C 语言中,左移进入有符号位是未定义的。 - Scotty Bauer

4

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

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

干杯!这就解释了为什么这本书在第7章中说我们学习更简单的方式,即类型转换。 - aussie_aj

3

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

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

这适用于 n > 0。


1
/* 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
使用循环,你可以像这样将五行非常相似的代码合并起来:
for (int d = 8 * 8 * 8 * 8; d > 0; d /= 8)
    printf("%d", n / d % 8);
printf("\n");

d 将从 8 * 8 * 8 * 8 开始,这是您用于 n2 的除数,然后通过 8 * 8 * 88 * 88 和最终的 1,这是 n6 的除数,沿途打印每个数字。

一个好的编译器实际上会将其展开成五行,因此您几乎会得到与开始时相同的东西。将其编写为循环的优点在于,您不能在其中一行中犯错误。

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


0

现有的答案不够干净,这是我的:

#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;
}

结果:

{ DEC:     1337, OCT:     2471 }

(a) 当 indecimal = 0; 时,你的代码会生成什么?(b) 为什么 OCTALSIZE 被设置为 8?这可以处理高达 24 位的 int 值,这是一个奇怪的支持大小。 - Jonathan Leffler

0

printf 中使用 %o 格式说明符

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

0

由于只介绍了基础知识,所以你不想(至少在这个阶段)使用函数、循环、位运算符、%o格式说明符和所有那些东西。以下是我的基本解决方案:

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);

请注意,由于输出中不需要n,因此您可以在每个步骤中修改(除以)它(从而节省计算和相对昂贵的除法)。 在八进制中,您可以安全地使用32767(即77777),因为32768(8 * 8 * 8 * 8 * 8 = 8 ^ 5 =(2 ^ 3)^ 5 = 2 ^ 15)是第一个需要六位数字的数字: 100000
这个o变量实际上并不需要,而且当int被签名为16位时(在某些古老的系统上),它也无法工作,因此从这一点开始最好只打印单独的数字。

0

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

#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();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接