Vì sao tiền trong lõi sàn không được phép là số thực

Phép thử 10 giây, làm ngay trên trình duyệt bạn đang mở
Bạn đang đọc bài này trên một trình duyệt. Hãy bấm phím F12 — một bảng công cụ hiện ra. Chọn thẻ Console, gõ đúng 7 ký tự này rồi Enter:
0.1+0.2
Máy trả về: 0.30000000000000004.
Không phải 0,3. Thừa ra một cái đuôi 4 nằm ở vị trí thứ 17 sau dấu phẩy. Gõ thêm 0.1+0.2 === 0.3 — máy trả về false. Chiếc máy đang phục vụ bạn đọc bài này khẳng định rằng một phần mười cộng hai phần mười không bằng ba phần mười.
Tôi gặp lại phép tính đó vào ngày bắt đầu viết phần tiền cho cái lõi sàn mà tôi đã kể ở kỳ 1. Và quyết định đầu tiên của cả phần đó không phải một thuật toán. Nó là một lời từ chối: tiền trong lõi này không bao giờ được là số thực.
Vì sao máy sai: 0,1 của chúng ta là số tuần hoàn của máy
Chuyện này không phải lỗi của một hãng nào. Nó nằm trong cách mọi máy tính lưu số lẻ, theo chuẩn chung IEEE-754.
Bạn đã quen với chuyện này ở hệ thập phân: lấy 1 chia 3, được 0,333333... — viết mãi không hết, tới lúc nào đó phải cắt đuôi, và bản cắt không còn đúng tuyệt đối nữa.
Máy tính đếm bằng hệ nhị phân — chỉ có 0 và 1. Và trong hệ nhị phân, 0,1 của chúng ta chính là một số tuần hoàn viết mãi không hết, giống hệt 1/3 trong hệ thập phân. Máy buộc phải cắt đuôi để nhét vào ô nhớ. Mỗi lần cắt, con số lệch đi một mẩu nhỏ hơn một phần tỷ tỷ. Cộng 0,1 với 0,2 là cộng 2 bản-đã-cắt với nhau — và 2 vết cắt chạm nhau thành cái đuôi 4 bạn vừa thấy.
Một mẩu tỷ tỷ thì có sao? — Có, và đây là phép nhân đáng sợ nhất
Với người dùng máy tính bình thường, cái đuôi thứ 17 sau dấu phẩy vô hại tuyệt đối. Màn hình làm tròn trước khi bạn kịp nhìn thấy nó.
Với một cái sổ giữ tiền người khác, câu chuyện đổi hẳn — vì sổ không nhìn số làm tròn trên màn hình. Sổ cộng số thật.
Hình dung một sàn khớp 100.000 lệnh một ngày. Mỗi lệnh đi qua vài phép nhân chia — giá nhân lượng, trừ phí, cộng vào vế này, trừ khỏi vế kia. Mỗi phép tính rụng một hạt bụi vô hình. Phần lớn hạt bụi tự triệt tiêu nhau. Nhưng "phần lớn" không phải "tất cả" — và một ngày nào đó, phép cộng toàn bộ 2 vế của sổ cái lệch nhau đúng 1 đồng.
1 đồng. Nghe như trò đùa. Nhưng ở kỳ 1 tôi đã kể về 7 điều lõi của tôi tự kiểm sau mọi lệnh, và điều số 1 là: tổng nợ bằng tổng có, xét riêng từng tài sản. Với cái sổ như thế, lệch 1 đồng không phải chuyện nhỏ — nó là chuông báo rằng ở đâu đó trong máy có một dòng tiền không giải thích được. Mà không giải thích được 1 đồng hôm nay nghĩa là không có gì bảo đảm ngày mai con số lệch không phải 1 tỷ.
Trong chú thích của tệp tiền tệ, tôi ghi một câu cho chính mình đọc lại: một sàn dùng số thực là một sàn đã hẹn ngày lệch sổ — chỉ chưa biết ngày nào.
Lời giải cũ hơn máy tính: đếm bằng đơn vị nhỏ nhất
Điều dễ chịu nhất của bài toán này là lời giải không cần phát minh. Kế toán đã dùng nó từ trước khi máy tính ra đời: không ghi sổ bằng "một phẩy hai lăm đồng" — ghi bằng số nguyên của đơn vị nhỏ nhất.
2 lời từ chối — và vì sao chúng là quyết định tài chính, không phải kỹ thuật
Lời từ chối thứ nhất: lõi không nhận số thực làm đầu vào. Muốn nạp "1.25" USDT, bạn phải đưa nó dưới dạng chuỗi ký tự, lõi tự đổi thành 1.250.000 đơn vị. Đưa một số thực JavaScript vào là bị chặn từ cửa. Vì nhận số thực ở cửa nghĩa là nhận luôn hạt bụi của nó vào sổ — khử trùng từ cổng rẻ hơn tẩy độc trong kho.
Lời từ chối thứ hai nghiêm hơn: gửi số mịn hơn đơn vị nhỏ nhất là bị chối, không phải được làm tròn giúp. Gửi "0.1234567" vào một tài sản chỉ có 6 chữ số lẻ, lõi không lặng lẽ cắt thành "0.123456". Nó ném lỗi, kèm thông điệp tôi viết nguyên văn: số này mịn hơn scale — lõi từ chối làm tròn tiền.
Vì sao không làm tròn giúp cho tiện? Vì làm tròn tiền của người khác là một quyết định tài chính, và quyết định tài chính thì phải có người ký. Cắt của khách một phần triệu USDT mà không hỏi — con số vô nghĩa về giá trị, nhưng về nguyên tắc thì máy vừa tự ý sửa tiền của người khác. Một cái lõi làm điều đó ở chỗ nhỏ sẽ được tha thứ để làm điều đó ở chỗ lớn.
Còn ở chỗ bắt buộc phải làm tròn — phép chia ra số dư, ví dụ tính phí 0,1% của một số nguyên — thì hướng làm tròn được chọn trước và ghi thành luật trong mã: phần thiệt luôn nghiêng về phía sàn, phần dư không bao giờ được sinh ra từ hư không. Phí làm tròn xuống, về phía sàn thu ít đi. Lượng chưa khớp hết nằm lại trên sổ chờ, không bốc hơi. Từng hạt bụi có địa chỉ.
Chỗ này chạm luật Việt Nam ở đúng một điều khoản
Điều 15 khoản 2 điểm a Nghị quyết 05/2025/NQ-CP buộc tổ chức cung cấp dịch vụ quản lý tách biệt tiền, tài sản mã hóa của khách hàng với tiền, tài sản của chính tổ chức — điều khoản tôi từng gọi là đắt nhất của cả văn bản, trong bài về Mt.Gox và FTX.
Nhưng "tách biệt" chỉ có nghĩa khi kiểm chứng được — nghĩa là đem 2 cái sổ ra đối chiếu và từng đơn vị phải khớp tuyệt đối. Ở đó không tồn tại khái niệm "xấp xỉ": tổng nghĩa vụ với khách bằng đúng tổng tài sản đang giữ, hoặc không bằng. Một hệ thống đếm bằng số thực đứng trước phép đối chiếu đó với một điểm yếu bẩm sinh: nó không thể hứa chữ "đúng tuyệt đối" — nó chỉ hứa được "gần đúng". Và tôi chưa gặp người gửi tiền nào hài lòng với số dư gần đúng.
Thêm một tầng nữa từ chuyện thuế: Thông tư 41 buộc sàn khấu trừ 0,1% ngay lúc lệnh khớp. 0,1% của một số nguyên là một phép chia có dư — và đồng dư đó về túi ai, làm tròn hướng nào, là con số phải khai được với cơ quan thuế trên từng giao dịch. Hướng làm tròn, hóa ra, là thứ nằm trong tầm đọc của một cuộc thanh tra.
Kim đồng hồ đang ở đâu
Chưa sàn nào được cấp phép, và Điều 8 Nghị quyết 05 — như tôi viết ở kỳ 1 — không có dòng nào đo tốc độ hay cách đếm tiền. Nhưng ngày thanh tra đầu tiên bước vào một sàn được cấp phép, câu họ hỏi sẽ không phải "máy anh nhanh bao nhiêu". Sẽ là: "sổ của anh có cân không, và chứng minh kiểu gì?" Bài hôm nay là một nửa câu trả lời kỹ thuật cho câu hỏi đó — nửa còn lại, chuyện cái sổ sống sót qua một lần mất điện, là kỳ 3 của nhật ký này.
Đọc xong rồi thì đi tiếp đâu
Nguồn — bản gốc, mời bạn đọc ở đây
Bài này khác các bài luật một chút: nguồn chính là những phép thử bạn tự chạy lại được, và chuẩn kỹ thuật đứng sau chúng.
0.1+0.2 · 0.1+0.7 · 0.3-0.1 · 0.1+0.2===0.3 · 9007199254740993. 5 dòng, chưa tới 1 phút, đúng trên mọi trình duyệt vì tất cả cùng theo một chuẩn.
Chúc bạn khai ngộ
Master Xuân Hùng
P.s: Sống trong mục tiêu.
Từ mục tiêu, con đường sẽ hiện dần ra.