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.

bodacydo
sumber
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))
Steve Tjoa
sumber
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.

pengguna3074620
sumber
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
TrofiGeek
sumber
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
David Bau
sumber
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.

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

Sintaksnya mungkin tidak se pythonic seperti yang mungkin disukai, tetapi ini adalah pustaka yang kuat.

https://docs.python.org/2/library/decimal.html

from decimal import *
print(int(Decimal(2.3).quantize(Decimal('1.'), rounding=ROUND_UP)))
NuclearPeon
sumber
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)

Andreas Schuh
sumber
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
Alexey
sumber
6

Coba ini:

a = 211.0
print(int(a) + ((int(a) - a) != 0))
pengguna3712978
sumber
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.

PonasM
sumber
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 .

Nearoo
sumber
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)
Kuřátko Zvyk
sumber
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
Pavel
sumber
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
osuwireless
sumber
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.

Klik
sumber
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
Gorttar
sumber
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

Fenmaz
sumber
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!!

erick vicente
sumber
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)

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

pengguna6612280
sumber
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
SooBin Kim
sumber
"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
andres
sumber
-3

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

round(integer) + 1
Daniel
sumber
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