182

//Python 3 で床で除算を行う Pythonの演算子について知りました。

代わりに ceil で除算する演算子はありますか? /( Python 3 で浮動小数点除算を行う演算子については知っています。)

4

8 に答える 8

373

いいえ、逆さまの床分割を使用できます:¹

def ceildiv(a, b):
    return -(a // -b)

これが機能するのは、 Python の除算演算子が床除算を行うためです(整数除算で小数部分が切り捨てられる C とは異なります)。

ここにデモンストレーションがあります:

>>> from __future__ import division     # for Python 2.x compatibility
>>> import math
>>> def ceildiv(a, b):
...     return -(a // -b)
...
>>> b = 3
>>> for a in range(-7, 8):
...     q1 = math.ceil(a / b)   # a/b is float division
...     q2 = ceildiv(a, b)
...     print("%2d/%d %2d %2d" % (a, b, q1, q2))
...
-7/3 -2 -2
-6/3 -2 -2
-5/3 -1 -1
-4/3 -1 -1
-3/3 -1 -1
-2/3  0  0
-1/3  0  0
 0/3  0  0
 1/3  1  1
 2/3  1  1
 3/3  1  1
 4/3  2  2
 5/3  2  2
 6/3  2  2
 7/3  3  3

math.ceil の代わりにこれを使用するのはなぜですか?

math.ceil(a / b)浮動小数点エラーが発生するため、静かに誤った結果が生成される可能性があります。例えば:

>>> from __future__ import division     # Python 2.x compat
>>> import math
>>> def ceildiv(a, b):
...     return -(a // -b)
...
>>> x = 2**64
>>> y = 2**48
>>> ceildiv(x, y)
65536
>>> ceildiv(x + 1, y)
65537                       # Correct
>>> math.ceil(x / y)
65536
>>> math.ceil((x + 1) / y)
65536                       # Incorrect!

一般に、特に必要でない限り、浮動小数点演算を完全に回避することをお勧めします。浮動小数点演算にはいくつかのトリッキーなエッジ ケースがあり、細心の注意を払わないとバグが発生する傾向があります。また、ハードウェア FPU を持たない小型/低電力デバイスでは、計算コストが高くなる可能性があります。


¹この回答の以前のバージョンでは、ceildiv は として実装されていましたが、ベンチマークで後者のパフォーマンスがわずかに優れているとコメント者が報告​​した後、return -(-a // b)に変更されました。通常、被除数 ( a ) は除数 ( b )よりも大きいreturn -(a // -b)ため、これは理にかなっています。Python はこれらの計算を実行するために任意精度の算術演算を使用するため、単項否定の計算にはほとんどの場合、 の計算と同等以上の作業が必要になります。-a-b

于 2013-07-07T10:30:02.063 に答える
73

ceil で除算する演算子はありません。あなたがする必要がimport mathあり、使用するmath.ceil

于 2013-02-11T22:35:29.347 に答える
31

(x + (d-1)) // d割るときにx行うことができます。d(x + 4) // 5

于 2013-02-11T22:54:17.300 に答える
22

インラインでもいつでも実行できます

((foo - 1) // bar) + 1

python3 では、これは、速度を気にする場合、float 除算を強制して ceil() を呼び出すよりも桁違いに高速です。必要があることを使用法で証明していない限り、これはすべきではありません。

>>> timeit.timeit("((5 - 1) // 4) + 1", number = 100000000)
1.7249219375662506
>>> timeit.timeit("ceil(5/4)", setup="from math import ceil", number = 100000000)
12.096064013894647
于 2013-02-11T23:03:45.540 に答える
8

math.ceil の精度は 53 ビットに制限されていることに注意してください。大きな整数を操作している場合、正確な結果が得られない場合があります。

gmpy2ライブラリは、天井の丸めを使用する関数を提供します。c_div

免責事項: 私は gmpy2 を保守しています。

于 2013-02-11T23:59:29.667 に答える