2

私は、任意の基数 (2-36) を別の基数 (整数) に変換できるシステムを作成しました。また、任意の実数を基数 10 から他の基数 (2-36) に変換できます。

私の問題は、有理数/無理数を 10 以外の基数から別の基数に変換するときに発生します。

小数点の右側の変換には、次のアルゴリズムを使用します。

1) 入力の小数点の右側 (0.xxxxxx--->) を取り、変換先の基数を掛けます。

2) 1 より大きい数値 (点の左側) を取り、変換された数値の右側に追加します。

3) 積の右辺を取り、次の繰り返しで乗数として使用します (基数に掛けます)。

4) 満足するまで繰り返すか、整数 (右側に 0) を残します。

これは、浮動小数点数を 10 進数から別の基数に変換する場合にうまく機能しますが、明らかに、10 進数でない基数から FROM を変換することはできません。

だから私が試したのは、その初期値を小数点の右側にある10を基数に変換し、数学部分を実行してから、それを出力値に追加するときに元の基数に戻すことです(前に新しい基数に変換されます)追加されています)。

残念ながら、これは小数点の右側に対して誤った結果を返します。したがって、10 を基数としていない基数から変換すると、左側は常に正しいが、右側は正しくない答えが得られます。

これを機能させる方法についてのアイデアはありますか?それとも、そうではないのでしょうか?

編集

または、誰かが私をリンクしたり、有理16進数値を10進数に変換する方法を教えてもらえますか? この問題を回避するには、それだけで十分です。

解決

将来、この質問を読んだ他の人のために、この問題のかなり簡単な回避策を見つけました。

あなたがしなければならないのは、小数の右側の数字(底が何であれ)を取り、それを小数に変換することです(整数を変換する方法はこちらで見ることができます)。次に、その数値を取り、最大位の値で割ります。例えば:

A.C
C == 12 (dec)
12 / 16 = .75 (this is the fractional value in decimal)

次に、その小数値を取得して、上で説明したアルゴリズムを実行できます。

この問題についてみんなの助けをありがとう!

4

1 に答える 1

3

浮動小数点を使用することは、正確な計算を実行したくないことを意味します。

Java浮動小数点値で正確に表現できるのは、基数 2、4、8、16、... で記述された数だけです (整数は別として)。これは、浮動小数点表現の制限によるものです。

基数 2、4、5、8、10、16、20、25、32、... で書かれた数値のみが、10 進数で正確に出力できます。これは、当社の10 進数システムの制限によるものです。

したがって、結果の丸めに関するいくつかのルールを適応させ、アルゴリズム全体に実装する必要があると思います。切り捨てるのではなく丸めることを確認してください。そうしないと、double型の精度が目的に十分な場合や、数値を正確に表現できる場合でも、浮動小数点を通過すると誤った結果が得られます。

より高い精度で計算を実行したい場合は、BigIntegerクラスを見て、整数のみでアルゴリズムを再設計してください。または、分数を操作するためのライブラリを使用します。これは、アルゴリズムへの入力を常に分数として正確に表すことができるため便利です。ただし、最終的には常に、結果の丸めルールを定義して正しく実装することになります。

編集

  1. コメントから学んだように、入力全体が読み取られる前に、出力数字を徐々に出力することを好みます。基本的に可能ですが、

    • 「アキュムレータ」として、単一の数値ではなく間隔を維持する必要があります。たとえば、これまで0.11113 進数で読み取ったことがある場合、出力が と の間0.49382716にあり0.50617284、この段階では小数点以下の最初の 10 進数すら出力できないことがわかっています。0.4999999992これは、最も「合理的な」入力のように出力が表示されないようにするために必要です。

    • 完全な入力が読み取られるときは、間隔の下限ではなく上限に基づいて「切り上げ」て出力を出す方が安全です。このよう0.1111に 3 進数は 10 進数で 0.5 に変換されます。(16 進数から 10 進数への変換に限定されている場合、これは無視できます。)

    • 入力によって達成される最大精度 (間隔の幅の対数) を追跡し、入力が保証するよりも多くの出力桁を発行しないようにします。

    • 必要な最大精度を安全に処理できる間隔エンドポイント (下限と上限) の内部表現を使用します。

    • 非常に人気のあるソフトウェアでさえ、このアルゴリズムの詳細を間違っている場合があり、中間結果を浮動小数点データ型で表現することを避けたり、入力が長い場合は安全に表現できる桁数に切り捨てたりすることに注意してください。

  2. 質問で無理数について言及していますが、使用される基数に関係なく、有限の(または定期的に繰り返される)展開で表現できるすべての数は有理数である必要があります。

  3. 16 進数から 10 進数への変換では、出力を常に正確に表すこともできます。これにより、下限と上限が収束するのを無期限に待機するなどの単純化が可能になります。

于 2012-06-10T21:06:38.910 に答える