TopDev AI Robot TopDev
#Backend & Microservices#Frontend & Web UI#Giải đề & Thuật toán

Tại sao 0.1 + 0.2 !== 0.3 trong máy tính? Bản chất chuẩn số thực dấu phẩy động IEEE 754

Lan Anh (Senior Frontend)
📖 2 phút đọc 💬 1 phản hồi
⚡ Tóm tắt 30 giây bởi TopDev AI
AI Overview

Phép toán cơ bản nhất khiến máy tính bối rối Mở bất kỳ ngôn ngữ lập trình nào JavaScript, Python, C++, Go, Java và chạy biểu thức sau: Đây không phải là lỗi của riêng JavaScript, mà là đặc tính cố hữ…

☰ Mục lục bài viết (6 phần) Mở / Đóng mục lục

Phép toán cơ bản nhất khiến máy tính bối rối#

Mở bất kỳ ngôn ngữ lập trình nào (JavaScript, Python, C++, Go, Java) và chạy biểu thức sau:

JAVASCRIPT
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false

Đây không phải là lỗi của riêng JavaScript, mà là đặc tính cố hữu của việc biểu diễn số thực trên máy tính theo Chuẩn quốc tế IEEE 754 (Định dạng dấu phẩy động 64-bit - Double Precision).

Nguyên nhân toán học: Hệ thập phân vs Hệ nhị phân#

Trong hệ thập phân (hệ cơ số 10), chúng ta không thể biểu diễn chính xác phân số $\frac{1}{3}$: $$\frac{1}{3} = 0.333333333... \text{ (vô hạn tuần hoàn)}$$

Tương tự như vậy trong máy tính (hệ cơ số 2 nhị phân):

  • Một phân số chỉ có thể biểu diễn hữu hạn nếu mẫu số là lũy thừa của 2 (như $\frac{1}{2} = 0.5$, $\frac{1}{4} = 0.25$, $\frac{1}{8} = 0.125$).
  • Số $0.1$ (tức $\frac{1}{10}$) và $0.2$ (tức $\frac{1}{5}$) khi chuyển sang hệ nhị phân sẽ trở thành số vô hạn tuần hoàn: $$0.1_{10} = 0.000110011001100110011..._2$$
  • Vì thanh ghi 64-bit chỉ có đúng 52 bits cho phần định trị (Mantissa), máy tính bắt buộc phải làm tròn (Rounding Error). Sự sai lệch siêu nhỏ ở bit thứ 53 khi cộng lại tạo ra con số đuôi ...0004!

Giải pháp xử lý số liệu tài chính an toàn#

Nếu bạn làm phần mềm ngân hàng, thương mại điện tử, tuyệt đối không bao giờ dùng kiểu float hay double để tính tiền:

1. Quy đổi toàn bộ về số nguyên nhỏ nhất (Cents / Xu / Đồng)#

Thay vì lưu $10.50$, hãy lưu là 1050 xu (Integers). Mọi phép cộng trừ số nguyên luôn chính xác 100%.

2. Sử dụng thư viện số học độ chính xác tùy biến (Arbitrary-precision)#

  • JavaScript: Sử dụng thư viện decimal.js hoặc bignumber.js.
  • Java: Sử dụng BigDecimal.
  • PostgreSQL: Sử dụng kiểu dữ liệu NUMERIC hoặc DECIMAL.

Góc thảo luận#

Dự án của bạn đang lưu trữ số dư tài khoản và giá sản phẩm bằng kiểu dữ liệu gì trong Database? Đã từng gặp lỗi lệch 1 đồng do làm tròn số chưa?


Xem thêm nội dung liên quan:

Chia sẻ thảo luận này:

Thảo luận

1 phản hồi

Ý kiến từ cộng đồng kỹ sư TopDev
💬

Tham gia thảo luận

Cộng đồng mở · Đăng nhập 1-chạm qua Google
  1. Thu Trang (Backend Engineer)
    #1

    Chuẩn mực ngành tài chính: Tiền tệ luôn lưu kiểu NUMERIC(15, 2) hoặc lưu số nguyên tính bằng đơn vị xu. Tuyệt đối cấm dùng FLOAT hay DOUBLE PRECISION trong các bảng kế toán nếu không muốn bị kiểm toán gõ đầu.

Bài liên quan trong #Backend & Microservices

1
TopDev AI Companion
AI
✓ Đã sao chép link