0

これは不可能かもしれませんが、質問しても問題ないと思いました。非整数の 10 進数を 8 進数に変換する必要があるプログラムがあります。私が知る限り、Java は 8 進数の整数のみを自動的に処理できます。私は、このような数を 8 の累乗に分解することを含む、ちょっとしたコツをまとめました。

.abcd = x * (1/8) + y * (1/64) + z * (1/512) + ......

意味がある場合は、「0.xyz」と表示されます。問題は、これにより、長い数値に対して多くの丸め/切り捨てエラーが発生することです。これを行うより良い方法はありますか?

(編集)小数点の右側の数字を処理するために私が使用してきたアルゴリズムは次のとおりです。

double floatPartNum = Double.parseDouble("0." + temps[1]);
     if (floatPartNum > 0) {
        int p = 1;
        result = result + ".";
        while (floatPartNum > 0 && p < 16) {
           double scale = 1/(Math.pow(8, p));
           int modT = (int)( floatPartNum / scale );
           result = result + modT;
           double modScale = (double)modT * scale;
           floatPartNum -= modScale;
           p++;
        }
     }
4

4 に答える 4

2

ベースJavaでの8進数の浮動小数点または固定小数点のサポートがないことを私は知っています。10進数から8進数を抽出するためのアルゴリズムを示すと、エラーを減らすのに役立つ可能性があります。

于 2012-02-14T03:28:54.640 に答える
1

Float クラスと Double クラスには、数値のビット単位の表現を取得できるメソッドがいくつかあります。たとえばDouble.doubleToLongBits(double)

次に、double-as-bits から仮数部と指数部を抽出し、精度を損なうことなく 8 進数形式に変換できます。


ただし、現在のアルゴリズムを修正する方が簡単な場合があります。精度を損なうことなくアプローチを実装できるはずだと思っていました。(精度がすでに失われている可能性を考慮しましたか?つまり、最初に数値を生成したプロセス/計算で?)

于 2012-02-14T03:52:49.237 に答える
1

出力p < 16を人為的に切り捨てています。あなたのコードを で試してみると1.0/3.0が得られますが0.252525252525252、実際には double には 8 進数を 3 桁追加するのに十分な精度があり0.252525252525252525、それを に変更すると が得られますp < 20。しかし、「長い数字」が気になる場合はdouble、ニーズに対して十分な大きさではないことに気付くかもしれません。

ところで、ループは次のように大幅に単純化できます。

for(int p = 1; floatPartNum > 0 && p < 20; ++p)
{
    floatPartNum *= 8.0;
    result = result + (int)floatPartNum;
    floatPartNum -= (int)floatPartNum;
}

(テスト済み)、これにより、などの必要がすべてなくなりますMath.pow。(Math.pow対数とべき乗を実行することで機能します。単に 8 を掛けるだけの場合、やり過ぎであり、丸めが発生しやすい可能性があります。)

于 2012-02-14T15:51:37.983 に答える
0

このようなものはどうですか?:

  String result = "";
  double floatPartNum = temps[1];
  if( floatPartNum > 0 )
  {
     int p = 1;
     result = result + ".";
     while( floatPartNum > 0 && p < 16 )
     {
        floatPartNum *= 8.0D;
        int modT = (int)floatPartNum;
        floatPartNum -= modT;
        result = result + modT;

        p++;
     }
  }

エラーを導入するための操作がはるかに少なくなります。(申し訳ありませんが、このコードを投稿する前にテストすることはできません。プログラミングツールの近くにいません。)

于 2012-02-14T05:28:15.210 に答える