web-dev-qa-db-ja.com

Python floatからintへの変換

基本的に、floatをintに変換していますが、期待される値が常に得られるとは限りません。

私が実行しているコードは次のとおりです。

x = 2.51

print("--------- 251.0")
y = 251.0
print(y)
print(int(y))

print("--------- 2.51 * 100")
y = x * 100
print(y)
print(int(y))

print("--------- 2.51 * 1000 / 10")
y = x * 1000 / 10
print(y)
print(int(y))

print("--------- 2.51 * 100 * 10 / 10")
y = x * 100 * 10 / 10
print(y)
print(int(y))

x = 4.02
print("--------- 402.0")
y = 402.0
print(y)
print(int(y))

print("--------- 4.02 * 100")
y = x * 100
print(y)
print(int(y))

print("--------- 4.02 * 1000 / 10")
y = x * 1000 / 10
print(y)
print(int(y))

print("--------- 4.02 * 100 * 10 / 10")
y = x * 100 * 10 / 10
print(y)
print(int(y))

結果は次のとおりです(最初の値は操作の結果、2番目の値は同じ操作のint()です)。

--------- 251.0
251.0
251
--------- 2.51 * 100
251.0
250
--------- 2.51 * 1000 / 10
251.0
251
--------- 2.51 * 100 * 10 / 10
251.0
250
--------- 402.0
402.0
402
--------- 4.02 * 100
402.0
401
--------- 4.02 * 1000 / 10
402.0
401
--------- 4.02 * 100 * 10 / 10
402.0
401

2.51と4.02は、2.50-> 5.00の範囲で奇妙な動作を引き起こす唯一の値です。その範囲内の他の2桁の値はすべて、同じ演算を指定した場合に問題なくintに変換されます。

だから、それらの結果につながる何が欠けていますか?ちなみにPython 2.7.2を使用しています。

60
B. Richard
2.51 * 100 = 250.999999999997

int()関数は、単に小数点で数値を切り捨てて250を返します。

int(round(2.51*100)) 

251を整数として取得します。一般に、浮動小数点数を正確に表すことはできません。したがって、丸め誤差に注意する必要があります。前述のように、これはPython固有の問題ではありません。これは、すべてのコンピューター言語で繰り返し発生する問題です。

77
Pascal Bugnion

すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと

浮動小数点数はすべての数を表すことはできません。特に、2.51は浮動小数点数で表すことはできず、それに非常に近い数で表されます。

>>> print "%.16f" % 2.51
2.5099999999999998
>>> 2.51*100
250.99999999999997
>>> 4.02*100
401.99999999999994

数値を切り捨てるintを使用すると、次のようになります。

250
401

Decimal タイプをご覧ください。

32
Jacob

2進浮動小数点表現(Pythonは1)を使用する言語は、すべての小数値を正確に表すことはできません。計算の結果が250.99999999999である場合(そうである可能性があります)、整数部分を取得すると250になります。

このトピックに関する標準的な記事は、 すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと です。

10
Greg Hewgill
>>> x = 2.51
>>> x*100
250.99999999999997

浮動小数点数は不正確です。この場合、それは250.99999999999999であり、これは実際に251に近い値ですが、int()は小数部分(この場合は250)を切り捨てます。

decimalモジュールを確認するか、mpmathライブラリで多くの計算を行う必要がある場合 http://code.google.com/p/mpmath/ :)、

7
Ant

intは、他の人が述べたように、切り捨てによって変換されます。これにより、答えが予想と異なる場合があります。これを回避する1つの方法は、結果が整数に「十分に近い」かどうかを確認し、それに応じて調整することです。これは、丸め誤差と計算誤差があまり大きくないことを前提としていますが、これは別の問題です。例えば:

def toint(f):
    trunc = int(f)
    diff = f - trunc

    # trunc is one too low
    if abs(f - trunc - 1) < 0.00001:
        return trunc + 1
    # trunc is one too high
    if abs(f - trunc + 1) < 0.00001:
        return trunc - 1
    # trunc is the right value
    return trunc

この関数は、整数に近い場合のオフバイワンエラーを調整します。 mpmathライブラリーは、整数に近い浮動小数点数に対して同様のことを行います。

1
HackerBoss