Làm thế nào để bạn làm tròn số UP trong Python?


487

Vấn đề này đang giết chết tôi. Làm thế nào để làm tròn số UP trong Python?

Tôi đã thử làm tròn (số) nhưng nó làm tròn số xuống. Thí dụ:

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

Tôi đã thử int (số + .5) nhưng nó làm tròn số xuống một lần nữa! Thí dụ:

int(2.3 + .5) = 2

Sau đó, tôi đã thử làm tròn (số + .5) nhưng nó không hoạt động trong các trường hợp cạnh. Thí dụ:

WAIT! THIS WORKED!

Xin tư vấn.


4
round(number + .5)không hoạt động nếu số là số nguyên. round(3+.5) == 4, khi bạn thực sự muốn 3.
Nearoo

Câu trả lời:


845

Các ceil (trần) chức năng:

import math
print(math.ceil(4.2))

21
Xây dựng: math.ceil trả về số nguyên nhỏ nhất lớn hơn hoặc bằng giá trị đầu vào. Hàm này coi đầu vào là một float (Python không có các biến được gõ mạnh) và hàm trả về một float. Nếu bạn muốn một int, bạn có thể xây dựng một int từ giá trị trả về, tức làint(math.ceil(363))
RW Sinnet

9
@Sinnet: Thật ra người ta có thể nói rằng trăn được gõ mạnh stackoverflow.com/a/11328980/5069869
Bernhard

1
@TheEspinosa: Có, python chắc chắn được gõ mạnh , chỉ có nhiều hàm đặt câu hỏi về loại của một số tham số và thực thi mã khác nhau tùy thuộc vào câu trả lời.
quamrana

12
@RWSinnet Trong Python 3, math.ceiltrả về một đối tượng số nguyên thực tế, không chỉ là đối tượng nổi với giá trị nguyên.
Arthur Tacca

Hãy cẩn thận với độ chính xác của phao, do 10000000 * 0.00136 = 13600.000000000002trần nhà có thể tăng lên rất nhiềumath.ceil(10000000 * 0.00136) = 13601.0
kể từ

171

Tôi biết câu trả lời này là cho một câu hỏi từ một thời gian trước, nhưng nếu bạn không muốn nhập môn toán và bạn chỉ muốn làm tròn, thì điều này hiệu quả với tôi.

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

Phần thứ nhất trở thành 4 và phần thứ hai ước tính là "Đúng" nếu có phần còn lại, ngoài ra True = 1; Sai = 0. Vì vậy, nếu không có phần dư, thì nó vẫn giữ nguyên số nguyên, nhưng nếu có phần còn lại thì thêm 1.


38
Đẹp. Bạn cũng có thể sử dụng //để chia số nguyên, vì vậy điều này trở thành 21 // 5 + (21 % 5 > 0).
ness101

6
Đây là giải pháp tốt nhất nếu chỉ có số nguyên được tham gia. Không có floats không cần thiết . Đẹp.
Nico Schlömer

158

Vấn đề Python 2.x thú vị cần ghi nhớ:

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

Vấn đề là việc chia hai int trong python tạo ra một int khác và nó bị cắt trước khi gọi trần. Bạn phải làm cho một giá trị nổi (hoặc bỏ) để có kết quả chính xác.

Trong javascript, cùng một mã tạo ra một kết quả khác nhau:

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

44
Trong Python 2.x : int / int -> int int / float -> float Trong Python 3.x : int / int có thể dẫn đến một float
gecco

7
bạn có thể có được Python 3.x về hành vi trên các phiên bản nhất định của Python 2.x bằng cách bật "phân chia thực sự" như được hiển thị ở đây
Rob Dennis

110

Nếu làm việc với các số nguyên, một cách làm tròn là tận dụng lợi thế của việc làm //tròn xuống: Chỉ cần thực hiện phép chia trên số âm, sau đó phủ nhận câu trả lời. Không có nhập khẩu, dấu phẩy động, hoặc điều kiện cần thiết.

