• ベストアンサー

浮動小数点数を10進表記するアルゴリズム

与えられた浮動小数点数から正確な10進表記の文字列を得るにはどうすればよいでしょうか。 主に、2進の指数を10進の指数に直す部分で悩んでいます。 単純に考えれば、2進数字の各桁について10進表記の数字列を求めて10進演算する方法が思いつきますが、大きな数や小さな数では計算量が極端に増えてしまいます。もっと効率的な方法はないものでしょうか。 logを取ればうまいこと計算量を減らせそうな気もしますが、正確さが犠牲になりそうです。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

log() の使い方がわからなければ、log() を使う必要はありません。 回答にも書いたように、(無限精度の実数で無く)double なら、300回ちょっとのかけ算(or 割り算)なので、気にするほどの計算量ではありません。 それによく考えたら、log() を使って、指数部分を計算したにしても、仮数部分を正規化するのに、やっぱり、その回数だけ、かけたり割ったりが必要なので、実質的にはほとんど意味が無いですね。

SortaNerd
質問者

お礼

> 仮数部分を正規化するのに、やっぱり、その回数だけ、かけたり割ったりが必要 そうなのですか。結局のところ大量の乗算は必須なようですね。 納得しました。ありがとうございます。

その他の回答 (4)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

そういえば, そもそも最初の「与えられた浮動小数点数」というのはどんなフォーマットを想定しているんでしょうか? ぶっちゃけた話, IEEE754-2008 の decimalxx なフォーマットを使えば, こんなことで悩む必要すらなかったりしますが.

SortaNerd
質問者

お礼

それはあまり考えていませんでしたが、とりあえず2進のつもりではあります。 元々特に必要があっての質問ではなくただの知的好奇心からですので、すみませんがdecimalでは面白くないので不可とさせてください。

回答No.3

No.2 です。 No.2 のロジックだと、別に、最高のハードなど必要なく、浮動小数点演算ができる(ライブラリでも)機能があれば十分です。 また、このロジックだと、log() をとることによる誤差は本質的にありません。 演算時間も、log() を1回とるだけなので、全く問題になりません。 ロジックが理解できれば、こういう点での質問は出ないと思うのですが。 あと、確かに(少なくとも最初の)最適化は、仮数部分を 1未満 0.1以上ですね。

SortaNerd
質問者

お礼

はい、ですからロジックが理解できません。 logを使う場合のロジックを順を追って説明してもらえませんか。

回答No.2

log までとれるような環境なら、数値としての演算はできるのですよね? 1) 浮動小数点が、正数・負数・ゼロ のいずれかを判断して、(符号を覚えた上で)正数にする。 2) さらに、0 以上 1 未満になるように、10 をかけるか、10で割る(かけたり割ったりした回数は覚えておく) 3) 前項で、かけたり割ったりした回数が、10進数表記における、指数部分。 ここまでで、指数部分は完成。 double でも、たかだか、300回ちょっとで計算は終わる。 なお、log() (底が10) を使うと、2) と 3) の繰り返し計算がなくても、一発で、 指数部分が算出可能。 以下、仮数部分。 1) 仮数は、0 以上 1 未満に正規化されていると仮定する。 2) 10倍すると、(10進数表記で)小数点以下一桁の数値が、整数部分に出てくる。 3) 整数部分が、小数点以下一桁になる。 4) 整数部分を引く 5)それを10倍すると、本来の数字の小数点以下二桁目が整数部分にでてくる。 6) 以下、必要な精度だけそれを繰り返す。 ※もちろん、算出できた指数部分とか、仮数部分の桁は、ちゃんと文字に変換する。 おまけ。 http://www.nest4.net/tec/strnum.html (ただし、ここで説明しているルーチンは、変換結果を指数表示するようにはなっていません)

SortaNerd
質問者

お礼

回答ありがとうございます。 思えば環境はあまり具体的に考えていませんでした。考える上で必要なら、現在最高のハードウェアということでお願いします。 > 0 以上 1 未満になるように、10 をかけるか、10で割る なるほど、10進数の方で2の冪乗を計算することを考えていましたが、2進数に10を掛けた方が速そうですね。 ただ小数になると2進数は10で割れないので10進数で計算した方がよさそうです。 > log 必要な精度が得られるのか、および計算時間について詳しく分かりませんか? 仮数部分については流れがよく分かりました。 正規化は0.1以上1未満ですよね。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

一般に, a^n (n は整数) を計算するために必要な乗算はたかだか 2 log n 回くらい, ですよね. 「n のビット数の 2倍」くらいで「極端に増える」ということはないと思いますけど....

SortaNerd
質問者

お礼

回答ありがとうございます。 回数はlogNのオーダーでも、ビット数が増えるので1回あたりの計算量はもっと増えますね。 極端かどうかは、まあ感じ方の問題で。