2012-02-10 68 views
20

Làm thế nào tôi có thể làm tròn lên một số để Place số thập phân thứ ba trong python ví dụ:Vòng lên đến ba chữ số thập phân Nơi bằng Python

0,022499999999999999

nên tròn đến 0,03

0,1111111111111000

Nên làm tròn lên đến 0.12

nếu có bất kỳ giá trị nào ở vị trí thập phân thứ ba, tôi muốn nó luôn luôn làm tròn để lại 2 giá trị sau dấu thập phân

+4

Tôi khuyên bạn nên đọc [Số học dấu chấm động: Các vấn đề và giới hạn] (http://docs.python.org/tutorial/floatingpoint.html) từ hướng dẫn Python trước khi bạn tiếp tục. –

+0

Ngoài ra, hãy cân nhắc xem bạn có thực sự muốn làm tròn các giá trị hay bạn chỉ muốn * hiển thị * chúng với 3 chữ số thập phân ... – geoffspear

Trả lời

17
from math import ceil 

num = 0.1111111111000 
num = ceil(num * 100)/100.0 

Xem:
math.ceil documentation
round documentation - Có thể bạn sẽ muốn kiểm tra này ra anyway để tham khảo trong tương lai

+0

Bạn không cần 'vòng()' ở đây - nó sẽ không thay đổi kết quả bằng mọi cách. –

+2

Cung cấp kết quả sai trong trường hợp sau: 'Math.ceil ((1,11 * 100,0))/100.0' đi ra để được '1.12' Bởi vì: ' 1.11 * 100.0' có giá trị' 111.00000000000001' – nimeshkiranverma

+1

@nimeshkiranverma xem [Toán học dấu chấm động có bị hỏng không?] (https://stackoverflow.com/questions/588004/is-floating-point-math-broken) Sử dụng ['decimal' module] (https://docs.python.org /3/library/decimal.html) nếu bạn cần kết quả thập phân chính xác. –

34

Python bao gồm các chức năng mà round()lets you specify số chữ số bạn muốn. Từ các tài liệu:

round(x[, n])

Return giá trị dấu chấm động x làm tròn đến n chữ số sau dấu thập phân. Nếu n được bỏ qua, nó mặc định là 0. Kết quả là một số dấu chấm động. Các giá trị được làm tròn đến bội số gần nhất của 10 đến công suất trừ n; nếu hai bội số là bằng nhau gần, làm tròn được thực hiện từ 0 (ví dụ, vòng (0.5) là 1.0 và tròn (-0.5) là -1.0).

Vì vậy, bạn muốn sử dụng round(x, 2) để làm tròn thông thường. Để đảm bảo rằng số này luôn được làm tròn lên, bạn sẽ cần phải sử dụng chức năng ceil(x). Tương tự, để làm tròn xuống, hãy sử dụng floor(x).

+4

Đề nghị tốt, nhưng nó không tròn ** lên ** như OP dường như yêu cầu. – NPE

+1

"Làm tròn" không giống như làm tròn thông thường. Nhìn vào các ví dụ trong câu hỏi. –

+0

Cả hai đều đúng - tôi đang chỉnh sửa ngay bây giờ. – simchona

10
x = math.ceil(x * 100.0)/100.0 
+1

Tôi đã phải nhìn chằm chằm vào điều này một lúc trước khi tôi nhận ra điều này thậm chí còn sâu sắc hơn so với giải pháp của tôi. – Edwin

9

Ngoại suy từ câu trả lời của Edwin:

from math import ceil, floor 
def float_round(num, places = 0, direction = floor): 
    return direction(num * (10**places))/float(10**places) 

Cách sử dụng:

>>> float_round(0.21111, 3, ceil) #round up 
>>> 0.212 
>>> float_round(0.21111, 3)  #round down 
>>> 0.211 
>>> float_round(0.21111, 3, round) #round naturally 
>>> 0.211 
+1

Cho kết quả sai trong các trường hợp sau: 'math.ceil ((1.11 * 100.0))/100.0' xuất hiện là '1.12' Bởi vì: '1.11 * 100.0' có giá trị' 111.00000000000001' – nimeshkiranverma

3

Lưu ý rằng các trick ceil(num * 100)/100 sẽ sụp đổ trên một số đầu vào thoái hóa, như 1e308. Điều này có thể không xuất hiện thường xuyên nhưng tôi có thể nói với bạn rằng nó chỉ chi phí cho tôi một vài ngày. Để tránh điều này, "sẽ rất tuyệt nếu" ceil()floor() lấy một đối số vị trí thập phân, như round() hiện ... Trong khi đó, bất kỳ ai biết một giải pháp thay thế sạch sẽ sẽ không gặp sự cố về đầu vào như thế này? Tôi đã có một số hy vọng về gói decimal nhưng có vẻ như chết quá:

>>> from math import ceil 
>>> from decimal import Decimal, ROUND_DOWN, ROUND_UP 
>>> num = 0.1111111111000 
>>> ceil(num * 100)/100 
0.12 
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP)) 
0.12 
>>> num = 1e308 
>>> ceil(num * 100)/100 
Traceback (most recent call last): 
    File "<string>", line 301, in runcode 
    File "<interactive input>", line 1, in <module> 
