Python'da bir sayıyı nasıl yuvarlarsınız?


487

Bu problem beni öldürüyor. Python'da bir sayı UP nasıl toplanır?

Ben (sayı) tur denedim ama sayı aşağı yuvarladı. Misal:

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

Ben int (sayı + .5) denedim ama yine numarayı aşağı yuvarlak! Misal:

int(2.3 + .5) = 2

Sonra tur (sayı + .5) denedim ama kenar durumlarda işe yaramaz. Misal:

WAIT! THIS WORKED!

Tavsiye lütfen.


4
round(number + .5)sayı tamsayı değilse çalışmaz. round(3+.5) == 4, gerçekten istediğiniz zaman 3.
Nearoo

Yanıtlar:


845

Ceil (tavan) fonksiyonu:

import math
print(math.ceil(4.2))

21
Ayrıntı: math.ceil, giriş değerinden büyük veya ona eşit en küçük tamsayıyı döndürür. Bu işlev, girişi bir kayan nokta olarak değerlendirir (Python'un güçlü yazılan değişkenleri yoktur) ve işlev bir kayan nokta döndürür. Bir int istiyorsanız, dönüş değerinden bir int oluşturabilirsiniz, yani,int(math.ceil(363))
RW Sinnet

9
@Sinnet: Aslında python'un güçlü bir şekilde yazıldığını söyleyebilir stackoverflow.com/a/11328980/5069869
Bernhard

1
@TheEspinosa: Evet, python kesinlikle güçlü bir şekilde yazılmıştır, sadece birçok fonksiyonun bazı parametrelerin türü hakkında sorular sorması ve cevaba bağlı olarak farklı kod yürütmesi.
quamrana

12
@RWSinnet Python 3'te, math.ceilyalnızca tamsayı değeri olan kayan nesneyi değil, gerçek bir tam sayı nesnesi döndürür.
Arthur Tacca

10000000 * 0.00136 = 13600.000000000002math.ceil(10000000 * 0.00136) = 13601.0
Tavanın

171

Bu cevabın bir süre önce bir soru için olduğunu biliyorum, ama matematik almak istemiyorsanız ve sadece yuvarlamak istiyorsanız, bu benim için işe yarıyor.

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

İlk bölüm 4 olur ve ikinci bölüm bir kalan varsa "True" olarak değerlendirilir, buna ek olarak True = 1; False = 0. Dolayısıyla, kalan yoksa, aynı tamsayı olarak kalır, ancak kalan varsa 1 ekler.


38
Güzel. //Tamsayı bölme için de kullanabilirsiniz , böylece bu olur 21 // 5 + (21 % 5 > 0).
naught101

6
Yalnızca tamsayılar varsa, bu en iyi çözümdür. Gereksiz floats. Güzel.
Nico Schlömer

158

Akılda tutulması gereken ilginç Python 2.x sorunu:

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

Sorun, python'da iki int bölmenin başka bir int üretmesi ve tavan çağrısından önce kesilmesidir. Doğru sonucu elde etmek için bir değeri bir kayan nokta (veya döküm) yapmanız gerekir.

Javascript'te, tam olarak aynı kod farklı bir sonuç üretir:

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

44
In Python 2.x : int / int -> int ve int / şamandıra -> In yüzer Python 3.x : int / int bir şamandıra neden olabilir
Gecco


110

Tamsayılarla çalışıyorsanız, yuvarlamanın bir yolu, yuvarlanan gerçeğin avantajından yararlanmaktır //: Sadece negatif sayıdaki bölümü yapın, ardından cevabı reddedin. İçe aktarma, kayan nokta veya koşullu gerekmez.

rounded_up = -(-numerator // denominator)

Örneğin:

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

1
Herhangi bir matematik işlemi yapmanız gerekmediğinde ne olur? Yani sadece bir numaran var.
Klik

2
@Klik: o zaman sadece 1 ==> - (-num // 1) ile bölebilirsin ve cevabını alıyorsun :-) İyi günler! David Bau: Çok güzel bir teklif!
Marco smdm

10
Buradaki tüm cevapları zamanladım ve bu bir sonraki en iyiden beş kat daha hızlıydı (math.ceil). @Andreas aynı zamana sahipti
mini totent

@minitotent Basit bir tamsayı bölümü ve birkaç tek döngü işlemi olduğundan bu şaşırtıcı değil. Bu size bir iş getiren cevaptır: Sadece dili değil, altındaki soyutlama katmanlarını da anlamak.
Nearoo

Güzel! Ben her zaman kullandım (num + den - 1) // den, bu intpozitif paydaları olan girdiler için iyi , ancak tek bir integral floatbile dahil değilse başarısız olur (pay veya payda); bu daha büyülü bir görünüş, ama hem ints hem de s için çalışıyor float. Küçük paydaşlar için, daha hızlıdır (CPython 3.7.2'de), garip bir şekilde, sadece pay, dizi tabanlı matematiğe ihtiyaç duyulacak kadar büyük olduğunda, yaklaşımınız daha yavaştır; bunun neden olduğu net değil, çünkü bölünme işi benzer olmalı ve iki tekli olumsuzlama toplama + çıkarmatan daha ucuz olmalıdır.
ShadowRanger

56

Şunu da beğenebilirsin numpy:

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

Matematikten daha iyi olduğunu söylemiyorum, ancak zaten başka amaçlar için numpy kullanıyorsanız, kodunuzu tutarlı tutabilirsiniz.

Her neyse, sadece bir ayrıntıya rastladım. Numpy'yi çok kullanıyorum ve bahsedilmediğine şaşırdım, ancak elbette kabul edilen cevap mükemmel çalışıyor.


3
Numpy kullanmak da güzel. Zaten kütüphanelerde inşa edilmiş python'un bir parçası olduğu için en kolayı matematikle olurdu. Daha mantıklı. Bunun yerine, diğer konular için çok fazla numpy kullanıyorsanız, numpy.ceil'i kullanmak mantıklı ve tutarlıdır :-) İyi ipucu!
Marco smdm

30

kullanım math.ceil için :

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

NOT : Giriş şamandıra olmalıdır.

Bir tamsayıya ihtiyacınız varsa, int dönüştürmek için :

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

BTW, kullanmak math.flooryuvarlak için aşağı ve rounden yakın tam sayıya yuvarlak için.

>>> 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 kullanılıyorsa, girişin bir float olması gerekmez: dahili olarak ceil() ilgilenecektir
guival


11

Kimsenin önermediğine şaşırdım

(numerator + denominator - 1) // denominator

yuvarlama ile tamsayı bölme için. Eskiden C / C ++ / CUDA (krş. divup)


2
Yalnızca statik olarak yazılan diller için geçerlidir. Payda bir şamandıra ise ölürsün.
Bharel

Bu aynı zamanda sadece payda pozitifse tutarlı olarak çalışır; payda negatifse, 1matematik yapmak yerine çıkartmak yerine eklemeniz veya pay ve payda işaretlerini çevirmeniz gerekir.
ShadowRanger

7

Shure yuvarlak değeri float olmalı

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

fakat

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

6

Bunu dene:

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

1
Zeki. ((int(a) - a) != 0)Sentezleme döner 1her aihtiyacı yuvarlanır için. Cevabınızı genişletmek ve bunun nasıl çalıştığını açıklamak isteyebilirsiniz.
Tom Aranda

@TomAranda Herkes bir mantıksal ifadenin bir değeri nasıl değerlendirdiğini açıklayabilir mi?
Bowen Liu

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

Bu işlev modül gerektirmez.


Numaranız varsa 3, o zaman 4birinin istediği şey olabilir veya olmayabilir
buydadip

15
Bu, tüm vakaların yalnızca% 99'unda çalışır. Bunu düzgün düşünmedin. Bu tür çözümlerden her ne pahasına olursa olsun kaçınılmalıdır.
Nearoo

+.5 yerine + .49999999 yerine benim için yeterince iyi.
FlyingZebra1

5

Yukarıdaki cevaplar doğrudur, ancak mathmodülü bu işlev için içe aktarmak genellikle benim için biraz fazlalık gibi geliyor. Neyse ki, bunu yapmanın başka bir yolu var:

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

Trueve Falseolarak yorumlanır 1ve 0python numaranın yer açıklamada. g.is_interger()temelde g.has_no_decimal()veya anlamına gelir g == int(g). Yani İngilizce'deki son ifade okuyor round g down and add one if g has decimal.


1
Ve eğer süslü hissediyorsanız, int(g) + (g % 1 > 0)bunun yerine kullanabilirsiniz ;-)
Nearoo

from math import ceilmatematik modülünün tamamını içe aktarmayı
düzeltiyor

@ SH7890 Korkarım ki bu çizgi import mathperde arkasında olanlardan çok farklı değil . Sadece hariç tüm sembolleri bırakır ceil.
Nearoo

5

Matematiği içe aktarmadan // temel ortamı kullanarak:

a) yöntem / sınıf yöntemi

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) lambda:

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

