-2

次のコード スニペットを作成しました。5 dpDNumberを 2 dp に変換し、これを文字列に挿入しようとしています。ただし、どの方法を使用しようとしても、常に元DNumberの小数点以下の桁数に戻るようです (5)

以下のコード スニペット:

if key == (1, 1):
    DNumber = '{r[csvnum]}'.format(r=row) 
    # returns 7.65321
    DNumber = """%.2f""" % (float(DNumber))
    # returns 7.65
    Check2 = False              
    if DNumber:
        if DNumber <= float(8):
            Check2 = True                    
        if Check2:
            print DNumber 
            # returns 7.65
            string = 'test {r[csvhello]} TESTHERE test'.format(r=row).replace("TESTHERE", str("""%.2f""" % (float(gtpe)))) 
# returns: test Hello 7.65321 test
            string = 'test {r[csvhello]} TESTHERE test'.format(r=row).replace("TESTHERE", str(DNumber))
# returns: test Hello 7.65321 test

私がそれが返すことを望んでいたもの:test Hello 7.65 test

試す代替方法に関するアイデアや提案はありますか?

4

3 に答える 3

4

float を小数点以下 2 桁の文字列に変換してから float に戻すと、小数点以下 2 桁の float が得られることを期待していたようです。

最初の問題は、コードが実際にはどこでもそれを行っていないことです。もしそうしていたら7.65、 ではなくに非常に近いものが得られるでしょう7.65321

しかし、より大きな問題は、あなたがやろうとしていることは意味をなさないということです. float は常に 53 桁の 2 進数を持ちます。それを 2 桁の 10 進数に丸めた場合 (文字列への変換とその逆の変換を含め、どのように行っても)、実際に得られるのは 2 桁の 10 進数に丸められ、次に 53の 2 進数に丸められた floatです。最も近いのは正確には ではありませんがfloat、. * したがって、それが最終的な結果になります。そして、それを回避する方法はありません。それは保存方法に固有のものです。7.657.657.650000000000000355271368float

ただし、これに使用できる別のdecimal.Decimalタイプがあります: . 例えば:

>>> f = 7.65321
>>> s = '%.2f' % f
>>> d = decimal.Decimal(s)
>>> f, s, d
(7.65321, '7.65', Decimal('7.65'))

または、もちろん、フロートの代わりに文字列を渡すこともできます (すでにコードで誤って行っているため)。または、.2f出力するたびにその形式を使用することを忘れないでください。


補足として、あなたDNumberは文字列として終わるので、この行は何も役に立ちません:

if DNumber <= 8:

Python 2.x では、型の異なる 2 つの値を比較すると、一貫性はあるものの恣意的で無意味な答えが得られます。CPython 2.x では、常にFalse.** になります。別の Python 2.x 実装では、異なる可能性があります。Python 3.x では、TypeError.

これを次のように変更しても、何の役にも立ちません。

if DNumber <= float(8):

strここで、 aと anを比較する代わりに、 aと a をint比較しstrていfloatます。これはまったく無意味であり、まったく同じ規則に従います。(また、float(8)と同じことを意味します8.0が、読みにくく、遅くなる可能性があります。)

さらに言えば、これは:

if DNumber:

… 常に真になります。数値の場合、if fooゼロ以外かどうかをチェックします。これは値の悪い考えfloatです (0 の絶対または相対誤差範囲内にあるかどうかを確認する必要があります)。floatしかし、繰り返しますが、あなたには価値がありません。を持っていstrます。文字列の場合if foo、文字列が空でないかどうかをチェックします。したがって、 から始めたとしても0、文字列"0.00"は true になります。


* ここでは、C 型に IEEE-754 double を使用するプラットフォームで CPython を使用しておりdouble、string と float の間で行ったり来たりするすべての余分な変換によって追加のエラーが発生していないことを前提としています。

** ルールは少し単純化されています。2 つの数値を比較すると、両方を保持できる型に変換されます。それ以外の場合、どちらかの値がNone小さい場合。それ以外の場合、いずれかの値が数値の場合は小さいです。それ以外の場合は、アルファベット順で名前が早い方の型が小さくなります。

于 2013-10-16T23:01:01.793 に答える
1

次のことをしようとしていると思います-フォーマットをゲッターと組み合わせます:

>>> a = 123.456789
>>> row = {'csvnum': a}
>>> print 'test {r[csvnum]:.2f} hello'.format(r=row)
test 123.46 hello
于 2013-10-16T22:56:16.827 に答える
0

番号が 7 の後に 5 桁の数字である場合は、次の方法を試してみてください。

print "%r" % float(str(x)[:4])

ここで、x は問題のフロートです。例:

>>>x = 1.11111
>>>print "%r" % float(str(x)[:4])
>>>1.11
于 2013-10-16T22:55:24.063 に答える