Bagaimana Anda mengumpulkan angka dengan Python?


487

Masalah ini membunuhku. Bagaimana cara mengumpulkan angka UP di Python?

Saya mencoba putaran (angka) tetapi membulatkan angka ke bawah. Contoh:

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

Saya mencoba int (angka + .5) tetapi membulatkan angka ke bawah lagi! Contoh:

int(2.3 + .5) = 2

Kemudian saya mencoba putaran (angka + .5) tetapi tidak akan bekerja dalam kasus tepi. Contoh:

WAIT! THIS WORKED!

Mohon saran.


4
round(number + .5)tidak berfungsi jika angka tersebut bilangan bulat. round(3+.5) == 4, padahal sebenarnya Anda inginkan 3.
Nearoo

Jawaban:


846

The ceil (langit-langit) fungsi:

import math
print(math.ceil(4.2))

21
Elaboration: math.ceil mengembalikan integer terkecil yang lebih besar atau sama dengan nilai input. Fungsi ini memperlakukan input sebagai float (Python tidak memiliki variabel yang diketik dengan kuat) dan fungsi mengembalikan float. Jika Anda menginginkan int, Anda dapat membuat int dari nilai balik, yaitu,int(math.ceil(363))
RW Sinnet

9
@ Sinnet: Sebenarnya orang bisa mengatakan bahwa python sangat diketik stackoverflow.com/a/11328980/5069869
Bernhard

1
@TheEspinosa: Ya, python pasti sangat diketik, hanya saja banyak fungsi yang bertanya tentang jenis beberapa parameter dan mengeksekusi kode yang berbeda tergantung pada jawabannya.
quamrana

12
@RWSinnet Dalam Python 3, math.ceilmengembalikan objek integer yang sebenarnya, bukan hanya objek mengambang dengan nilai integer.
Arthur Tacca

Jaga presisi float, karena 10000000 * 0.00136 = 13600.000000000002langit-langit dapat meningkat banyakmath.ceil(10000000 * 0.00136) = 13601.0
ofthestreet

171

Saya tahu jawaban ini untuk pertanyaan sejak beberapa waktu lalu, tetapi jika Anda tidak ingin mengimpor matematika dan Anda hanya ingin mengumpulkan, ini bekerja untuk saya.

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

Bagian pertama menjadi 4 dan bagian kedua mengevaluasi ke "Benar" jika ada sisanya, yang di samping Benar = 1; Salah = 0. Jadi jika tidak ada sisa, maka itu tetap bilangan bulat yang sama, tetapi jika ada sisanya menambahkan 1.


38
Bagus. Anda juga dapat menggunakan //untuk divisi integer, jadi ini menjadi 21 // 5 + (21 % 5 > 0).
naught101

6
Ini adalah solusi terbaik jika hanya bilangan bulat yang terlibat. Tidak perlu float. Bagus.
Nico Schlömer

158

Masalah Python 2.x yang menarik untuk diingat:

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

Masalahnya adalah bahwa membagi dua int di python menghasilkan int lain dan itu terpotong sebelum panggilan langit-langit. Anda harus membuat satu nilai float (atau cast) untuk mendapatkan hasil yang benar.

Dalam javascript, kode yang sama persis menghasilkan hasil yang berbeda:

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

44
Dalam Python 2.x : int / int -> int dan int / float -> float Dalam Python 3.x : int / int dapat menghasilkan float
gecco

7
Anda bisa mendapatkan perilaku Python 3.x pada versi tertentu dari Python 2.x dengan mengaktifkan "pembagian sejati" seperti yang ditunjukkan di sini
Rob Dennis

110

Jika bekerja dengan bilangan bulat, salah satu cara mengumpulkan adalah dengan mengambil keuntungan dari fakta yang //dibulatkan: Lakukan saja pembagian pada angka negatif, kemudian negasikan jawabannya. Tidak perlu impor, titik apung, atau bersyarat.