5

Yuvarlamak isteyenler için a / b ve tamsayı almak :

Tamsayı bölümü kullanan bir başka varyant

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

Herhangi bir kişinin belirli bir ondalık basamağa yuvarlamak istemesi durumunda:

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

1

Bu cevabı henüz görmediğime şaşırdım round(x + 0.4999), bu yüzden cevaplayacağım . Bunun herhangi bir Python sürümü ile çalıştığını unutmayın. Python yuvarlama şemasında yapılan değişiklikler işleri zorlaştırdı. Bu gönderiye bakın .

İçe aktarmadan kullanıyorum:

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)))

Bu neden çalışıyor?

Dokümanlardan

Round () özelliğini destekleyen yerleşik türler için, değerler güç eksi n'nin 10 en yakın katına yuvarlanır; iki kat eşit derecede yakınsa, yuvarlama eşit seçeneğe doğru yapılır

Bu nedenle 2.5 2'ye yuvarlanır ve 3.5 4'e yuvarlanır. Eğer durum böyle değilse, yuvarlama 0.5 ekleyerek yapılabilir, ancak yarım noktaya gelmekten kaçınmak istiyoruz. Yani, 0,4999 eklerseniz yakınlaşacaksınız, ancak normalde beklediğiniz şeye yuvarlanacak yeterli marj ile. Tabii ki, bu x + 0.4999eşitse başarısız olur [n].5000, ancak bu olası değildir.