rounded_up = -(-numerator // denominator)

Ví dụ:

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

1
Còn khi bạn không cần thực hiện bất kỳ phép toán nào thì sao? Tức là bạn chỉ có một số.
Klik

2
@Klik: sau đó bạn chỉ có thể chia cho 1 ==> - (-num // 1) và bạn sẽ nhận được câu trả lời của mình :-) Chúc một ngày tốt lành! David Bau: đề nghị rất hay!
Marco smdm

10
Tôi đã tính thời gian cho tất cả các câu trả lời ở đây và nó nhanh hơn năm lần so với câu trả lời tốt nhất tiếp theo (math.ceil). @Andreas đã có cùng thời gian
nhỏ vào

@minitotent Điều đó không đáng ngạc nhiên vì nó là phép chia số nguyên đơn giản và một vài thao tác đơn chu kỳ. Đây là loại câu trả lời giúp bạn có một công việc: Hiểu không chỉ ngôn ngữ, mà tất cả các lớp trừu tượng bên dưới nó.
Nearoo

Đẹp! Tôi đã luôn sử dụng (num + den - 1) // den, điều này tốt cho các intđầu vào có mẫu số dương, nhưng không thành công nếu ngay cả một không tích phân duy nhất floatcó liên quan (cả tử số hoặc mẫu số); cái này trông kỳ diệu hơn, nhưng hoạt động cho cả ints và floats. Đối với các tử số nhỏ, nó cũng nhanh hơn (trên CPython 3.7.2), mặc dù thật kỳ lạ, khi chỉ có tử số đủ lớn để toán học dựa trên mảng là cần thiết, cách tiếp cận của bạn chậm hơn; không rõ lý do tại sao, vì công việc phân chia nên tương tự và hai phủ định đơn phương nên rẻ hơn phép cộng + phép trừ.
ShadowRanger

56

Bạn cũng có thể thích numpy:

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

Tôi không nói rằng nó tốt hơn toán học, nhưng nếu bạn đã sử dụng numpy cho các mục đích khác, bạn có thể giữ mã của mình nhất quán.

Dù sao, chỉ là một chi tiết tôi đi qua. Tôi sử dụng numpy rất nhiều và rất ngạc nhiên khi nó không được đề cập, nhưng tất nhiên câu trả lời được chấp nhận hoạt động hoàn toàn tốt.


3
Sử dụng numpy là tốt quá. Đơn giản nhất sẽ là với toán học vì nó đã là một phần của python được xây dựng trong các thư viện. Nó có ý nghĩa hơn. Thay vào đó như bạn đã đề cập nếu bạn sử dụng nhiều numpy cho các vấn đề khác, thì nó có ý nghĩa và nhất quán khi sử dụng numpy.ceil :-) Gợi ý tốt!
Marco smdm

30

Sử dụngmath.ceil để làm tròn:

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

LƯU Ý : Đầu vào phải nổi.

Nếu bạn cần một số nguyên, hãy gọi intđể chuyển đổi nó:

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

BTW, sử dụng math.floorđể làm tròn xuốngroundlàm tròn đến số nguyên gần nhất.

>>> 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
Đầu vào không nhất thiết phải là một float nếu sử dụng python 3: ceil() sẽ chăm sóc nó bên trong
guival 24/2/2017


11

Tôi ngạc nhiên không ai đề nghị

(numerator + denominator - 1) // denominator

cho phép chia số nguyên với làm tròn lên. Được sử dụng là cách phổ biến cho C / C ++ / CUDA (xem divup)


2
Chỉ liên quan cho các ngôn ngữ gõ tĩnh. Nếu mẫu số là một phao bạn đã chết.
Bharel

Điều này cũng chỉ hoạt động nhất quán nếu mẫu số là dương; nếu mẫu số là âm, bạn cần thêm 1thay vì trừ nó, hoặc lật các dấu của cả tử số và mẫu số trước khi thực hiện phép toán.
ShadowRanger

7

Được shure tròn giá trị nên được nổi

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

nhưng

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

6

Thử cái này:

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

1
Tài giỏi. Các ((int(a) - a) != 0)lợi nhuận biểu hiện 1bất cứ khi nào acần phải được làm tròn lên. Bạn có thể muốn mở rộng câu trả lời của bạn và giải thích cách làm việc này.
Tom Aranda

@TomAranda Bất cứ ai có thể giải thích làm thế nào một biểu thức boolean đánh giá một giá trị xin vui lòng?
Bowen Liu

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

Chức năng này không yêu cầu mô-đun.


Điều gì sẽ xảy ra nếu số của bạn là 3, sau đó nó sẽ làm tròn số 4có thể hoặc không phải là thứ mà ai đó muốn
buydadip

15
Điều này chỉ hoạt động trong 99% của tất cả các trường hợp. Bạn đã không nghĩ điều này thông qua đúng. Những giải pháp như vậy nên tránh bằng mọi giá.
Nearoo

vì vậy thay vì +.5 làm + .49999999 đủ tốt cho tôi.
FlyingZebra1

5

Các câu trả lời trên là chính xác, tuy nhiên, việc nhập mathmô-đun chỉ cho một chức năng này thường tạo cảm giác hơi quá mức cho tôi. May mắn thay, có một cách khác để làm điều đó:

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

TrueFalseđược giải thích như 10trong một tuyên bố liên quan đến các con số trong python. g.is_interger()về cơ bản dịch sang g.has_no_decimal()hoặc g == int(g). Vì vậy, câu cuối cùng bằng tiếng Anh đọc round g down and add one if g has decimal.


1
Và nếu bạn cảm thấy lạ mắt, bạn có thể sử dụng int(g) + (g % 1 > 0)thay thế ;-)
Nearoo

