floatを位置情報付き文字列に変換(科学的記数法、虚数精度なし)
質問
浮動小数点数を常に10進数で表示するようにしたい (例:
12345000000000000000000.0
または
0.000000000000012345
にはない。
科学的表記法
しかし、私は結果が最大で15.7になるようにしたいと思います。
有効数字
であり、それ以上ではありません。
私が欲しいのは
理想的には
になるように、その結果が
最短
に変換しても同じ値になる10進数形式の文字列です。
float
.
よく知られているように
repr
の
float
は、指数が15より大きい場合は科学的記数法で、-4より小さい場合は科学的記数法で表記されます。
>>> n = 0.000000054321654321
>>> n
5.4321654321e-08 # scientific notation
もし
str
が使われると、結果の文字列は再び科学的記数法になります。
>>> str(n)
'5.4321654321e-08'
提案されているのは
format
と
f
フラグと、科学的記法を取り除くのに十分な精度が必要です。
>>> format(0.00000005, '.20f')
'0.00000005000000000000'
この場合、末尾にゼロが追加されますが、動作します。しかし、同じフォーマットが
.1
では同じ書式は失敗し、floatの実際の機械精度を超える小数点以下の桁数を与えてしまいます。
>>> format(0.1, '.20f')
'0.10000000000000000555'
そして、もし私の番号が
4.5678e-20
であれば
.20f
を使っても相対的な精度は落ちます。
>>> format(4.5678e-20, '.20f')
'0.00000000000000000005'
このように これらのアプローチは私の要求と一致しません。 .
と同じ桁数の任意の浮動小数点数を10進数で表示する最も簡単でパフォーマンスの良い方法は何でしょうか?
repr(n)
(または
str(n)
Python 3 の場合)
ただし、科学的記数法ではなく、常に10進法を使っています。
つまり、例えばfloatの値を変換する関数や演算は
0.00000005
を文字列
'0.00000005'
;
0.1
から
'0.1'
;
420000000000000000.0
から
'420000000000000000.0'
または
420000000000000000
で、float 値をフォーマットします。
-4.5678e-5
として
'-0.000045678'
.
懸賞金期間終了後。Karinが文字列操作を使って、Python 2上の私の初期アルゴリズムと比較して大幅な速度向上を達成できることを実証したように、少なくとも2つの実行可能なアプローチがあるようです。
このように
-
パフォーマンスが重要で Python 2 との互換性が必要な場合、あるいは
decimal
モジュールが何らかの理由で使用できない場合 文字列操作を用いたKarinのアプローチ という方法があります。 - Python 3で。 を使えば、私の多少短いコードも速くなります。 .
私は主にPython 3で開発しているので、私自身の答えを受け入れ、Karinに報奨金を授与することにします。
どのように解決するのですか?
残念なことに
float.__format__
での新しい書式でさえもサポートしていないようです。デフォルトの書式設定である
float
は
repr
と同じです。
f
フラグを使用すると、デフォルトで6桁の端数が発生します。
>>> format(0.0000000005, 'f')
'0.000000'
しかし、望む結果を得るためのハックがあります - 最速のものではありませんが、比較的簡単です。
-
を使用して float を文字列に変換します。
str()
あるいはrepr()
-
とすると、新しい
Decimal
のインスタンスがその文字列から作成されます。 -
Decimal.__format__
サポートf
フラグをサポートしており、これは望ましい結果をもたらします。float
とは異なり、デフォルトの精度ではなく、実際の精度を表示します。
このようにして、簡単なユーティリティ関数
float_to_str
:
import decimal
# create a new context for this task
ctx = decimal.Context()
# 20 digits should be enough for everyone :D
ctx.prec = 20
def float_to_str(f):
"""
Convert the given float to a string,
without resorting to scientific notation
"""
d1 = ctx.create_decimal(repr(f))
return format(d1, 'f')
グローバルな10進数コンテキストを使用しないように注意する必要があるため、この関数のために新しいコンテキストが構築されます。これは最も速い方法です。他の方法としては
decimal.local_context
を使用することもできますが、新しいスレッドローカルコンテキストと変換ごとのコンテキストマネージャを作成するため、より遅くなります。
この関数は、仮数から可能なすべての桁を丸めた文字列を返すようになりました。 最短の等価表現 :
>>> float_to_str(0.1)
'0.1'
>>> float_to_str(0.00000005)
'0.00000005'
>>> float_to_str(420000000000000000.0)
'420000000000000000'
>>> float_to_str(0.000000000123123123123123123123)
'0.00000000012312312312312313'
最後の結果は下一桁で丸められます。
かりんさん(@Karin)が指摘されているように
float_to_str(420000000000000000.0)
は厳密には期待された形式と一致しません。
420000000000000000
を返し、末尾に
.0
.
関連
-
[解決済み] どうすれば、文字列中のリテラルな中抜き文字を印刷し、また.formatを使用することができるのでしょうか?
-
[解決済み] 10進数以降の桁をf文字列で固定する。
-
[解決済み] 浮動小数点以下の0を削除して文字列に変換する方法
-
[解決済み】科学的記数法なしで、与えられた精度でnumpy.arrayをpretty-printするには?
-
[解決済み】Pandasの集計結果から科学的記法をフォーマットする/抑制する
-
[解決済み] 浮動小数点値の精度を維持するためのPrintf幅指定子
-
[解決済み] PythonのRequestsモジュールを使ってWebサイトに "ログイン "するには?
-
[解決済み] Django filter queryset __in for *every* item in list
-
[解決済み] 精度や小数点以下の桁数を指定して、floatを文字列に変換できますか?
-
[解決済み] 科学的記数法を用いない2倍から文字列への変換
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Jupyterノートブックでenv変数を設定する方法
-
[解決済み] Spyderを仮想環境で動作させるには?
-
[解決済み] タプルのリストを複数のリストに変換するには?
-
[解決済み] Pandasの'Freq'タグにはどのような値が有効ですか?
-
[解決済み] 文字列から先頭と末尾のスペースを削除するには?
-
[解決済み] サブフォルダからのインポートモジュール
-
[解決済み] あるオブジェクトが数であるかどうかを確認する、最もパイソン的な方法は何でしょうか?
-
[解決済み] subprocess.run()の出力を抑制またはキャプチャするには?
-
[解決済み] djangoフレームワークでフォームフィールドから値を取得するには?
-
[解決済み] Pythonによる一対のクロスプロダクト [重複] (英語)