Saya mengetahui tentang //
operator dengan Python yang dalam Python 3 melakukan pembagian dengan lantai.
Apakah ada operator yang membagi dengan ceil? (Saya tahu tentang /
operator yang dalam Python 3 melakukan pembagian floating point.)
python
python-3.x
Cradam
sumber
sumber
Jawaban:
Tidak ada operator yang membagi dengan langit-langit. Anda perlu
import math
dan menggunakanmath.ceil
sumber
Anda bisa melakukan pembagian lantai terbalik:
Ini berfungsi karena operator divisi Python melakukan pembagian lantai (tidak seperti di C, di mana pembagian integer memotong bagian pecahan).
Ini juga berfungsi dengan bilangan bulat besar Python, karena tidak ada konversi floating-point (lossy).
Berikut peragaannya:
sumber
int
tidak (yah, tidak ada yang berarti; pada Python 64 bit Anda terbatas pada30 * (2**63 - 1)
angka bit), dan bahkan untuk sementara mengonversifloat
dapat kehilangan informasi. Bandingkanmath.ceil((1 << 128) / 10)
dengan-(-(1 << 128) // 10)
.Anda bisa melakukannya
(x + (d-1)) // d
saat membagix
dengand
, yaitu(x + 4) // 5
.sumber
math.ceil()
.sys.float_info.max
, dan itu tidak memerlukan impor.Solusi 1: Ubah lantai menjadi langit-langit dengan negasi
Mengingatkan pada trik levitasi Penn & Teller , ini "membalikkan dunia (dengan negasi), menggunakan pembagian lantai biasa (di mana langit-langit dan lantai telah ditukar), dan kemudian membalikkan dunia ke kanan (dengan negasi lagi) "
Solusi 2: Biarkan divmod () melakukan pekerjaannya
Fungsi divmod () diberikan
(a // b, a % b)
untuk integer (ini mungkin kurang dapat diandalkan dengan float karena kesalahan round-off). Langkah denganbool(r)
menambahkan satu ke hasil bagi setiap kali ada sisa bukan nol.Solusi 3: Sesuaikan pembilang sebelum pembagian
Terjemahkan pembilangnya ke atas sehingga pembagian lantai membulat ke bawah ke langit-langit yang diinginkan. Catatan, ini hanya berfungsi untuk bilangan bulat.
Solusi 4: Ubah menjadi float untuk menggunakan math.ceil ()
Kode math.ceil () mudah dimengerti, tetapi diubah dari int menjadi floats dan back. Ini tidak terlalu cepat dan mungkin memiliki masalah pembulatan. Juga, ini bergantung pada semantik Python 3 di mana "pembagian benar" menghasilkan pelampung dan di mana fungsi ceil () mengembalikan bilangan bulat.
sumber
-(-a // b)
o_O-(a // -b)
lebih cepat dari-(-a // b)
, setidaknya ketika contoh mainan waktu denganpython -m timeit ...
Anda juga selalu dapat melakukannya secara inline
Dalam python3, ini hanya malu urutan besarnya lebih cepat daripada memaksa divisi float dan memanggil ceil (), asalkan Anda peduli dengan kecepatan. Yang seharusnya tidak Anda lakukan, kecuali Anda telah membuktikan melalui penggunaan yang Anda perlukan.
sumber
number=100000000
). Per satu panggilan, perbedaannya tidak terlalu signifikan.foo = -8
danbar = -4
, misalnya, jawabannya harus 2, bukan 3, sama seperti-8 // -4
. Pembagian lantai Python didefinisikan sebagai "bahwa pembagian matematika dengan fungsi 'lantai' diterapkan pada hasil" dan pembagian langit-langit adalah hal yang sama tetapiceil()
bukan denganfloor()
.Perhatikan bahwa math.ceil dibatasi hingga 53 bit presisi. Jika Anda bekerja dengan bilangan bulat besar, Anda mungkin tidak mendapatkan hasil yang tepat.
The gmpy2 libary menyediakan
c_div
fungsi yang menggunakan langit-langit pembulatan.Penafian: Saya mempertahankan gmpy2.
sumber
python2 -c 'from math import ceil;assert ceil(11520000000000000102.9)==11520000000000000000'
(dan juga menggantikannyapython3
) KEDUATrue
Solusi sederhana: a // b + 1
sumber