Đố vui: biểu thức 0.1 + 0.2 > 0.3

bữa có người bạn đó biểu thức trên.
Trong javascript: biểu thức 0.1 + 0.2 > 0.3 là biểu thức đúng luôn bằng true.
có bạn nào giải thích về vấn đề này không.

Bởi vì trong Javascript: 0.1 + 0.2 = 0.30000000000000004 :smile:

2 Likes

Không chỉ Javascript mà nhiều ngôn ngữ khác cũng thế. Điển hình là Python:

>>>1.1 + 2.2 == 3.3
False

Nguyên nhân là do máy tính không thể biểu diễn chính xác số thập phân, nên gây ra sai số kiểu này.

3 Likes

@Luong_Quang_Manh: còn hướng giải quyết thì sao bạn

Lỗi này thuộc về bản chất rồi, không thể khắc phục triệt để được. Python có nhiều giải pháp tạm thời như biến đổi thành string dùng string formatting rồi lại đổi về float, hay sử dụng class Decimal từ thư viện decimal,… nhưng nói chung vẫn chỉ là tạm thời.
Và bạn cũng không cần lo lắng quá đâu, những lỗi này rất ít gặp thôi. Và nếu bạn không làm khoa học hay cần sự chính xác tuyệt đối thì những lỗi này cũng không quá nghiêm trọng.

2 Likes

Cái này là do chuẩn IEEE rồi, tức là do nó biểu diễn số thực dưới dạng tổng lũy thừa của 2 nên có sai số.
vì nó là bản chất nằm ngay trong hệ thống biểu diễn của máy tính nên cách khắc phục hoàn toàn là không có (trừ khi bạn tìm ra 1 chuẩn mới và làm cho cả thế giới thay đổi theo bạn). Cách khắc phục tạm ổn nhất mà không cầu kỳ, đó là sử dụng 1 sai số epsilon nào đó, nếu chênh lệch giữa 2 biểu thức không vượt quá eps này thì xem như chúng bằng nhau
Ví dụ trên python:

>>>abs(0.1 + 0.2 - 0.3) <= 1e-6
True
4 Likes

Đáng lẽ câu trả lời này mới nên là câu trả lời được chọn
Mọi biểu diễn, xử lý trên máy tính cuối cùng đều được quy về hệ nhị phân (bit 0 và 1) hết, thế nên với các số thập phân sẽ được biểu diễn thành số thập phân dấu chấm động (float) kiểu như thế này:

2^1 + 2^-1 + 2^-2 + 2^-3 + ...

và kết quả trả ra là số thập phân có giá trị xấp xỉ số thập phân ban đầu. Số lượng bit biểu diễn phần đằng sau dấu chấm càng nhiều thì sai số càng nhỏ (tất nhiên rồi!)
keyword google thêm: Floating Point Rounding Error

Lỗi này thực ra không hề khó sửa, đa số các ngôn ngữ đều có các hàm math để khắc phục lỗi này, hoặc sử dụng kiểu decimal để biểu diễn số thập phân, và tất nhiên sự chính xác sẽ phải đánh đổi với hiệu năng.

Và cuối cùng thì lỗi này thực ra gặp khá nhiều (chứ chả phải ít gặp), mức độ nghiêm trọng thì tùy thuộc vào tính chất của ứng dụng (vd các ứng dụng liên quan đến tiền bạc mà dính lỗi này là nghiêm trọng rồi, rồi thì làm game dính lỗi này cũng mệt, v.v…)

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?