5

ユーザーが入力した10進数を8進数に変換するCプログラムを作成してみました。私は、他のユーザーがどのようにそれを行おうとしているのかを調査することなく、独自のロジックでCコードを作成しました。数値やその他のいくつかの数値では正常に機能し601ますが、ほとんどの数値では、最後の桁が1本来よりも小さい8進数に相当するものが返されます。の代わりに75戻ります。withを使用すると作業が完了しますが、プログラミングを学ぶという目的を損なうようなものです。これが私のコードです:112113printf%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計算の1つは、100ではなく99.99999999999992のようなものを返します。intに戻すと、0.999 ...の分数が失われ、100ではなく99になります。または、1000ではなく999になります。指数がゼロであるため、1の場所にはありません。正確に1.0を取得する特殊なケース。

ちなみに、32ビットintでは9桁しか取得できないため、int形式で10の累乗を乗算するというsusmitの提案は非常に合理的です。特別な場合を除いて、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);

シフトファクターを持ち、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( "8進数に相当するもの:%lf \ n"、s);

0を返します。}

これで問題は解決すると思います。実際、Pow()はdouble値を返します。コードでは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 に答える