2016-05-11 1 views
-3

は、私はしばらく前に尋ねた:なぜ浮動小数点数のPython 3レンジオブジェクトの最適化はありませんか?前の質問から飛び降り

Why is 1000000000000000 in range(1000000000000001) so fast in Python 3?

あなたはこれを行う場合:

1000000000000000.0 in range(1000000000000001) 

... rangeがいるかどうかを確認するために最適化されていないことは明らかですfloatが指定された範囲内にあります。

私はrangeの目的でのみint秒で動作するようであることを理解だと思う - ので、あなたは、例えば、このような何かすることはできません。

1000000000000 in range(1000000000000001.0) 
# error: float object cannot be interpreted as an integer 

またはこの:

1000000000000 in range(0, 1000000000000001, 1.0) 
# error: float object cannot be interpreted as an integer 

しかし、何らかの理由で、このようなことを許可するように決定されました:

1.0 in range(1) 

の最適化が同様に機能するため、1.0(および上記の1000000000000.0)は、intに強制されていないようです。

私の質問は、なぜ矛盾、なぜfloatの最適化がないのですか?あるいは、上記のコードが前の例と同じエラーを生成しない理由の背後にある根拠は何ですか?

これは、intの最適化に加えて明らかな最適化のようです。私は、そのような最適化のクリーンな実装を妨げるいくつかの微妙な問題があると推測しています。あるいは、そのような最適化を実際には含まない理由について何らかの根拠があります。あるいは、おそらく両方。

編集:ここで少し問題を明確にするために、すべて次の文は、同様Falseに評価さ:

3.2 in range(5) 
'' in range(1) 
[] in range(1) 
None in range(1) 

これは私には予期しない動作のように思えるが、今のところ何の矛盾は間違いありません。ただし、以下はTrueに評価されます。

1.0 in range(2.0) 

を、以前に示したように、上記と同様の構造が最適化されていません。

これは、評価のある時点で値1.0(または私の元の例では1000000000001.0)が強制的にintになっているようです。これは、.0で終わるfloatintに変換するのは当然のことなので意味があります。しかし、まだ問題は残っています。とにかくintに変換されている場合、1000000000000.0 in range(1000000000001)はなぜ最適化されていませんか?

+1

あなたの編集では、 'x in range(n)'が* any * float 'x'に対してfalseであると仮定しているようです。それは真実ではありません:たとえば、 '1.0 in range(2)'を試してください。 –

+0

@ MarkDickinson良い点 - 今私は私が矛盾していると考えているところに戻り、1000000000000.0の範囲(1000000000001)が最適化されていないということについては疑問が残っています。残念ながら私はすでに答えを受け入れています。 –

+0

@ MarkDickinson質問を再編集しました。これを指摘してくれてありがとう。 –

答えて

5

ここには矛盾なしがあります。浮動小数点値は整数に強制することはできませんが、それは逆にしか動作しません。したがって、range()は、包含のテストの際にfloatを整数に暗黙的に変換することはありません。

range()オブジェクトは、の配列タイプです。それは離散的な整数値を含む(事実上ではあるが)。したがって、の包含テストをサポートする必要があります。オブジェクトは同等と評価される可能性があります。

これは、含まれている各整数と等しいかどうかをテストするために、範囲内のすべての可能な値をフルスキャンする必要があります。 実際の整数を使用した場合にのみ、それはrange()オブジェクトがを変換せずに等しいと見なされますどのような値を知ることができる唯一のタイプだと

はしかし、は、最適化を適用することができます。

+1

それは理にかなっています。しかし 'float'が' int'境界を 'floats'に変換することで2つの' int'の範囲内にあるかどうかのチェックを最適化することができます。これは非常に明白なことのようです。なぜそれをしないのですか? –

+0

@RickTeachey: 'range()'は一連の*離散*整数で構成されているため、その間の非整数の10進値は範囲の一部ではありません。 –

+0

その場合、 '1.0 in range(1)'はエラーを生成するはずです。それはしません。不一致。 –

関連する問題