2
0.4999 kullanıldığında, sadece tam olarak değil, aynı zamanda ???. 0000 ve ???. 0001 (açık aralık) arasındaki herhangi bir giriş için doğru sonuç vermeyecektir. Örneğin, 3.00005 ile denerseniz, beklenen 4 yerine 3 sonucunu elde edersiniz. Tabii ki, maksimum şamandıraya kadar daha fazla basamak ekleyerek bunun gerçekleşme olasılığını azaltabilirsiniz, ancak kullanmak gibi daha sağlam ve sezgisel çözümler varsa, buna işaret etmek math.ceil()?
blubberdiblub

@blubberdiblub Cevabımda belirtiyorum Without importing I use:. Ben de x + 0.4999eşit olursa başarısız olacağını söyledi [n].5000.
Klik

4
Evet, cevabınızda çözümünüzün içe aktarılmadan olduğunu söylüyorsunuz, ancak bunun değerini görmüyorum. mathModülü ve math.ceil()ekstra şeyler yüklemeden tüm pratik amaçlar için her yerde, standart kütüphanede o kadar mevcuttur. Ve ne zaman başarısız olduğu hakkında bahsettiğinizde, bu sadece tek bir nokta için değil, tüm bir aralıkta başarısız olduğu için cevabınızda eksiktir. Teknik olarak, size söyleyecek olursak, bir doğru ileri sürülebilir ise değil IFF , ancak daha az olası olduğundan daha olduğunu o sıradan okuyucu üzerinde etki yapacaktır.
blubberdiblub

