Pythonのmath.ceil()およびmath.floor()操作が整数ではなく浮動小数点を返すのはなぜですか?


170

誰かがこれを説明できますか(ドキュメントから直接-私の強調):

math.ceil(x)xの上限をfloatとして返します。これは、x 以上の最小の整数値です。

math.floor(x)xの下限をfloatとして返します。これは、x以下の最大の整数値です。

なぜ浮動小数点数が整数を計算することになっているのに、浮動小数点数.ceil.floor返すのでしょうか?


編集:

まあ、これはなぜ浮動小数点数返す必要があるのか​​について非常に良い議論があり、@ jcolladoが実際に Python 3でintを返すことを指摘したとき、私はちょうどそのアイデアに慣れていました...


1
私の推測では、xは整数ではなく浮動小数点数であると考えられますが、Pythonを知らないか使用していないので、他の人にもっと明確に答えさせます。:)
アダムV

6
@ Adam-しかし、ceil / floor演算の要点は、floatを整数に丸めることです!
Yarin

1
これは私が最初に出会ったときも、私はそれが間違っているように思えたので、私も苛立ちました。少なくとも、使用するのはそれほど難しくありませんint(floor(n))
ウィム

1
皮肉なことに(オーバーフローを防ぐためにフロートが使用されたため)、64ビットのintがオーバーフローするずっと前に、フロート表現のために、floor / ceilによって返される値は下位桁では意味がありません。[32ビットの昔はこれは当てはまりませんでした。]
Yves Daoust

回答:


99

浮動小数点数の範囲は通常、整数の範囲を超えています。浮動小数点値を返すことにより、関数は、表現可能な整数の範囲外にある入力値に対して適切な値を返すことができます。

検討してください:floor()整数が返された場合、何をfloor(1.0e30)返す必要がありますか?

さて、Pythonの整数は任意の精度になりましたが、常にそうであるとは限りませんでした。標準ライブラリ関数は、同等のCライブラリ関数の薄いラッパーです。


13
また、Python整数は任意の精度になりましたが、床と天井を整数で表すことができないフロートも残っています。floor(float("inf"))またはを試してくださいceil(float("nan"))
Michael Hoffman

4
@ Michael-どうやらP3では、そうしようとするとOverflowExceptionsが発生するようです。jcolladoの回答を見る
Yarin

4
えっと、それは 'long'型(別名 'bigint')を返すはずですよね?私には明らかな答えのように思えますが、今は何とかナイーブであるように感じています。
koschei

3
@koschei:Python 3.xで実行されます。jcolladoの回答を参照してください。
グレッグヒューギル2011

範囲内の数値でもこれが理にかなっている別の回答へのコメントも参照してください。
ivan_pozdeev 2016年

96

他の回答で指摘されているように、Pythonではフロートを返しますが、これはおそらくオーバーフローの問題を防ぐための歴史的な理由によるものです。ただし、Python 3では整数を返します。

>>> import math
>>> type(math.floor(3.1))
<class 'int'>
>>> type(math.ceil(3.1))
<class 'int'>

詳細については、PEP 3141を参照してください。


@ jcollado- P3で整数を返すことはどこでわかりますか?
Yarin、

4
@Yarin上記のコマンドを入力しました。また、float("inf")またはfloat("nan")を使用すると、OverflowError例外が発生します。
jcollado 2011

10
完全を期すために、Python numpy.floorおよびceil戻り浮動小数点数(<class 'numpy.float64'>)
Neil G

1
@jcollado:float("inf")Python 2.7または3で例外を生成しません
エンドリス

1
@endolithそうです、私はそれをチェックしました、そしてそれはもう起こりません。おそらくそれは2011
。– jcollado 2013年

18

あなたの混乱の原因はあなたのコメントで明白です:

ceil / floor操作の要点は、floatを整数に変換することです!

ceilおよびfloor操作のポイントは、浮動小数点データを整数値に丸めることです。型変換を行わないこと。整数値を取得する必要があるユーザーは、操作後に明示的な変換を実行できます。

