Pythonで数値をどのように切り上げますか?


487

この問題は私を殺しています。Pythonで数値を切り上げるにはどうすればよいですか?

round(number)を試しましたが、切り捨てられました。例:

round(2.3) = 2.0 and not 3, what I would like

私はint(number + .5)を試しましたが、再び数値を切り捨てました!例:

int(2.3 + .5) = 2

次に、丸め(数値+ .5)を試しましたが、エッジケースでは機能しません。例:

WAIT! THIS WORKED!

お知らせ下さい。


4
round(number + .5)数値が整数の場合は機能しません。round(3+.5) == 4、あなたが実際に欲しいとき3
Nearoo、

回答:


845

CEIL(天井)機能:

import math
print(math.ceil(4.2))

21
エラボレーション:math.ceilは、入力値以上の最小の整数を返します。この関数は入力を浮動小数点数として扱い(Pythonには厳密に型指定された変数はありません)、関数は浮動小数点数を返します。あなたがintをしたい場合は、戻り値、すなわち、からint型を構築することができますint(math.ceil(363))
RW Sinnet

9
@Sinnet:実際には1つは、パイソンが強く型付けされたと言うことができるstackoverflow.com/a/11328980/5069869
ベルンハルト

1
@TheEspinosa:はい、Pythonは間違いなく強く型付けされています。多くの関数がいくつかのパラメーターの型について質問し、その答えに応じて異なるコードを実行するだけです。
quamrana

12
@RWSinnet Python 3では、math.ceil整数値を持つ浮動オブジェクトだけでなく、実際の整数オブジェクトを返します。
Arthur Tacca

以下のために、float精度の世話をする10000000 * 0.00136 = 13600.000000000002多くを増やすことができます切り上げmath.ceil(10000000 * 0.00136) = 13601.0
ofthestreet

171

この答えはしばらく前の質問に対するものであることは知っていますが、数学をインポートしたくなく、切り上げたいだけの場合は、これでうまくいきます。

>>> int(21 / 5)
4
>>> int(21 / 5) + (21 % 5 > 0)
5

最初の部分は4になり、残りの部分がある場合、2番目の部分は "True"と評価され、さらにTrue = 1になります。False =0。したがって、剰余がない場合は同じ整数のままですが、剰余がある場合は1が加算されます。


38
いいね。//整数除算にも使用できるので、これはになり21 // 5 + (21 % 5 > 0)ます。
naught101

6
整数のみが関係する場合、これが最良のソリューションです。不要なfloatsはありません。いいね。
NicoSchlömer2017

158

心に留めておくべき興味深いPython 2.xの問題:

>>> import math
>>> math.ceil(4500/1000)
4.0
>>> math.ceil(4500/1000.0)
5.0

問題は、Pythonで2つのintを分割すると別のintが生成され、上限の呼び出しの前に切り捨てられることです。正しい結果を得るには、1つの値を浮動小数点(またはキャスト)にする必要があります。

JavaScriptでは、まったく同じコードで異なる結果が生成されます。

console.log(Math.ceil(4500/1000));
5

44
Python 2.xの:int型/ int型- > int型 - int型/フロート>ではフロートのPython 3.xでは int型/ int型フロートにつながることができます:
gecco


110

整数を扱う場合、切り上げの1つの方法は、切り捨てという事実を利用することです//。単に負の数で除算を行ってから、答えを否定します。インポート、浮動小数点、または条件は必要ありません。

