5

この質問の目的のために、私には施設を使用する能力がありませprintf(残念ながら、理由はわかりませんが、今のところ、私が何をしているのかを知っていると仮定しましょう)。

IEEE754単精度数の場合、次のビットがあります。

SEEE EEEE EFFF FFFF FFFF FFFF FFFF FFFF

ここSで、は符号、Eは指数、Fは分数です。

NaN記号の印刷は、 (E == 0xff, F != 0)、InfE == 0xff, F == 0)、0E == 0, F == 0、指数バイアスが使用されていないという理由だけで特別と見なされる)などのすべての特殊なケースをキャッチするのと同様に、すべてのケースで比較的簡単です。

2つの質問があります。

E == 0, F != 01つ目は、非正規化された数値(where )を正規化された数値(where)に変換する最善の方法1 <= E <= 0xfeです。次の質問への答えを単純化するためにこれが必要になると思います(しかし、私は間違っている可能性があるので、遠慮なく私を教育してください)。

2番目の質問は、正規化された数値を印刷する方法です。-3.74195E3指数関数のような方法と非指数関数のような方法の2つの方法でそれらを印刷できるようにしたいと思います3741.95。ただし、これら2つを並べて見るだけで、小数点を移動するだけで前者を後者に変えるのはかなり簡単なはずです。それでは、指数形式に集中しましょう。

ずっと前にPIを印刷するために使用したアルゴリズムの漠然とした思い出があります。ここでは、減少し続ける数式の1つを使用し、可能性の上限と下限を維持し、両方の制限が一致したときに桁を出力し、計算を次のようにシフトします。係数10(したがって、上限と下限が3.23643.1234の場合、を出力3して計算で調整できます)。

しかし、それをやったのは久しぶりなので、それがここでの適切なアプローチかどうかさえわかりません。1/2小数部( 、、など)を移動するとき、各ビットの値は前のビットの半分であるため、そう思われ1/4ます1/8

どうしても必要な場合を除いて、ソースコードを調べなくprintfてもいいので、誰かがこれを手伝ってくれるなら、私は永遠に感謝します。

4

4 に答える 4

3

すべての変換で正確な結果を取得したい場合は、printf()実装で行われるように、任意精度の演算を使用する必要があります。「近い」結果を取得したい場合は、おそらく最下位桁のみが異なる場合は、非常に単純な倍精度ベースのアルゴリズムで十分です。整数部分については、10で繰り返し除算し、余りをに追加します。 10進文字列を形成します(逆)。小数部分の場合は、10を繰り返し乗算し、整数部分を減算して10進文字列を形成します。

最近、このメソッドに関する記事を書きました:http: //www.exploringbinary.com/quick-and-dirty-floating-point-to-decimal-conversion/。科学的記数法は印刷されませんが、追加するのは簡単です。アルゴリズムは非正規化数を出力します(私が印刷した数は正確に出力されましたが、より徹底的なテストを行う必要があります)。

于 2010-11-25T16:03:39.927 に答える
1

非正規化数を同じ浮動小数点型の正規化数に変換することはできません。同等の正規化された数値の指数は、指数で表すには小さすぎます。

正規化された数値を印刷するために、私が考えることができる1つのばかげた方法は、10を繰り返し乗算することです(小数部分の場合)。

于 2010-11-25T08:20:55.110 に答える
0

あなたが概説したものと同じ原理に基づいているように見えるアルゴリズムをより詳細に説明しているG.Steeleによる論文があります。メモリが機能する場合、無制限の高精度演算を使用せざるを得ない場合があります。(浮動小数点数を正確に印刷する方法だと思いますが、現在ここから引用者がダウンしているので確認できず、20年後の回顧紙でグーグルの結果が汚染されています)。

于 2010-11-25T09:23:24.310 に答える
0

最初に行う必要があるのは、対数を使用して指数を10進数に変換することです(おそらく、これが出力を必要とするためです)。その結果の分数を取り、仮数にその分数のexp10を掛けてから、それを10進文字に変換します。そこから、小数点を適切な位置に挿入する必要があります。これは、現在10進数の指数でシフトされています。

于 2010-11-25T08:22:43.403 に答える