rounded_up = -(-numerator // denominator)

Sebagai contoh:

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

1
Bagaimana ketika Anda tidak perlu melakukan operasi matematika? Yaitu Anda hanya memiliki satu nomor.
Klik

2
@Lik: maka Anda bisa membagi dengan 1 ==> - (-num // 1) dan Anda mendapatkan jawaban Anda :-) Selamat bersenang-senang! David Bau: proposal yang sangat bagus!
Marco smdm

10
Saya menghitung semua jawaban di sini dan ini lima kali lebih cepat dari yang terbaik berikutnya (math.ceil). @ Andreas memiliki waktu yang sama
mini totent

@minitotent Itu tidak mengejutkan karena ini adalah divisi integer sederhana dan beberapa operasi siklus tunggal. Ini adalah jenis jawaban yang memberi Anda pekerjaan: Memahami tidak hanya bahasa, tetapi semua lapisan abstraksi di bawahnya.
Nearoo

Bagus! Saya selalu menggunakan (num + den - 1) // den, yang baik untuk intinput dengan penyebut positif, tetapi gagal jika bahkan non-integral tunggal floatterlibat (baik pembilang atau penyebut); ini lebih ajaib, tetapi bekerja untuk keduanya intdan floats. Untuk pembilang kecil, itu juga lebih cepat (pada CPython 3.7.2), meskipun anehnya, ketika hanya pembilang yang cukup besar yang dibutuhkan matematika berbasis array, pendekatan Anda lebih lambat; tidak jelas mengapa ini terjadi, karena pekerjaan pembagian harus serupa dan dua negasi unary harus lebih murah daripada penambahan + pengurangan.
ShadowRanger

56

Anda mungkin juga suka numpy:

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

Saya tidak mengatakan ini lebih baik daripada matematika, tetapi jika Anda sudah menggunakan numpy untuk tujuan lain, Anda dapat menjaga kode Anda konsisten.

Bagaimanapun, hanya detail yang saya temui. Saya menggunakan banyak numpy dan terkejut itu tidak disebutkan, tetapi tentu saja jawaban yang diterima berfungsi dengan baik.


3
Menggunakan numpy juga bagus. Yang paling mudah adalah dengan matematika karena sudah menjadi bagian dari python yang dibangun di perpustakaan. Itu lebih masuk akal. Alih-alih seperti yang Anda sebutkan jika Anda menggunakan banyak numpy untuk masalah lain, maka masuk akal dan konsisten untuk menggunakan numpy.ceil :-) Petunjuk yang bagus!
Marco smdm

30

Gunakanmath.ceil untuk mengumpulkan:

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

CATATAN : Input harus mengambang.

Jika Anda membutuhkan integer, panggil intuntuk mengubahnya:

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

BTW, gunakan math.flooruntuk membulatkan ke bawah dan rounduntuk membulatkan ke bilangan bulat terdekat.

>>> 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
Input tidak harus berupa float jika menggunakan python 3: ceil() akan menjaganya secara internal
guival


11

Saya terkejut tidak ada yang menyarankan

(numerator + denominator - 1) // denominator

untuk divisi integer dengan pembulatan ke atas. Digunakan untuk menjadi cara umum untuk C / C ++ / CUDA (lih. divup)


2
Hanya relevan untuk bahasa yang diketik secara statis. Jika penyebutnya adalah pelampung, berarti Anda sudah mati.
Bharel

Ini juga hanya berfungsi secara konsisten jika penyebutnya positif; jika penyebutnya negatif, Anda perlu menambahkan 1alih-alih menguranginya, atau membalikkan tanda pembilang dan penyebut sebelum melakukan perhitungan.
ShadowRanger

7

Jadilah shure rounded value haruslah float

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

tapi

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

6

Coba ini:

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

1
Pintar. The ((int(a) - a) != 0)Ekspresi kembali 1setiap kali aharus dibulatkan. Anda mungkin ingin memperluas jawaban dan menjelaskan cara kerjanya.
Tom Aranda

@TomAranda Adakah yang bisa menjelaskan bagaimana ekspresi boolean mengevaluasi nilai?
Bowen Liu

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

Fungsi ini tidak memerlukan modul.


Bagaimana jika nomor Anda adalah 3, maka itu akan menjadi 4yang mungkin atau tidak sesuai keinginan seseorang
buydadip

15
Ini hanya bekerja di 99% dari semua kasus. Anda tidak memikirkan ini dengan baik. Solusi semacam itu harus dihindari dengan cara apa pun.
Nearoo

jadi alih-alih +5 lakukan + .49999999 cukup baik untuk saya.
FlyingZebra1

5

Jawaban di atas benar, namun, mengimpor mathmodul hanya untuk fungsi yang satu ini biasanya terasa sedikit berlebihan bagi saya. Untungnya, ada cara lain untuk melakukannya:

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

Truedan Falseditafsirkan sebagai 1dan 0dalam pernyataan yang melibatkan angka dengan python. g.is_interger()pada dasarnya diterjemahkan ke g.has_no_decimal()atau g == int(g). Jadi pernyataan terakhir dalam bahasa Inggris berbunyiround g down and add one if g has decimal .


1
Dan jika Anda merasa mewah, Anda bisa menggunakan int(g) + (g % 1 > 0);-)
Nearoo

