Giới thiệu
Bạn đã bao giờ cảm thấy bối rối khi chạy phép toán 0.1 + 0.2 trong JavaScript? Thay vì kết quả dự kiến là 0.3, bạn lại nhận được 0.30000000000000004. Điều này không chỉ là một hiện tượng kỳ lạ, mà còn là một câu chuyện thú vị về cách máy tính quản lý các số thập phân và vấn đề chính xác.
Hiểu Về Số Học Dấu Phẩy Động
Số học dấu phẩy động là một trong những khái niệm quan trọng trong lập trình mà mỗi lập trình viên đều cần nắm rõ. Khi chúng ta làm việc với các số giống như 1/3, kết quả trả về sẽ là 0.33333… và không bao giờ dừng lại. Như con người, chúng ta thường làm tròn những con số này để dễ hiểu hơn. Nhưng máy tính thì không có khả năng này và thường gặp khó khăn trong việc lưu trữ chính xác các giá trị số.
Tại Sao Lại Xảy Ra Sai Số?
Khi bạn cộng 0.1 và 0.2, thực chất mỗi số này không thể được biểu diễn chính xác trong hệ nhị phân - hình thức mà máy tính sử dụng để lưu trữ số. Hệ thống này chỉ sử dụng hai chữ số: 0 và 1, và không phải tất cả các số thập phân đều có thể chuyển đổi sang nhị phân một cách hoàn hảo. Ví dụ, 0.1 trở thành:
0.0001100110011001100110011001100110011... (lặp mãi mãi)
Tương tự, 0.2 cũng không thể được lưu trữ chính xác, điều này dẫn đến việc máy tính phải cắt bớt các chữ số thừa để tiết kiệm bộ nhớ. Và khi bạn cộng hai giá trị gần đúng này, kết quả cũng trở thành một giá trị gần đúng.
JavaScript Và Tiêu Chuẩn IEEE 754
JavaScript dựa vào tiêu chuẩn IEEE 754, quy định cách lưu trữ và tính toán số dấu phẩy động trong ngôn ngữ này. Tiêu chuẩn này định nghĩa các giới hạn cho số nguyên an toàn mà JavaScript có thể xử lý mà không làm mất độ chính xác:
- Số nguyên an toàn tối đa: 2^53 - 1 (9007199254740991)
- Số nguyên an toàn tối thiểu: -(2^53 - 1) (-9007199254740991)
Giải Pháp Cho Các Số Lớn: BigInt
Nếu bạn cần làm việc với các số lớn hơn giới hạn an toàn như 9007199254740991, JavaScript cung cấp một loại dữ liệu mới mang tên BigInt. Bạn có thể dễ dàng tạo một BigInt bằng cách thêm ký tự "n" vào cuối một số hoặc sử dụng hàm tạo BigInt. Ví dụ:
javascript
const bigNumber = 1234567890123456789012345678901234567890n;
Thực Hiện Các Phép Tính Với BigInt
BigInt cho phép bạn thực hiện các phép toán cơ bản như cộng, trừ, nhân, và lũy thừa. Tuy nhiên, cần lưu ý rằng bạn không thể trộn BigInt và Number trong các phép tính mà không thực hiện chuyển đổi rõ ràng giữa chúng.
Kết Luận
JavaScript sẽ luôn tồn tại các vấn đề liên quan đến sai số chính xác khi làm việc với số thập phân. Tuy nhiên, hiểu rõ những vấn đề này sẽ giúp bạn trở thành một lập trình viên giỏi hơn. Hãy nhớ rằng, nếu bạn cần làm việc với các số lớn hơn giới hạn số nguyên an toàn, BigInt chính là giải pháp tối ưu nhất.
Bạn có đang gặp khó khăn khi sử dụng các phép toán số trong JavaScript? Đừng ngại khám phá thêm về các nguyên lý này để nâng cao khả năng lập trình của bạn!
source: viblo