0

Herhangi bir içe aktarma olmadan yapmak için:

>>> 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

Bunun bir süre önce olduğunu biliyorum, ama oldukça ilginç bir cevap buldum, işte burada:

-round(-x-0.5)

Bu, kenarları düzeltir ve hem pozitif hem de negatif sayılar için çalışır ve herhangi bir işlev içe aktarması gerektirmez

Şerefe


2
Bu yine de yuvarlanacak-round(-x-0.3) = x
Diblo Dk

0

python'da 4500/1000 çalıştırdığınızda, sonuç 4 olacaktır, çünkü varsayılan python sonucu tamsayı olarak kabul eder, mantıksal olarak: 4500/1000 = 4.5 -> int (4.5) = 4 ve 4 tavanı açıkça 4'tür

4500 / 1000.0 kullanıldığında sonuç 4.5 ve tavan 4.5 olacak -> 5

Javascript kullanarak 4500/1000 sonucu 4,5 alırsınız, çünkü javascript yalnızca sonucu "sayısal tip" olarak alır ve bir sonucu doğrudan float olarak döndürür

İyi şanslar!!


Bu sadece Python 2.x için geçerlidir. Python 3'te, tekli bir bölüm /her zaman bir kayan nokta ile sonuçlanır, bu yüzden 4500/1000her zaman 4.5'tir.
Nearoo

0

Hiçbir şeyi içe aktarmak istemiyorsanız, kendi basit işlevinizi her zaman şu şekilde yazabilirsiniz:

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


2
Num 2.05 ise bu çalışmaz. Girişiniz kadar 9'a sahip en az sayıda basamağa sahip olmanız ve sizi 0.999 ile bırakmanız gerekir ... bu da 1'dir. Ancak köşe kasanız 2 yeniden yuvarlanır. - Sanırım math.ceil'in orada olmasının bir nedeni var.
Johannes Maria Frank

-1

Zemin sapmasını kullanabilir ve buna 1 ekleyebilirsiniz. 2.3 // 2 + 1


2
veya ceil()garip bir şekilde tersini yapmak ve sonra telafi etmek için kullanın
guival

2
Bu işe yaramaz. Örneğin:from math import ceil; assert 4 // 2 + 1 == ceil(4 / 2)
Carl Thomé

-1

Sanırım int()ve arasındaki çalışma mekanizmalarını karıştırıyorsunuz round().

int()kayan bir sayı verilirse her zaman ondalık sayıları keser; oysa round(), 2.5nereye 2ve 3her ikisine eşit mesafede 2.5olursa Python 0 noktasından daha uzak olanı döndürür.

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

"yuvarlama" , örneklerinizin hiçbirinde meydana gelmeyen örneğin 2.3dönüştürüleceği anlamına gelir 3.
Nearoo

-2

Benim payım

print(-(-101 // 5)) = 21Yukarıda verilen örneği test ettim .

Şimdi yuvarlamak için:

101 * 19% = 19.19

Ben kullanamam **böylece çarpma bölme yayıldı:

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

-3

Ben temelde Python bir acemi değilim, ama sadece aşağı yerine yuvarlamaya çalışıyorsanız neden yapmıyorsunuz:

round(integer) + 1

2
Bu, 2.5 <tamsayı <3 olduğunda herhangi bir tamsayı i için çalışmaz. Yuvarlamadan sonra istenen değer 3'tür, ancak ifadeniz 4'e dönüşecektir.
Pranav Shukla

1
Sanırım round(integer + 0.5)sık sık yaptığım budur
Klik
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.