Đây là một vấn đề không cụ thể đối với java. Sử dụng == để so sánh hai số float / double / bất kỳ số loại thập phân nào có khả năng gây ra sự cố do cách chúng được lưu trữ. Một float có độ chính xác đơn (theo tiêu chuẩn IEEE 754) có 32 bit, được phân phối như sau:
1 bit - Dấu (0 = dương, 1 = âm)
8 bit - Biểu diễn lũy thừa (đặc biệt (độ lệch-127) của x trong 2 ^ x)
23 bit - Mantisa. Số Actuall được lưu trữ.
Các mantisa là những gì gây ra vấn đề. Nó giống như ký hiệu khoa học, chỉ có số trong cơ sở 2 (nhị phân) trông giống như 1.110011 x 2 ^ 5 hoặc một cái gì đó tương tự. Nhưng trong hệ nhị phân, số 1 đầu tiên luôn là số 1 (ngoại trừ biểu diễn bằng 0)
Do đó, để tiết kiệm một chút dung lượng bộ nhớ (ý định chơi chữ), IEEE đã quyết định rằng 1 nên được giả sử. Ví dụ, một mantisa của 1011 thực sự là 1.1011.
Điều này có thể gây ra một số vấn đề khi so sánh, đặc biệt là với 0 vì 0 không thể được biểu diễn chính xác trong một float. Đây là lý do chính khiến == không được khuyến khích, ngoài các vấn đề toán học dấu phẩy động được mô tả bởi các câu trả lời khác.
Java có một vấn đề duy nhất là ngôn ngữ này là phổ quát trên nhiều nền tảng khác nhau, mỗi nền tảng có thể có định dạng nổi duy nhất của riêng nó. Điều đó làm cho nó thậm chí còn quan trọng hơn để tránh ==.
Cách thích hợp để so sánh hai số float (tâm trí cụ thể không phải ngôn ngữ của bạn) cho sự bình đẳng như sau:
if(ABS(float1 - float2) < ACCEPTABLE_ERROR)
//they are approximately equal
trong đó ACCEPTABLE_ERROR là #d xác định hoặc một số hằng số khác bằng 0,000000001 hoặc bất kỳ độ chính xác nào được yêu cầu, như Victor đã đề cập.
Một số ngôn ngữ có chức năng này hoặc hằng số này được tích hợp, nhưng nhìn chung đây là một thói quen tốt.