Làm tròn hay làm méo?

Công Nghệ
Làm tròn hay làm méo?
Bài viết được sự cho phép của tác giả Nguyễn Việt Hưng Làm việc với kiểu dữ liệu float (số thực) luôn mang lại những bất ngờ đầy thú vị (thú vị không có hàm ý là tốt hay xấu). Nếu như kiểu integer (số nguyên) luôn tròn trịa, đẹp...

Bài viết được sự cho phép của tác giả Nguyễn Việt Hưng

Làm việc với kiểu dữ liệu float (số thực) luôn mang lại những bất ngờ đầy thú vị (thú vị không có hàm ý là tốt hay xấu). Nếu như kiểu integer (số nguyên) luôn tròn trịa, đẹp đẽ, thì float lại xù xì, thô ráp, thiếu chính xác (float là biểu diễn gần đúng), thực dụng, và đầy dãy bất ngờ.

YinYangYinYang

Số nguyên như một bức tranh về những tưởng tượng của con người. Còn số thực thì rất thực, như cuộc sống này vậy.

Python có sẵn function round dùng để làm tròn một số float về kiểu int, rất dễ hiểu, gần gữi như lúc ta học

P.S: code trong bài sử dụng Python 3.5

In [2]: round(4.2)
Out[2]: 4

In [3]: round(6.9)
Out[3]: 7

In [4]: round(6.0)
Out[4]: 6

In [5]: round(7.0)
Out[5]: 7

Mọi thứ đều đơn giản, cho đến khi có vấn đề xảy ra. Liệu kết quả sẽ thu được là mấy nếu làm tròn 9.5? Là 9 hay là 10? Nếu tuân theo logic thông thường, ta sẽ làm tròn về số nguyên nào mà ở gần 9.5 hơn. Với 9.5, khoảng cách tới 9 hay 10 đều là 0.5. Vậy em chọn lối nào?

Đưa ra lựa chọn là một điều không hề đơn giản, đưa ra lựa chọn đúng thì phải mãi về sau có kết quả rồi ta mới biết.

Giả sử với bộ dữ liệu có

L = [5.5, 6.5, 7.5, 8.5]

Bộ dữ liệu này có giá trị trung bình là

In [1]: L = [5.5, 6.5, 7.5, 8.5]

In [2]: sum(L)/len(L)
Out[2]: 7.0

Khi mang đi làm tròn, ta chỉ muốn thu được các giá trị “tròn” hơn, nhưng vẫn mong muốn giữ nguyên ý nghĩa của bộ dữ liệu – giá trị trung bình (mean) ở đây là một đại diện có thể xem xét.

Nếu làm tròn lên số nguyên lớn hơn, ta có:

In [3]: import math

In [4]: [math.ceil(n) for n in L]
Out[4]: [6, 7, 8, 9]

In [5]: up = [math.ceil(n) for n in L]

In [6]: sum(up)/len(up)
Out[6]: 7.5

Bộ dữ liệu của ta giờ đã có vẻ tiến lên so với ban đầu.

Nếu làm tròn xuống số nguyên gần nhất, ta có:

In [7]: [math.floor(n) for n in L]
Out[7]: [5, 6, 7, 8]

In [8]: down = [math.floor(n) for n in L]

In [9]: sum(down)/len(down)
Out[9]: 6.5

Bộ dữ liệu có vẻ đã “dịch xuống” một chút.

Giải pháp nào để làm tròn mà giảm thiểu sự lệch của bộ dữ liệu? Vấn đề này có thể không xuất hiện ở Việt Nam, với đơn vị tiền tệ biểu diễn bằng kiểu integer, với đơn vị tối thiểu là trăm (đồng), nhưng hẳn đã khiến người Mỹ đau đầu khi đơn vị dola ($) thường xuất hiện ở dạng 1.5 $, 2.4 $…

Và nói đến tiền, những người hiểu về tiền nhất, có lẽ là các nhà ngân hàng (banker). Ngành banker có một phương pháp làm tròn mà Microsoft, … các ngôn ngữ lập trình đều học theo, đó là làm tròn tới số chẵn gần nhất.

In [2]: [round(n) for n in L]
Out[2]: [6, 6, 8, 8]