OverflowError: cannot convert float infinity to integer 
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP)) 
Traceback (most recent call last): 
    File "<string>", line 301, in runcode 
    File "<interactive input>", line 1, in <module> 
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>] 

Tất nhiên người ta có thể nói bị rơi đó là hành vi lành mạnh chỉ trên đầu vào như vậy, nhưng tôi cho rằng nó không phải là làm tròn nhưng nhân đó là nguyên nhân gây ra vấn đề (đó là lý do tại sao, ví dụ, 1e306 không sụp đổ), và việc thực hiện sạch hơn của fn round-up-nnth-place sẽ tránh được việc hack nhân.

+0

Vấn đề bạn đang gặp phải với việc sử dụng' thập phân' này là kết quả của biểu thức lượng tử cần 311 chữ số để thể hiện và độ chính xác hiện tại quá nhỏ. Nếu bạn thực hiện một 'từ nhập khẩu thập phân getcontext; getcontext(). prec = 400' trước, điều này sẽ "làm việc", đối với một số giá trị của "công việc". Hoặc bạn có thể lưu ý rằng bất kỳ phao lớn hơn 2 ** 52 trong giá trị tuyệt đối phải là một số nguyên, do đó làm tròn sẽ không có hiệu lực. Và có, tôi đồng ý nó sẽ tốt đẹp nếu "ceil" và "sàn" lấy một đối số thập phân. –

7

Điều này phụ thuộc vào hành vi bạn muốn khi xem xét số dương và số âm, nhưng nếu bạn muốn thứ gì đó luôn tròn thành giá trị lớn hơn (ví dụ: 2,0449 -> 2,05, -2.0449 -> -2,04) sau đó bạn có thể làm:

round(x + 0.005, 2) 

hoặc một chút fancier:

def round_up(x, place): 
    return round(x + 5 * 10**(-1 * (place + 1)), place) 

này cũng dường như làm việc như sau:

round(144, -1) 
# 140 
round_up(144, -1) 
# 150 
round_up(1e308, -307) 
# 1.1e308 
0

Các funtion tròn nói không không hoạt động để xóa số nguyên như:

a = 8
tròn (a, 3)
8,0
a = 8,00
tròn (a, 3)
8,0
a = 8,000000000000000000000000
tròn (a, 3)
8.0

nhưng, làm việc cho:

r = 400/3,0
r
133,33333333333334
tròn (r, 3)
133,333

Hơn thế nữa các số thập phân như 2.675 được làm tròn thành 2,67 n ot 2,68.
Sử dụng tốt hơn phương pháp khác được cung cấp ở trên.

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