2015-08-14 23 views
6

Tại sao Java không nhất quán khi so sánh -0.0 và +0.0? Phương pháp chuẩn Java để so sánh các số với tài khoản cho -0/+ 0 là gì?Java - so sánh các số 0 dương và âm

Tôi đã gặp ông kẹ này cụ thể:

public class ZeroCompare { 
    public static void main(String[] args) { 
     if (0.0 == -0.0) { 
      System.out.println("== --> same"); 
     } else { 
      System.out.println("== --> different"); 
     } 

     if (new Double(0.0).equals(-0.0)) { 
      System.out.println("equals --> same"); 
     } else { 
      System.out.println("equals --> different"); 
     } 
    } 
} 

It in như sau:

== --> same 
equals --> different 

tôi mạnh mẽ không thích thực tế là như thế nào bạn so sánh hai giá trị này ảnh hưởng đến kết quả và tôi muốn yêu cho một lời giải thích.

+0

trước tiên chữ bên trong bằng (-0,0) là Float không phải là Gấp đôi. và thứ hai phương thức equals so sánh các đối tượng và cho các literals khác nhau có các đối tượng wrapper khác nhau. –

+1

@amitmahajan Đó là một đôi. Nó sẽ yêu cầu một 'f' hoặc' F' ở cuối là một chữ phao. – Kayaman

+0

Nhân tiện, các số dấu phẩy động không bao giờ được so sánh với sự bình đẳng chính xác. Họ yêu cầu một giá trị đồng bằng nhỏ để xem nếu hai số đủ gần để được coi là bằng nhau (mặc dù trong trường hợp cụ thể này, đây là một vấn đề nhỏ). – Kayaman

Trả lời

10

Hành vi này là actually documented:

Nếu d1 đại diện cho 0,0 trong khi d2 đại diện -0,0, hoặc ngược lại, các thử nghiệm tương đương có giá trị sai, mặc dù 0,0 == - 0.0 có giá trị thực . Định nghĩa này cho phép các bảng băm hoạt động đúng.

+0

Hãy cẩn thận chút ít trong Javadoc ... – Kayaman

+0

Cảm ơn bạn đã liên kết. Khi tôi googled nó, tôi đã ban đầu hy vọng các tài liệu java sẽ được kéo lên. Nhưng rõ ràng, Google tìm thấy stackoverflow phổ biến hơn nhiều. – Curds

+1

Tôi không biết nếu tôi đồng ý với quyết tâm của Java rằng điều này "cho phép bảng băm hoạt động đúng" Hãy tưởng tượng tôi có các giá trị dấu phẩy động (32 hoặc 64 bit) mà tôi đang sử dụng làm khóa trong bản đồ băm (kỳ lạ, tôi biết. Đó là một ví dụ.) Giả sử mã của tôi làm việc với phao, nhưng băm trên Floats. Bởi vì autoboxing, tôi có thể lập chỉ mục với phao trực tiếp. Bên ngoài bản đồ băm, 0,0 và -0.0 sẽ so sánh tương tự - nhưng chúng sẽ tạo hai mục khác nhau trong bản đồ băm. Python đi theo cách khác; vì 0,0 và -0,0 được coi là "bằng nhau", chúng băm giống nhau. Tôi nghĩ tôi thích điều đó. – Curds

1

Java Language Specification: Numerical Comparison Operators <, <=, >, and >=

tích cực và tiêu cực zero zero được coi là bình đẳng.

Double.valueOf (+0.0) và Double.valueOf (-0.0) có các biểu diễn bit khác nhau. Double.equals so sánh biểu diễn bit.

Ngoài ra, bạn có thể sử dụng Double.compare

+0

Tôi ngạc nhiên khi biểu diễn bit đôi của +/- 0.0 khác với biểu diễn nguyên thủy. Tôi đã luôn luôn giả định nó chỉ đơn giản là một wrapper đối tượng để bạn có thể đẩy nguyên thủy vào bộ sưu tập. Điều đó nói rằng, ngay cả khi biểu diễn bit của giá trị cơ bản giống hệt với giá trị nguyên thủy (mà tôi giả định là trường hợp), phương thức "equals" không bị ràng buộc dưới bất kỳ hình thức hoặc biểu mẫu nào để sử dụng toán tử == để xác định sự bình đẳng. Đó là loại điểm của nó. – Curds

+0

Đại diện cũng khác với kiểu gốc, nhưng đặc tả Java lang nói rằng toán tử (><...) không sử dụng bit so sánh bit. – sibnick