In [3]: bankers = [round(n) for n in L]

In [4]: sum(bankers)/len(bankers)
Out[4]: 7.0

Trong một bộ số liệu bất kỳ, khi tỷ lệ giữa số chẵn và số lẻ là như nhau, nếu làm tròn 5.5 lên 6 (số chẵn gần nhất), ta tăng nó lên 0.5, còn với 6.5, làm tròn sẽ giảm đi 0.5 thì kết quả là các số lẻ tiến lên, các số chẵn lùi lại, ta giữ được thế cân bằng. Cách làm tròn này vốn tồn tại với cái tên “bankers’ rounding”, sau này được chuẩn hóa vào tiêu chuẩn xử lý số thực (float) IEEE-754 mà hầu hết các ngôn ngữ lập trình tuân theo.

Cái gì quá cũng không tốt, to quá, nhỏ quá, mạnh quá, yếu quá, ít quá, nhiều quá đều không ổn. Vạn vật chỉ phát triển khi đạt tới một thế cân bằng, âm dương hòa hợp, đất trời nảy hoa, cỏ cây xanh lá.

P.P.S: cách làm tròn này là một thay đổi của Python 3 so với Python 2, có ghi trong changelog của python 3.0

Tham khảo

Xem thêm bài viết về một “sự thật” cần biết về số thực tại đây.

Bài viết gốc được đăng tải tại pymi.vn

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên Station D

Bài viết liên quan

Ngành IT: Làm việc “trên mây” kiếm nhiều tiền nhất hiện nay

Ngành IT: Làm việc “trên mây” kiếm nhiều tiền nhất hiện nay

Kết quả từ cuộc khảo sát đầu năm của Station D về lương bổng của lập trình viên cho thấy nhiều thay đổi đã và đang diễn ra trong ngành IT – cuộc khảo sát tập trung vào các câu hỏi về khối lượng công việc, triển vọng cũng như...

By stationd
Đâu chỉ mỗi Bitcoin, công nghệ Blockchain còn nhiều ứng dụng hơn thế!

Đâu chỉ mỗi Bitcoin, công nghệ Blockchain còn nhiều ứng dụng hơn thế!

Khi nhắc đến blockchain , lập tức mọi người thường nghĩ ngay đến các loại tiền mã hóa, chẳng hạn như bitcoin. Tuy nhiên, blockchain lại là công nghệ tạo ra tiền mã hóa nhưng bản thân công nghệ này không phải là tiền mã hóa như cách mà chúng...

By stationd
Mock phương thức static trong Unit Test sử dụng PowerMock

Mock phương thức static trong Unit Test sử dụng PowerMock

Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh Trong bài viết này, mình sẽ hướng dẫn các bạn Mock các phương thức static trong Unit Test các bạn nhé! Nếu bạn nào chưa biết về Mock trong Unit Test thì mình có thể nói sơ qua...

By stationd
Một "thuật ngữ ma" đã tồn tại 75 năm trên internet, nó đang "ám" vào các mô hình AI, và sẽ còn tiếp tục tồn tại cho đến vĩnh cửu

Một "thuật ngữ ma" đã tồn tại 75 năm trên internet, nó đang "ám" vào các mô hình AI, và sẽ còn tiếp tục tồn tại cho đến vĩnh cửu

Một lời cảnh báo cho những người thích trích dẫn kiểu "nguồn sưu tầm", "nguồn internet" hay "nguồn AI", họ có thể sẽ đào lên được những "hóa thạch số" vô nghĩa.

By admin
Cảnh Báo Malware Giả Mạo Hợp Đồng Việc Làm: Tập Tin .EXE Nguy Hiểm Đội Lốt PDF/Word

Cảnh Báo Malware Giả Mạo Hợp Đồng Việc Làm: Tập Tin .EXE Nguy Hiểm Đội Lốt PDF/Word

Kẻ xấu đang lợi dụng nhu cầu tìm việc để phát tán phần mềm độc hại (malware) dưới dạng tệp 'hợp đồng' giả mạo. Hãy cảnh giác với những file có icon Word/PDF nhưng thực chất là .exe. Nếu mở, máy tính của bạn có thể bị đánh cắp toàn bộ thông tin cá nhân, cookie và mật khẩu.

By admin