from math import ceildường như sửa lỗi nhập toàn bộ mô-đun toán học :)
SH7890

@ SH7890 Tôi sợ rằng dòng đó không khác nhiều so với import mathnhững gì xảy ra đằng sau hậu trường. Nó chỉ giảm tất cả các biểu tượng ngoại trừ ceil.
Nearoo

5

Không nhập toán học // bằng cách sử dụng envionment cơ bản:

a) phương thức / phương thức lớp

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

Đối với những người muốn làm tròn a / bvà nhận số nguyên:

Một biến thể khác sử dụng phép chia số nguyên là

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

Trong trường hợp bất cứ ai đang tìm cách làm tròn đến một vị trí thập phân cụ thể:

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

1

Tôi ngạc nhiên tôi chưa thấy câu trả lời này round(x + 0.4999), vì vậy tôi sẽ đặt nó xuống. Lưu ý rằng điều này hoạt động với bất kỳ phiên bản Python nào. Những thay đổi được thực hiện cho sơ đồ làm tròn Python đã khiến mọi thứ trở nên khó khăn. Xem bài này .

Không nhập, tôi sử dụng:

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

Tại sao điều này hoạt động

Từ các tài liệu

Đối với các loại tích hợp hỗ trợ round (), các giá trị được làm tròn đến bội số gần nhất của 10 với công suất trừ n; Nếu hai bội số gần nhau như nhau, làm tròn được thực hiện theo lựa chọn chẵn

Do đó, 2,5 được làm tròn thành 2 và 3,5 được làm tròn thành 4. Nếu không phải như vậy thì việc làm tròn có thể được thực hiện bằng cách thêm 0,5, nhưng chúng tôi muốn tránh đi đến điểm giữa chừng. Vì vậy, nếu bạn thêm 0.4999, bạn sẽ nhận được gần, nhưng với biên độ đủ để được làm tròn theo những gì bạn thường mong đợi. Tất nhiên, điều này sẽ thất bại nếu x + 0.4999bằng [n].5000, nhưng điều đó là không thể.


2
Sử dụng 0.4999, nó sẽ không cung cấp kết quả chính xác cho bất kỳ đầu vào nào trong khoảng từ 0000 đến ??? 0001 (khoảng thời gian mở), không chỉ chính xác ???. 0001. Chẳng hạn, nếu bạn thử với 3.00005, bạn sẽ nhận được kết quả là 3 thay vì dự kiến ​​4. Tất nhiên bạn có thể giảm khả năng điều này xảy ra bằng cách thêm ngày càng nhiều chữ số lên độ chính xác tối đa của phao, nhưng đó là chỉ ra rằng nếu có các giải pháp mạnh mẽ và trực quan hơn, như sử dụng math.ceil()?
blubberdiblub

@blubberdiblub Trong câu trả lời của tôi, tôi nêu Without importing I use:. Tôi cũng đã đề cập rằng nó sẽ thất bại nếu x + 0.4999bằng [n].5000.
Klik