rounded_up = -(-numerator // denominator)

例えば:

>>> print(-(-101 // 5))
21

1
数学演算を実行する必要がない場合はどうですか?つまり、あなたはただ一つの番号を持っています。
Klik

2
@Klik:その後、1 ==>-(-num // 1)で除算すれば、答えが得られます:-)よい一日を!David Bau:とてもいい提案です!
Marco smdm 2017

10
ここですべての回答の時間を計ったところ、次のベスト(math.ceil)よりも5倍高速でした。@Andreasは、同じ時間を過ごしました
ミニtotentを

@minitotent単純な整数除算といくつかの単一サイクル演算であるため、これは当然のことです。これはあなたに仕事を与える一種の答えです:言語だけでなく、その下の抽象化のすべての層を理解すること。
Nearoo

いいね!私は常に使用してきましたが(num + den - 1) // den、これはint分母が正の入力には問題ありませんが、1つの非整数float(分子または分母のいずれか)が関係している場合でも失敗します。これはより魔法のように見えますが、intfloatの両方で機能します。小さな分子の場合は(CPython 3.7.2では)高速ですが、奇妙なことに、分子のみが配列ベースの計算が必要なほど大きい場合、アプローチは遅くなります。これはなぜかは明らかではありません。除算の作業は似ているはずであり、2つの単項否定は加算+減算よりも安くなるはずです。
ShadowRanger

56

あなたはnumpyも好きかもしれません:

>>> import numpy as np
>>> np.ceil(2.3)
3.0

数学より優れているとは言っていませんが、すでに他の目的でnumpyを使用している場合は、コードの一貫性を保つことができます。

とにかく、私が出会った細部だけ。私はnumpyをたくさん使用していて、言及されていないことに驚いていましたが、もちろん、受け入れられた答えは完全にうまくいきます。


3
numpyを使うのもいいです。数学はライブラリに組み込まれているpythonの一部であるため、最も簡単です。それはもっと理にかなっています。代わりに、他の問題に大量のnumpyを使用する場合は、numpy.ceilを使用することは理にかなっており、一貫性があります。
Marco smdm 2017

30

math.ceil切り上げに使用

>>> import math
>>> math.ceil(5.4)
6.0

:入力は浮動である必要があります。

整数が必要な場合は、呼び出しintて変換します。

>>> int(math.ceil(5.4))
6

ところで、使用math.floorラウンドにダウンし、round最も近い整数にラウンドに。

>>> math.floor(4.4), math.floor(4.5), math.floor(5.4), math.floor(5.5)
(4.0, 4.0, 5.0, 5.0)
>>> round(4.4), round(4.5), round(5.4), round(5.5)
(4.0, 5.0, 5.0, 6.0)
>>> math.ceil(4.4), math.ceil(4.5), math.ceil(5.4), math.ceil(5.5)
(5.0, 5.0, 6.0, 6.0)

1
python 3を使用している場合、入力は必ずしもフロートである必要はありません:ceil() それの世話をします内部
guival


11

誰も提案していないことに驚いています

(numerator + denominator - 1) // denominator

切り上げによる整数除算。以前はC / C ++ / CUDAの一般的な方法でした(cf. divup


2
静的に型付けされた言語にのみ関連します。分母がフロートである場合、あなたは死んでいます。
バレル2017

これは、分母が正の場合にのみ一貫して機能します。分母が負の場合は、1それを減算する代わりに加算するか、計算を実行する前に分子と分母の両方の符号を反転する必要があります。
ShadowRanger

7

丸められた値は浮動小数点数である必要があります

a = 8 
b = 21
print math.ceil(a / b)
>>> 0

だが

print math.ceil(float(a) / b)
>>> 1.0

6

これを試して:

a = 211.0
print(int(a) + ((int(a) - a) != 0))

1
賢い。この((int(a) - a) != 0)式は、切り上げが必要な1ときにいつでも返さaれます。答えを広げて、これがどのように機能するかを説明することもできます。
トムアランダ2017

@TomAranda誰かがブール式が値にどのように評価されるか説明できますか?
Bowen Liu、

6
>>> def roundup(number):
...     return round(number+.5)
>>> roundup(2.3)
3
>>> roundup(19.00000000001)
20

この関数はモジュールを必要としません。


あなたの番号であれば何をして3、それはに切り上げでしょう4か誰かが何を望んであってもなくてもよい
buydadip

15
これはすべてのケースの99%でのみ機能します。あなたはこれを適切に考えていませんでした。そのような解決策は、いかなる犠牲を払っても避けられるべきです。
Nearoo

+.5の代わりに+ .49999999で十分です。
FlyingZebra1

5

上記の答えは正しいですが、mathこの1つの関数だけのためにモジュールをインポートすることは、通常、私には少しやり過ぎのように感じられます。幸いなことに、それを行う別の方法があります。

g = 7/5
g = int(g) + (not g.is_integer())

Trueそして、Falseとして解釈される10pythonで数字を含む文で。g.is_interger()基本的にg.has_no_decimal()またはに変換されg == int(g)ます。したがって、英語の最後のステートメントは次のようになりますround g down and add one if g has decimal


1
そして、もし気がint(g) + (g % 1 > 0)
利い

from math import ceil数学モジュール全体のインポートを修正しているようです:)
SH7890

@ SH7890 import math裏で何が起きているかという点では、ラインはそれほど変わらないと思います。を除くすべてのシンボルを削除しますceil
Nearoo、

5

数学をインポートせず//基本的な環境を使用:

a)メソッド/クラスメソッド

def ceil(fl): 
  return int(fl) + (1 if fl-int(fl) else 0)

def ceil(self, fl): 
  return int(fl) + (1 if fl-int(fl) else 0)

b)ラムダ:

ceil = lambda fl:int(fl)+(1 if fl-int(fl) else 0)

5

切り上げてa / b整数を取得したい人のために:

整数除算を使用する別のバリ​​アントは、

def int_ceil(a, b):
    return (a - 1) // b + 1

>>> int_ceil(19, 5)
4
>>> int_ceil(20, 5)
4
>>> int_ceil(21, 5)
5

3

誰かが特定の小数点以下を切り上げようとしている場合:

import math
def round_up(n, decimals=0):
    multiplier = 10 ** decimals
    return math.ceil(n * multiplier) / multiplier

1

まだこの答えを見ていなかったので驚いたround(x + 0.4999)ので、これから書き留めておきます。これはすべてのPythonバージョンで機能することに注意してください。Pythonの丸め方式に加えられた変更により、事態が困難になりました。この投稿を参照してください。

インポートせずに、私は使用します:

def roundUp(num):
    return round(num + 0.49)

testCases = list(x*0.1 for x in range(0, 50))

print(testCases)
for test in testCases:
    print("{:5.2f}  -> {:5.2f}".format(test, roundUp(test)))

なぜこれが機能するのか

ドキュメントから

round()をサポートする組み込み型の場合、値は10の累乗からnを引いた最も近い倍数に丸められます。2つの倍数が等しく近い場合、丸めは偶数の選択に向かって行われます

したがって、2.5は2に丸められ、3.5は4に丸められます。これが当てはまらない場合は、0.5を追加することで切り上げが可能ですが、中間点に到達しないようにします。したがって、0.4999を追加すると近づきますが、通常予想される値に丸めるのに十分なマージンがあります。もちろん、x + 0.4999がに等しい場合、これは失敗[n].5000しますが、そうなることはほとんどありません。


2
0.4999を使用すると、正確に???。0001だけでなく、???。0000から???。0001(オープンインターバル)の間の入力に対して正しい結果が得られません。たとえば、3.00005で試した場合、期待される4ではなく3の結果が得られます。もちろん、浮動小数点数の最大精度まで桁を追加することで、このような可能性を減らすことができますが、使用してのような手で、より堅牢で直感的なソリューションは、存在する場合はそれにポイントmath.ceil()
blubberdiblub

@blubberdiblub私の答えでは、私は述べていWithout importing I use:ます。x + 0.4999がに等しい場合は失敗することも述べました[n].5000
Klik

4
はい、あなたの答えはあなたのソリューションがインポートなしであると述べていますが、私はそれの価値を見ません。mathモジュールやmath.ceil()余分なものをインストールすることなく、すべての実用的な目的のためにどこでも、標準ライブラリで提供されていますので。そして、いつ失敗するかについてのあなたの言及に関して、これはあなたの答えでは不完全です、それはそれが単一の点だけでなく、全体の間隔で失敗するからです。技術的には、iffであるかどうかにかかわらず、正しいと主張することはできますが、カジュアルな読者には、実際よりも可能性が低いという印象を与えます。
blubberdiblub 2016年

0

インポートなしでそれを行うには:

>>> round_up = lambda num: int(num + 1) if int(num) != num else int(num)
>>> round_up(2.0)
2
>>> round_up(2.1)
3

0

私はこれがかなり昔からあることを知っていますが、私はかなり興味深い答えを見つけたので、ここに行きます:

-round(-x-0.5)

これは端のケースを修正し、正と負の両方の数で機能し、関数のインポートを必要としません

乾杯


2
これは切り捨てられます-round(-x-0.3) = x
Diblo Dk 2015

0

pythonで4500/1000を操作すると、結果は4になります。これは、デフォルトのpythonは整数として結果を仮定するため、論理的には4500/1000 = 4.5-> int(4.5)= 4であり、ceil of 4は明らかに4です。

4500 / 1000.0を使用すると、結果は4.5となり、ceilは4.5-> 5になります。

javascriptを使用すると、4500/1000の結果として4.5を受け取ります。これは、javascriptが結果のみを「数値タイプ」と想定し、結果を直接floatとして返すためです。

幸運を!!


これは、Python 2.xでのみ当てはまります。Python 3では、単一の除算は常に/浮動小数点数になるため4500/1000、常に4.5になります。
Nearoo

0

何もインポートしたくない場合は、いつでも次のように独自の単純な関数を作成できます。

def RoundUP(num): if num== int(num): return num return int(num + 1)


2
これは、numが2.05の場合は機能しません。少なくとも9の数字を入力と同じ数にし、0.999を1のままにします。ただし、1ですが、コーナーケース2が再度切り上げられます。-まあ、math.ceilが存在する理由はあると思います。
Johannes Maria Frank

-1

フロア分割を使用して、1を追加できます。2.3 // 2 + 1


2
またはceil()、奇妙に反対のことをして代償する代わりに使用する
guival

2
これは機能しません。例:from math import ceil; assert 4 // 2 + 1 == ceil(4 / 2)
CarlThomé2017

-1

私はあなたが間に働くメカニズムを混乱していると思うint()と、round()

int()浮動小数点数が指定されている場合は、常に10進数を切り捨てます。一方round()の場合に、及びから等しい距離以内、より離れた0点からの方のPython戻ります。2.5232.5

round(2.5) = 3
int(2.5) = 2

「切り上げ」とは、たとえば2.3がに変わることを意味し3ますが、どちらの例でも発生しません。
Nearoo

-2

私の分け前

私はテストしました print(-(-101 // 5)) = 21上記の例。

切り上げのために:

101 * 19% = 19.19

私は使用できない**ので、乗算を除算に広げます:

(-(-101 //(1/0.19))) = 20

-3

私は基本的にPythonの初心者ですが、切り捨てるのではなく切り上げようとしているのであれば、どうしてですか:

round(integer) + 1

2
この切り上げ後の2.5 <整数<3.目的の値が3であるが、あなたの式は4にそれを向けるだろう任意の整数iに対する動作しません
Pranavシュクラ

1
私はあなたの意味だと思うround(integer + 0.5)。これは私が頻繁に何をすべきかです
Klik
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.