2013-09-27 180 views
9

Tôi tìm thấy mã này để tìm các bản sao trong SO đăng ở đây. nhưng tôi không hiểu những gì dòng này có nghĩa int mid = (low + high) >>> 1;">>>" có nghĩa là gì trong java?

private static int findDuplicate(int[] array) { 
     int low = 0; 
     int high = array.length - 1; 

     while (low <= high) { 
      int mid = (low + high) >>> 1; 
      System.out.println(mid); 
      int midVal = array[mid]; 

      if (midVal == mid) 
       low = mid + 1; 
      else 
       high = mid - 1; 
     } 
     return high; 
    } 
+2

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html – iamnotmaynard

Trả lời

33

Nhà điều hành >>>unsigned right bit-shift operator in Java. Nó phân chia hiệu quả toán hạng theo số 2 thành lũy thừa của toán hạng bên phải, hoặc chỉ 2 tại đây.

Sự khác biệt giữa >>>>> sẽ chỉ hiển thị khi chuyển số âm. Nhà điều hành >> thay đổi một bit 1 thành bit quan trọng nhất nếu nó là 1 và các ca >>> thay đổi trong một 0 bất kể.

UPDATE:

Hãy trung bình 12147483647 (Integer.MAX_VALUE). Chúng ta có thể làm toán dễ dàng:

(1 + 2147483647)/2 = 2147483648/2 = 1073741824 

Bây giờ, với mã (low + high)/2, đây là các bit tham gia:

  1: 00000000 00000000 00000000 00000001 
+2147483647: 01111111 11111111 11111111 11111111 
================================================ 
-2147483648: 10000000 00000000 00000000 00000000 // Overflow 
/2 
================================================ 
-1073741824: 11000000 00000000 00000000 00000000 // Signed divide, same as >> 1. 

Hãy làm cho "sự thay đổi" để >>>:

  1: 00000000 00000000 00000000 00000001 
+2147483647: 01111111 11111111 11111111 11111111 
================================================ 
-2147483648: 10000000 00000000 00000000 00000000 // Overflow 
>>> 1 
================================================ 
+1073741824: 01000000 00000000 00000000 00000000 // Unsigned shift right. 
+1

@can bạn minh họa bằng ví dụ. điều đó sẽ rất hữu ích – eagertoLearn

+1

Cảm ơn bạn đã minh họa tuyệt vời.nhưng trong trường hợp này là '(thấp + cao)/2' và' thấp + cao >>> 1', chúng tương đương như thế nào? – eagertoLearn

+1

Trong Java, chúng không tương đương trong trường hợp tràn, như tôi đã minh họa. – rgettman

17

Ý nghĩa của

int mid = (low + high) >>> 1; 

; bằng cách sử dụng thay đổi chưa được ký, nó sẽ tránh các luồng tràn dẫn đến số âm. Điều này là cần thiết vì Java không hỗ trợ các giá trị unsigned int. (BTW char là unsigned)

Cách truyền thống để viết những dòng này là

int mid = (low + high)/2; // don't do this 

tuy nhiên điều này có thể tràn cho các khoản tiền lớn hơn và bạn sẽ có được một số âm cho vào giữa.

ví dụ:

int high = 2100000000; 
int low = 2000000000; 
System.out.println("mid using >>> 1 = " + ((low + high) >>> 1)); 
System.out.println("mid using/2 = " + ((low + high)/2)); 

in

mid using >>> 1 = 2050000000 
mid using/2 = -97483648 

rõ kết quả thứ hai là không chính xác.

+1

+1; rất quan sát (và thích hợp) để chỉ ra unsigned-ness của char. – Bathsheba

+0

@peter: nếu tôi đang triển khai tìm kiếm nhị phân, thì tôi cần '(mid = low + high)/2', cách nào có thể tránh được ?. – eagertoLearn

+0

@peter: bạn có thể đưa ra ví dụ để cho thấy tầm quan trọng của '>>>', vui lòng – eagertoLearn

0

toán tử bitwise của nó .. Nó hoạt động trên giá trị bit. Giả sử nếu A giữ 60 thì A >>> 2 sẽ cho 15 (bit giá trị 0000 1111)

Tên thực của nó là "Shift Zero right Operator" ở đây giá trị toán hạng bên trái được di chuyển ngay bằng số bit được chỉ định (2 trong trường hợp này) bởi toán hạng bên phải và các giá trị dịch chuyển được lấp đầy bằng số không (0000).