整数を返すceilまたはfloat演算しか利用できない場合、整数値への丸めを簡単に実装することはできないことに注意してください。まず、入力が表現可能な整数の範囲内にあることを確認してから、関数を呼び出す必要があります。NaNと無限大を別のコードパスで処理する必要があります。

さらに、IEEE 754に準拠する場合は、浮動小数点数を返すceilおよびfloorのバージョンが必要です。


スティーブン-私はコメントを書き直しました-私は回心するのではなく、ラウンドするつもりでした。しかし、それが私の混乱の原因ではなく、むしろ範囲の差異を認識していなかったことが原因でした。
Yarin

悲しいことに、私は今日投票できません。これは正解です。表現の制限よりもはるかに正確です。
Marcin

13
長年のプログラミングで、floor / ceilの結果を整数ではなく浮動小数点にしたいという状況に遭遇したことを覚えていません。python3 が行うこと整数を返すは、これが実際に行う方がより有用であることを示しています。「...のポイント」の主張は購入しません。プログラマーが望むものではなく、それが何をするかに基づいてポイントを定義しているようです。
ShreevatsaR 2013

2
@ShreevatsaRその状況は数回ありました(ただし、主にPythonコンテキストの外)。私が覚えているのは、マンデルブロ集合を扱うときです。整数値を作成する必要がある場合がありますが、その直後に浮動小数点演算を値に適用します(たとえば、0.5でスケーリングします)。次に、最初にintに変換してからすぐにfloatに戻すよりも、フローリングされたfloatを保持して浮動小数点演算を適用する方がはるかに効率的です。
blubberdiblub

17

なぜなら、Pythonの数学ライブラリは、浮動小数点数を返すC数学ライブラリの薄いラッパーだからです。


C数学ライブラリは任意精度の整数をサポートしていますか?それは、他のpython数学関数が返すものだからです。
エンドリス2013年

5

Python 2.4以前では、整数は切り捨てられた実数の全範囲を保持できませんでした。

http://docs.python.org/whatsnew/2.4.html#pep-237-unifying-long-integers-and-integers


2
「切り捨てられた実数の全範囲」を保持することもできません。これは明らかに無限のセットであるため、無限の量のメモリが必要になるためです。切り捨てられたfloatの範囲を保持できますが、これはofの小さなサブセットです。
leftaroundabout '12

6
@leftaroundabout-うるさい あなたは私が何を意味するのか知っていました。
Mark Ransom 2011

4

floatの範囲が整数の範囲より大きいため、整数を返すとオーバーフローする可能性があります


7
Pythonでは整数はオーバーフローしません。それらが大きくなりすぎると、その整数はbigintに変換されます。Pythonインタープリターを開いて「2 ** 500」と入力すると、intのようにあらゆる方法で処理できるオブジェクトが表示されます。
koschei

@koschei:無限を表現しようとすると、bigintさえオーバーフローします。
Stephen Canon

4

これは非常に興味深い質問です。浮動小数点は指数(= bits_for_exponent)を格納するためにいくつかのビットを必要とするため、2**(float_size - bits_for_exponent)常に整数値よりも大きい任意の浮動小数点数!もう一方の極端では、負の指数を持つ浮動小数点数は10またはのいずれかになり-1ます。これらの関数は、数値が整数型の範囲外にあるときはいつでも元の数値を返すだけので、これは整数範囲浮動小数点範囲の議論を無効にします。Pythonの関数は、ラッパーのあるC機能とこれは本当にの欠乏であるのでC、彼らは整数を返され、レンジ/実行するプログラマ余儀なくされていなければならない機能NaN/ Inf切り上げ/床を呼び出す前にチェックを。

したがって、論理的な答えは、これらの関数が有用な場合にのみ整数範囲内の値を返すため、浮動小数点数を返すという事実は誤りであり、これを実現するのは非常に賢明です。


1

多分他の言語もこれを行うので、それは一般的に受け入れられている動作です。(他の回答に示されているように、正当な理由から)


またはチャールズが言ったこと。:)
Almo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.