2013-02-11 31 views
59

Tôi đã tìm hiểu về toán tử // bằng Python trong Python 3 phân chia với sàn.Có trần tương đương với // toán tử bằng Python không?

Có nhà điều hành nào phân chia bằng ceil thay thế không? (Tôi biết về các nhà điều hành / mà trong Python 3 không phân chia điểm nổi.)

+0

"chia-then-ceil" là không thực sự là một điều phổ biến trong toán học, trong khi '// 'được dựa trên nguyên phân-với-mô đun hoạt động. – millimoose

+0

Quan trọng: bạn có muốn có kết quả int hay float không? – smci

+3

Bạn nên thay đổi câu trả lời được chấp nhận thành dlitz's. math.ceil là cho float, nó không hoạt động với ints dài chính xác tùy ý của Python. – endolith

Trả lời

35

Không có toán tử chia cho ceil. Bạn cần phải import math và sử dụng math.ceil

+0

vì vậy foobar = math.ceil (foo/bar)? Hmm, tôi có thể sống với điều đó, không biết bất cứ nơi nào tôi muốn sử dụng, chỉ tò mò, cảm ơn – Cradam

+8

–1 ** không sử dụng **, điều này sẽ bắt đầu thất bại cho các số nguyên rất lớn. Hoặc sử dụng một thư viện số học nhiều độ chính xác hoặc ở trong miền số nguyên với cách tiếp cận [this] (https://stackoverflow.com/a/17511341/674039). – wim

9

Bạn có thể làm (x + (d-1)) // d khi chia x bởi d, ví dụ: (x + 4) // 5.

+0

Đây là phương pháp cổ điển mà tôi đã sử dụng vĩnh viễn. Không làm việc cho ước số tiêu cực mặc dù. –

+0

Nó tạo ra [cùng một kết quả] (https://repl.it/FZGd/5) dưới dạng 'math.ceil()'. – Abhijeet

+0

@Abhijeet Vâng, đó là câu hỏi đặt ra. Ngoại trừ nó hoạt động tốt hơn cho các số nguyên lớn ở trên 'sys.float_info.max' và nó không yêu cầu nhập. – Artyer

8

Bạn có thể luôn luôn chỉ làm điều đó inline cũng

((foo - 1) // bar) + 1 

Trong python3, đây chỉ là nhút nhát của một thứ tự cường độ nhanh hơn buộc các bộ phận phao và gọi ceil(), với điều kiện bạn quan tâm về tốc độ . Mà bạn không nên, trừ khi bạn đã chứng minh thông qua việc sử dụng mà bạn cần.

>>> timeit.timeit("((5 - 1) // 4) + 1", number = 100000000) 
1.7249219375662506 
>>> timeit.timeit("ceil(5/4)", setup="from math import ceil", number = 100000000) 
12.096064013894647 
+0

chỉ cần chạy những bài kiểm tra bản thân mình tôi nhận được khoảng 12,5 giây, ehrm, tại sao tôi không quan tâm về tốc độ khi nó là một sự khác biệt tốc độ rất lớn? – Cradam

+2

@Cradam Lưu ý rằng anh ấy đang sử dụng 100 triệu cuộc gọi ('number = 100000000'). Mỗi cuộc gọi duy nhất, sự khác biệt là khá không đáng kể. –

+0

ahh, cảm ơn, tôi sẽ sử dụng phương pháp ceil sau đó – Cradam

7

Lưu ý rằng math.ceil bị giới hạn ở 53 bit chính xác. Nếu bạn đang làm việc với số nguyên lớn, bạn có thể không nhận được kết quả chính xác.

Thư viện gmpy2 cung cấp chức năng c_div sử dụng làm tròn trần.

Tuyên bố từ chối trách nhiệm: Tôi duy trì gmpy2.

+2

Gói này sẽ hữu ích nếu tôi đang làm một cái gì đó nặng nề về toán học hoặc khoa học định hướng, tôi thích câu trả lời sử dụng các thư viện lõi mặc dù. Tôi đang đưa ra một upvote mặc dù vì nó là một câu trả lời hữu ích – Cradam

163

Bạn có thể chỉ làm phận sàn lộn ngược:

def ceildiv(a, b): 
    return -(-a // b) 

này hoạt động vì Python's division operator does floor division (không giống như trong C, nơi phân chia số nguyên truncates phần phân đoạn).

Điều này cũng hoạt động với các số nguyên lớn của Python, vì không có chuyển đổi dấu chấm động (mất).

Dưới đây là một cuộc biểu tình:

>>> from __future__ import division # a/b is float division 
>>> from math import ceil 
>>> b = 3 
>>> for a in range(-7, 8): 
...  print(["%d/%d" % (a, b), int(ceil(a/b)), -(-a // b)]) 
... 
['-7/3', -2, -2] 
['-6/3', -2, -2] 
['-5/3', -1, -1] 
['-4/3', -1, -1] 
['-3/3', -1, -1] 
['-2/3', 0, 0] 
['-1/3', 0, 0] 
['0/3', 0, 0] 
['1/3', 1, 1] 
['2/3', 1, 1] 
['3/3', 1, 1] 
['4/3', 2, 2] 
['5/3', 2, 2] 
['6/3', 2, 2] 
['7/3', 3, 3] 
+11

Wow! Rất thông minh! Đây phải là giải pháp được chấp nhận. – apadana

Các vấn đề liên quan