from math import ceiltampaknya memperbaiki mengimpor seluruh modul matematika :)
SH7890

@ SH7890 Saya khawatir kalimat itu tidak jauh berbeda dengan import mathapa yang terjadi di balik layar. Itu hanya menjatuhkan semua simbol kecuali ceil.
Nearoo

5

Tanpa mengimpor matematika // menggunakan lingkungan dasar:

a) metode / metode kelas

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

Bagi mereka yang ingin mengumpulkan a / bdan mendapatkan bilangan bulat:

Varian lain yang menggunakan pembagian integer adalah

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

Jika ada orang yang mencari untuk dibulatkan ke tempat desimal tertentu:

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

1

Saya terkejut saya belum melihat jawaban ini round(x + 0.4999), jadi saya akan meletakkannya. Perhatikan bahwa ini berfungsi dengan versi Python apa pun. Perubahan yang dibuat pada skema pembulatan Python telah membuat hal-hal sulit. Lihat posting ini .

Tanpa mengimpor, saya menggunakan:

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

Kenapa ini bekerja?

Dari dokumen

Untuk jenis bawaan yang mendukung putaran (), nilai dibulatkan ke kelipatan terdekat dari 10 dengan daya minus n; jika dua kelipatan sama-sama dekat, pembulatan dilakukan menuju pilihan genap

Oleh karena itu 2,5 dibulatkan menjadi 2 dan 3,5 dibulatkan menjadi 4. Jika ini tidak terjadi maka pembulatan dapat dilakukan dengan menambahkan 0,5, tetapi kami ingin menghindari sampai ke titik setengah. Jadi, jika Anda menambahkan 0,4999 Anda akan mendekati, tetapi dengan margin yang cukup untuk dibulatkan ke apa yang biasanya Anda harapkan. Tentu saja, ini akan gagal jika x + 0.4999sama dengan [n].5000, tetapi itu tidak mungkin.


2
Menggunakan 0,4999, itu akan gagal memberikan hasil yang benar untuk setiap input di antara ???. 0000 dan ???. 0001 (interval terbuka), bukan hanya persis ???. 0001. Misalnya, jika Anda mencobanya dengan 3.00005, Anda akan mendapatkan hasil 3 daripada yang diharapkan 4. Tentu saja Anda dapat mengurangi kemungkinan ini terjadi dengan menambahkan lebih banyak dan lebih banyak hingga presisi maksimum kendaraan, tetapi apa masalahnya tunjukkan bahwa jika ada solusi yang lebih kuat dan intuitif, seperti menggunakan math.ceil()?
blubberdiblub

@blubberdiblub Dalam jawaban saya, saya menyatakan Without importing I use:. Saya juga menyebutkan bahwa itu akan gagal jika x + 0.4999sama dengan [n].5000.
Klik

