Tôi đang phải đối mặt với một hành vi kỳ lạ của hàm
>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
3:for i in range[1, 15, 2]:
n = i / 2
print[n, "=>", round[n]]
Mã này in:
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
Tôi dự kiến các giá trị nổi sẽ luôn được làm tròn, nhưng thay vào đó, nó được làm tròn đến số chẵn gần nhất.
Tại sao hành vi như vậy, và cách tốt nhất để có được kết quả chính xác là gì?
Tôi đã cố gắng sử dụng
>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
4 nhưng kết quả là như nhau.
Martineau
Huy hiệu vàng 115K2525 gold badges160 silver badges284 bronze badges
Hỏi ngày 8 tháng 10 năm 2015 lúc 15:11Oct 8, 2015 at 15:11
4
Phần các loại số ghi lại hành vi này một cách rõ ràng:
5 x làm tròn thành n chữ số, làm tròn một nửa đến chẵn. Nếu N bị bỏ qua, nó mặc định là 0.>>> from decimal import localcontext, Decimal, ROUND_HALF_UP >>> with localcontext[] as ctx: ... ctx.rounding = ROUND_HALF_UP ... for i in range[1, 15, 2]: ... n = Decimal[i] / 2 ... print[n, '=>', n.to_integral_value[]] ... 0.5 => 1 1.5 => 2 2.5 => 3 3.5 => 4 4.5 => 5 5.5 => 6 6.5 => 7
x rounded to n digits, rounding half to even. If n is omitted, it defaults to 0.
Lưu ý một nửa làm tròn đến chẵn. Đây cũng được gọi là nhân viên ngân hàng làm tròn; Thay vì luôn luôn làm tròn hoặc xuống [các lỗi làm tròn gộp], bằng cách làm tròn đến số gần nhất, bạn trung bình các lỗi làm tròn.
Nếu bạn cần kiểm soát nhiều hơn đối với hành vi làm tròn, hãy sử dụng mô -đun
>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
6, cho phép bạn chỉ định chính xác chiến lược làm tròn nào nên được sử dụng.Ví dụ, để làm tròn từ một nửa:
>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
Đã trả lời ngày 8 tháng 10 năm 2015 lúc 15:24Oct 8, 2015 at 15:24
Martijn Pieters ♦ Martijn Pieters♦Martijn Pieters
988K275 Huy hiệu vàng3888 Huy hiệu bạc3245 Huy hiệu Đồng275 gold badges3888 silver badges3245 bronze badges
3
Ví dụ:
from decimal import Decimal, ROUND_HALF_UP
Decimal[1.5].quantize[0, ROUND_HALF_UP]
# This also works for rounding to the integer part:
Decimal[1.5].to_integral_value[rounding=ROUND_HALF_UP]
Đã trả lời ngày 8 tháng 10 năm 2015 lúc 15:28Oct 8, 2015 at 15:28
Dhobbsdhobbsdhobbs
3.1171 Huy hiệu vàng17 Huy hiệu bạc18 Huy hiệu đồng1 gold badge17 silver badges18 bronze badges
Bạn có thể sử dụng điều này:
import math
def normal_round[n]:
if n - math.floor[n] < 0.5:
return math.floor[n]
return math.ceil[n]
Nó sẽ làm tròn số lên hoặc xuống đúng cách.
Đã trả lời ngày 18 tháng 12 năm 2016 lúc 7:20Dec 18, 2016 at 7:20
fedor2612fedor2612fedor2612
4214 Huy hiệu bạc6 Huy hiệu Đồng4 silver badges6 bronze badges
2
>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
3 sẽ làm tròn hoặc xuống, tùy thuộc vào số lượng chẵn hay số lẻ. Một cách đơn giản để chỉ làm tròn là:int[num + 0.5]
Nếu bạn muốn điều này hoạt động đúng cho các số âm sử dụng:
[[num > 0] - [num < 0]] * int[abs[num] + 0.5]
Lưu ý, điều này có thể gây rối cho số lượng lớn hoặc các số thực sự chính xác như
>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
8 và >>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
9.Đã trả lời ngày 31 tháng 7 năm 2017 lúc 19:51Jul 31, 2017 at 19:51
3
Hành vi bạn đang thấy là hành vi làm tròn IEEE 754 điển hình. Nếu nó phải chọn giữa hai số khác nhau như nhau so với đầu vào, nó luôn chọn một số. Ưu điểm của hành vi này là hiệu ứng làm tròn trung bình bằng không - không kém nhiều số làm tròn lên xuống. Nếu bạn làm tròn các số nửa chiều theo một hướng nhất quán, việc làm tròn sẽ ảnh hưởng đến giá trị dự kiến.
Hành vi bạn đang thấy là chính xác nếu mục tiêu là làm tròn công bằng, nhưng điều đó không phải lúc nào cũng cần thiết.
Một mẹo để có được loại làm tròn bạn muốn là thêm 0,5 và sau đó lấy sàn. Ví dụ, thêm 0,5 đến 2,5 cho 3, với tầng 3.
Đã trả lời ngày 8 tháng 10 năm 2015 lúc 15:24Oct 8, 2015 at 15:24
0
Martijn Pieters ♦ Martijn Pieters
import math
def normal_round[n, decimals=0]:
expoN = n * 10 ** decimals
if abs[expoN] - abs[math.floor[expoN]] < 0.5:
return math.floor[expoN] / 10 ** decimals
return math.ceil[expoN] / 10 ** decimals
oldRounding = round[26.455,2]
newRounding = normal_round[26.455,2]
print[oldRounding]
print[newRounding]
Output:
26.45
26.46
988K275 Huy hiệu vàng3888 Huy hiệu bạc3245 Huy hiệu ĐồngOct 2, 2018 at 23:47
Ví dụ:Joe Cat
Đã trả lời ngày 8 tháng 10 năm 2015 lúc 15:281 silver badge8 bronze badges
1
Dhobbsdhobbs
def HalfRoundUp[value]:
return int[value + 0.5]
3.1171 Huy hiệu vàng17 Huy hiệu bạc18 Huy hiệu đồng
HalfRoundUp = lambda value: int[value + 0.5]
Bạn có thể sử dụng điều này:Jun 20, 2021 at 22:50
Nó sẽ làm tròn số lên hoặc xuống đúng cách.TeaCoast
Đã trả lời ngày 18 tháng 12 năm 2016 lúc 7:201 silver badge10 bronze badges
3
4214 Huy hiệu bạc6 Huy hiệu Đồngreally 2.67499999999999982236431605997495353221893310546875 [exactly]. And you can specify the rounding you desire: ROUND_CEILING, ROUND_DOWN, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_UP, and ROUND_05UP are all options.
>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
3 sẽ làm tròn hoặc xuống, tùy thuộc vào số lượng chẵn hay số lẻ. Một cách đơn giản để chỉ làm tròn là:Oct 8, 2015 at 15:20
Nếu bạn muốn điều này hoạt động đúng cho các số âm sử dụng:rmunn
Lưu ý, điều này có thể gây rối cho số lượng lớn hoặc các số thực sự chính xác như
8 và >>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
9.9 gold badges71 silver badges103 bronze badges>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
0
Đã trả lời ngày 31 tháng 7 năm 2017 lúc 19:51
Hành vi bạn đang thấy là hành vi làm tròn IEEE 754 điển hình. Nếu nó phải chọn giữa hai số khác nhau như nhau so với đầu vào, nó luôn chọn một số. Ưu điểm của hành vi này là hiệu ứng làm tròn trung bình bằng không - không kém nhiều số làm tròn lên xuống. Nếu bạn làm tròn các số nửa chiều theo một hướng nhất quán, việc làm tròn sẽ ảnh hưởng đến giá trị dự kiến.
Hành vi bạn đang thấy là chính xác nếu mục tiêu là làm tròn công bằng, nhưng điều đó không phải lúc nào cũng cần thiết.Oct 8, 2015 at 15:19
Một mẹo để có được loại làm tròn bạn muốn là thêm 0,5 và sau đó lấy sàn. Ví dụ, thêm 0,5 đến 2,5 cho 3, với tầng 3.MRocklin
Yêu câu trả lời của Fedor2612. Tôi đã mở rộng nó với một đối số "số thập phân" tùy chọn cho những người muốn sử dụng hàm này để làm tròn bất kỳ số lượng số thập phân nào [ví dụ: nếu bạn muốn làm tròn một loại tiền tệ $ 26,455 đến $ 26,46].21 gold badges146 silver badges220 bronze badges
1
Đã trả lời ngày 2 tháng 10 năm 2018 lúc 23:47
Joe Catjoe Cat
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
01591 Huy hiệu bạc8 Huy hiệu đồngJul 11, 2019 at 9:40
Tại sao làm cho nó rất phức tạp?
Tất nhiên bạn có thể biến nó thành một lambda sẽ là:
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
1Đã trả lời ngày 20 tháng 6 năm 2021 lúc 22:50
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
2TeacoasttecoastJun 15, 2021 at 7:50
1861 Huy hiệu bạc10 Huy hiệu đồngdodge
Phiên bản ngắn: Sử dụng mô -đun thập phân. Nó có thể biểu thị các số như 2.675 chính xác, không giống như phao Python trong đó 2.675 thực sự là 2.674999999999998236431605997495353221893310546875 [chính xác]. Và bạn có thể chỉ định làm tròn mà bạn mong muốn: Round_ceiling, Round_down, Round_floor, Round_half_down, Round_Half_Even, Round_half_up, Round_up và Round_05Up đều là các tùy chọn.1 silver badge4 bronze badges
Đã trả lời ngày 8 tháng 10 năm 2015 lúc 15:20
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
3from decimal import Decimal, ROUND_HALF_UP
Decimal[1.5].quantize[0, ROUND_HALF_UP]
# This also works for rounding to the integer part:
Decimal[1.5].to_integral_value[rounding=ROUND_HALF_UP]
4rmunnrmunnNov 15, 2018 at 23:18
33.2K9 Huy hiệu vàng71 Huy hiệu bạc103 Huy hiệu đồngdiscover
Làm tròn đến số gần nhất đã trở thành thông lệ trong các ngành số. "Làm tròn lên" tạo ra một sự thiên vị nhẹ đối với kết quả lớn hơn.1 gold badge4 silver badges14 bronze badges
1
Giải pháp sau đây đạt được "thời trang trường học" mà không sử dụng mô -đun
>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
6 [hóa ra là chậm].0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
4ví dụ.
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
5Đã trả lời ngày 20 tháng 12 năm 2018 lúc 15:51Dec 20, 2018 at 15:51
Vì vậy, chỉ để đảm bảo có một ví dụ hoạt động rõ ràng ở đây, tôi đã viết một chức năng tiện lợi nhỏ
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
6Và một tập hợp các trường hợp kiểm tra thích hợp
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
7Đã trả lời ngày 19 tháng 12 năm 2020 lúc 15:43Dec 19, 2020 at 15:43
Bạn có thể dùng:
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
8Đã trả lời ngày 8 tháng 10 năm 2015 lúc 15:29Oct 8, 2015 at 15:29
CDONTSCDONTScdonts
8.9283 Huy hiệu vàng42 Huy hiệu bạc71 Huy hiệu đồng3 gold badges42 silver badges71 bronze badges
Một cách làm tròn toán học cổ điển mà không có bất kỳ thư viện nào
0.5 => 0
1.5 => 2
2.5 => 2
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
9Đã trả lời ngày 16 tháng 12 năm 2018 lúc 14:12Dec 16, 2018 at 14:12
Biết rằng
from decimal import Decimal, ROUND_HALF_UP
Decimal[1.5].quantize[0, ROUND_HALF_UP]
# This also works for rounding to the integer part:
Decimal[1.5].to_integral_value[rounding=ROUND_HALF_UP]
6 vòng đến from decimal import Decimal, ROUND_HALF_UP
Decimal[1.5].quantize[0, ROUND_HALF_UP]
# This also works for rounding to the integer part:
Decimal[1.5].to_integral_value[rounding=ROUND_HALF_UP]
7 và from decimal import Decimal, ROUND_HALF_UP
Decimal[1.5].quantize[0, ROUND_HALF_UP]
# This also works for rounding to the integer part:
Decimal[1.5].to_integral_value[rounding=ROUND_HALF_UP]
8 vòng để from decimal import Decimal, ROUND_HALF_UP
Decimal[1.5].quantize[0, ROUND_HALF_UP]
# This also works for rounding to the integer part:
Decimal[1.5].to_integral_value[rounding=ROUND_HALF_UP]
9 mang lại thành công:Mục tiêu: Cung cấp số vòng thấp hơn và cao hơn tùy thuộc vào
import math
def normal_round[n]:
if n - math.floor[n] < 0.5:
return math.floor[n]
return math.ceil[n]
0>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
0Một số thử nghiệm:
YW
Đã trả lời ngày 9 tháng 11 năm 2019 lúc 18:54Nov 9, 2019 at 18:54
gies0rgies0rgies0r
4.0951 Huy hiệu vàng35 Huy hiệu bạc44 Huy hiệu đồng1 gold badge35 silver badges44 bronze badges
>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
1Đã trả lời ngày 26 tháng 3 năm 2020 lúc 11:06Mar 26, 2020 at 11:06
LetzerwilleletzerwilleLetzerWille
5.2234 Huy hiệu vàng22 Huy hiệu bạc26 Huy hiệu đồng4 gold badges22 silver badges26 bronze badges
Bạn có thể thử cái này
>>> from decimal import localcontext, Decimal, ROUND_HALF_UP
>>> with localcontext[] as ctx:
... ctx.rounding = ROUND_HALF_UP
... for i in range[1, 15, 2]:
... n = Decimal[i] / 2
... print[n, '=>', n.to_integral_value[]]
...
0.5 => 1
1.5 => 2
2.5 => 3
3.5 => 4
4.5 => 5
5.5 => 6
6.5 => 7
2Nó sẽ hoạt động vì
import math
def normal_round[n]:
if n - math.floor[n] < 0.5:
return math.floor[n]
return math.ceil[n]
1 sẽ luôn luôn là ____42 trong quá trình gần với import math
def normal_round[n]:
if n - math.floor[n] < 0.5:
return math.floor[n]
return math.ceil[n]
3 do đó chức năng tròn sẽ hoạt động đúng và nó sẽ làm tròn import math
def normal_round[n]:
if n - math.floor[n] < 0.5:
return math.floor[n]
return math.ceil[n]
4 đến import math
def normal_round[n]:
if n - math.floor[n] < 0.5:
return math.floor[n]
return math.ceil[n]
3Đã trả lời ngày 5 tháng 7 năm 2019 lúc 7:32Jul 5, 2019 at 7:32
seVenVo1dseVenVo1dseVenVo1d
3686 Huy hiệu bạc15 Huy hiệu Đồng6 silver badges15 bronze badges
1