5

我尝试制作一个 C 程序来将用户输入的十进制数转换为八进制。我用自己的逻辑编写了 C 代码,没有研究其他用户如何尝试这样做。它适用于数字601和其他一些数字,但对于大多数数字,它返回等效的八进制数,最后一位数字1小于应有的数字。因为75它返回112而不是113. 我意识到使用printfwith%o可以完成工作,但这有点违背学习编程的目的。这是我的代码:

#include <stdio.h>
#include <math.h>

/* converting decimal to octal */

int main() 
{
    int n,x,y,p,s;
    printf("Enter a decimal number ");
    scanf("%d",&x);
    s=0;p=0;

    while (x!=0)
    {
         y=x%8;
         s=s+y*pow(10,p);
         x=(x-y)/8;
         p=p+1;
    }  

  printf("the octal equivalent is: %d\n",s);
  getch();
  return 0;
}
4

6 回答 6

6

这是一种有趣的方式。我会为了原创性而对这个问题投赞成票。

通过添加一个软糖因子来解决这个问题:

s = s + y*pow(10,p) + 0.1;

问题是浮点精度。其中一个 pow 计算返回类似 99.99999999999992 而不是 100。转换回 int 会丢失 0.999... 分数并得到 99 而不是 100。或 999 而不是 1000。它不在一个位置,因为零指数是恰好得到 1.0 的特殊情况。

顺便说一句,由于您只能在 32 位 int 中得到 9 位数字,因此 susmit 以 int 形式乘以 10 的幂的建议是相当合理的。除特殊情况外,pow 会将 pow(x,y) 计算为 exp(y*log(x))。exp() 和 log() 往往是昂贵的计算。

更顺便说一句,即使强制 exp 和 log 计算,我也无法重现该问题。我得到 (10 + 1.8e-15)、(100 + 4.3e-14) 和 (1000 + 6.8e-13) 的值,所有四舍五入都是正确的,因为错误都是正数。这是在 x86 上,我相信我用 VC++2008 编译了这个计算器。你用的是什么编译器?

于 2012-11-02T04:40:15.343 回答
1

替代第一个答案,而不是

s=s+y*pow(10,p);

有一个 shiftfactor,初始化为 1,然后做

s += y*shiftfactor;
shiftfactor *= 10;

此外,代替 x=(xy)/8; 只做 x/=8 就足够了;由于整数舍入。

于 2012-11-02T05:11:46.840 回答
0
#include <stdio.h>
#include <math.h>

/* converting decimal to octal */

int main()
{
   int n, x, y, p;
   double s = 0;
   printf("Enter a decimal number ");
   scanf("%d", &x);

   p = 0;

   while (x != 0)
   {
        y = x % 8;
        s = s + (double)y * pow(10, p);
        x = ( x - y ) / 8;
        p = p + 1;
}

printf("八进制等效值为:%lf\n",s);

返回0;}

我认为这将解决您的问题。实际上 Pow() 返回双精度值。在您的代码中,您使用了 int,因此小数部分将被截断并放入变量“s”中。

于 2012-11-02T06:15:19.540 回答
0
#include <stdio.h>
int main()
{
    int d_num = 0;
    int o_num = 0;
    int factor = 1;

    printf("Enter a decimal number: ");
    scanf("%d", &d_num);

    while (d_num > 0) {
            o_num += d_num % 8 * factor;
            d_num /= 8;
            factor *= 10;
    }

    printf("Octal equivalent: %d\n", o_num);
    return 0;
}

对我来说,这段代码只适用于整数运算。

于 2012-11-02T06:41:25.113 回答
0

为什么你需要使用x=(x-y)/8. 为什么你不能用x=x/8。它与 lhs 和 rhs 中使用的变量类型都是整数的效果相同。顺便说一句,代码对我有用。我认为问题在于整数舍入。只需x=(x-y)/8替换x=x/8

于 2012-11-02T06:42:06.290 回答
0

OP 前段时间解决了这个问题,但我想我会提出一个简单的解决方案。

/* converting decimal to octal */
unsigned decimal_to_octal(unsigned x) {
  if (x < 8) {
    return x;
  }
  return decimal_to_octal(x/8)*10 + x%8;
}

测试代码

unsigned test10to8(void) {
  for (;;) {
    unsigned x;
    scanf("%d", &x);
    printf("x:%u y:%u\n", x, decimal_to_octal(x));
  }
}
于 2015-08-27T13:09:43.540 回答