4
Ya, Anda menyatakan dalam jawaban Anda bahwa solusi Anda tanpa mengimpor, tetapi saya tidak melihat nilainya. The mathmodul dan math.ceil()adalah di perpustakaan standar, sehingga tersedia di mana-mana untuk semua tujuan praktis tanpa menginstal hal ekstra. Dan mengenai penyebutan Anda ketika gagal, ini tidak lengkap dalam jawaban Anda, karena gagal untuk seluruh interval, bukan hanya untuk satu titik. Secara teknis, Anda bisa berargumen bahwa Anda benar, seperti yang Anda katakan jika dan bukan iff , tetapi itu akan membuat kesan pada pembaca biasa bahwa itu lebih kecil kemungkinannya daripada yang sebenarnya.
blubberdiblub

0

Untuk melakukannya tanpa impor:

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

Saya tahu ini dari beberapa waktu yang lalu, tetapi saya menemukan jawaban yang cukup menarik, jadi begini:

-round(-x-0.5)

Ini memperbaiki kasus tepi dan bekerja untuk angka positif dan negatif, dan tidak memerlukan impor fungsi

Bersulang


2
Ini masih akan dibulatkan ke bawah-round(-x-0.3) = x
Diblo Dk

0

ketika Anda mengoperasikan 4500/1000 dalam python, hasilnya akan menjadi 4, karena untuk ason python default sebagai bilangan bulat hasilnya, secara logis: 4500/1000 = 4,5 -> int (4.5) = 4 dan ceil of 4 jelaslly adalah 4

menggunakan 4500 / 1000.0 hasilnya akan 4,5 dan langit-langit 4,5 -> 5

Dengan menggunakan javascript, Anda akan menerima 4,5 sebagai hasil dari 4500/1000, karena javascript menganggap hanya hasilnya sebagai "tipe numerik" dan mengembalikan hasilnya secara langsung sebagai float

Semoga berhasil!!


Itu hanya benar di Python 2.x. Dalam Python 3, pembagian dengan satu /selalu menghasilkan float, jadi 4500/1000selalu 4,5.
Nearoo

0

Jika Anda tidak ingin mengimpor apa pun, Anda selalu dapat menulis fungsi sederhana Anda sendiri sebagai:

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


2
Ini tidak berfungsi jika num adalah 2,05. Anda harus memiliki paling sedikit digit dengan 9 sebagai input Anda, meninggalkan Anda dengan 0,999 ... yang adalah 1. Tapi kemudian kotak sudut 2 Anda dibulatkan lagi. - Yah, kurasa ada alasan mengapa math.ceil ada di sana.
Johannes Maria Frank

-1

Anda dapat menggunakan lantai devisi dan menambahkan 1 untuknya. 2.3 // 2 + 1


2
atau gunakan ceil()alih-alih melakukan hal yang sebaliknya dan kemudian memberikan kompensasi
guival

2
Ini tidak akan berhasil. Sebagai contoh:from math import ceil; assert 4 // 2 + 1 == ceil(4 / 2)
Carl Thomé

-1

Saya pikir Anda membingungkan mekanisme kerja antara int()dan round().

int()selalu memotong angka desimal jika angka mengambang diberikan; sedangkan round(), dalam hal di 2.5mana 2dan 3keduanya berada dalam jarak yang sama dari 2.5, Python mengembalikan mana yang lebih jauh dari titik 0.

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

"pembulatan" berarti bahwa eg 2.3diubah menjadi 3, yang tidak terjadi pada contoh Anda.
Nearoo

-2

Bagian saya

Saya sudah menguji print(-(-101 // 5)) = 21contoh yang diberikan di atas.

Sekarang untuk mengumpulkan:

101 * 19% = 19.19

Saya tidak bisa menggunakan **jadi saya menyebarkan multiply ke divisi:

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

-3

Saya pada dasarnya seorang pemula di Python, tetapi jika Anda hanya mencoba untuk mengumpulkan alih-alih mengapa tidak melakukannya:

round(integer) + 1

2
Ini tidak akan berfungsi untuk bilangan bulat mana pun saya di mana 2,5 <bilangan bulat <3. Nilai yang diinginkan setelah pembulatan adalah 3 tetapi ekspresi Anda akan mengubahnya menjadi 4.
Pranav Shukla

1
Saya pikir maksud Anda round(integer + 0.5)Inilah yang sering saya lakukan
Klik
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.