4
Có, bạn nêu trong câu trả lời của mình rằng giải pháp của bạn là không cần nhập, nhưng tôi không thấy giá trị của nó. Các mathmô-đun và math.ceil()là trong thư viện tiêu chuẩn, vì vậy có sẵn ở mọi nơi cho tất cả các mục đích thực tế mà không cần cài đặt thêm công cụ. Và liên quan đến việc bạn đề cập đến khi nó thất bại, điều này không đầy đủ trong câu trả lời của bạn, vì nó thất bại trong cả một khoảng thời gian, không chỉ cho một điểm duy nhất. Về mặt kỹ thuật, bạn có thể tranh luận bạn là chính xác, như bạn nói nếu không khi và chỉ khi , nhưng nó sẽ làm cho ấn tượng về người đọc ngẫu nhiên mà nó là ít có khả năng hơn nó thực sự là.
blubberdiblub

0

Để làm điều đó mà không cần nhập bất kỳ:

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

Tôi biết điều này từ khá lâu rồi, nhưng tôi đã tìm thấy một câu trả lời khá thú vị, vì vậy hãy đến đây:

-round(-x-0.5)

Điều này sửa các trường hợp cạnh và hoạt động cho cả số dương và số âm và không yêu cầu nhập bất kỳ chức năng nào

Chúc mừng


2
Điều này vẫn sẽ làm tròn xuống-round(-x-0.3) = x
Diblo Dk

0

Khi bạn vận hành 4500/1000 trong python, kết quả sẽ là 4, vì đối với python mặc định là số nguyên kết quả, theo logic: 4500/1000 = 4.5 -> int (4.5) = 4 và trần của 4 Rõ ràng là 4

sử dụng 4500 / 1000.0, kết quả sẽ là 4,5 và trần là 4,5 -> 5

Sử dụng javascript, bạn sẽ nhận được 4,5 là kết quả của 4500/1000, vì javascript chỉ coi kết quả là "kiểu số" và trả về kết quả trực tiếp dưới dạng float

Chúc may mắn!!


Điều đó chỉ đúng trong Python 2.x. Trong Python 3, phép chia với một lần duy nhất /luôn dẫn đến kết quả là float, vì vậy 4500/1000luôn là 4,5.
Nearoo

0

Nếu bạn không muốn nhập bất cứ thứ gì, bạn luôn có thể viết hàm đơn giản của riêng mình như:

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


2
Điều này không hoạt động nếu num là 2.05. Bạn phải có ít nhất nhiều chữ số với số 9 làm đầu vào của mình, để lại cho bạn 0,99 ... đó là 1. Nhưng sau đó, trường hợp góc 2 của bạn được làm tròn lại. - Chà, tôi đoán có một lý do tại sao math.ceil ở đó.
Julian Maria Frank

-1

Bạn có thể sử dụng độ lệch sàn và thêm 1 vào nó. 2.3 // 2 + 1


2
hoặc sử dụng ceil()thay vì làm điều ngược lại một cách kỳ lạ và sau đó bù lại
guival

2
Điều này sẽ không làm việc. Ví dụ:from math import ceil; assert 4 // 2 + 1 == ceil(4 / 2)
Carl Thomé

-1

Tôi nghĩ rằng bạn đang nhầm lẫn giữa các cơ chế làm việc giữa int()round().

int()luôn luôn cắt các số thập phân nếu một số nổi được đưa ra; trong khi đó round(), trong trường hợp 2.5vị trí 23cả hai đều nằm trong khoảng cách bằng nhau 2.5, Python trả về bất kỳ điểm nào cách xa điểm 0 hơn.

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

"Làm tròn" có nghĩa là ví dụ 2.3được chuyển thành 3, điều này xảy ra trong cả hai ví dụ của bạn.
Nearoo

-2

Chia sẻ của tôi

Tôi đã thử nghiệm print(-(-101 // 5)) = 21ví dụ ở trên.

Bây giờ để làm tròn:

101 * 19% = 19.19

Tôi không thể sử dụng **vì vậy tôi trải rộng bội số để chia:

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

-3

Về cơ bản, tôi là người mới bắt đầu với Python, nhưng nếu bạn chỉ cố gắng làm tròn thay vì xuống thì tại sao không làm:

round(integer) + 1

2
Điều này sẽ không hoạt động đối với bất kỳ số nguyên i nào trong đó 2,5 <số nguyên <3. Giá trị mong muốn sau khi làm tròn là 3 nhưng biểu thức của bạn sẽ biến nó thành 4.
Pranav Shukla

1
Tôi nghĩ ý bạn là round(integer + 0.5)Đây là điều tôi thường làm
Klik
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.