2010-10-16 32 views
18

xem xét ảnh chụp sau mã javaHành vi của sự thay đổi unsigned đúng áp dụng cho byte biến

byte b=(byte) 0xf1; 
byte c=(byte)(b>>4); 
byte d=(byte) (b>>>4); 

đầu ra:

c=0xff 
d=0xff 

đầu ra mong đợi:

c=0x0f 

như thế nào? dưới dạng b trong số nhị phân 1111 0001 sau khi dịch chuyển phải không được ký 0000 1111 do đó 0x0f nhưng tại sao lại là 0xff như thế nào?

+3

Có lẽ byte là dấu hiệu đầu tiên được mở rộng thành int – CodesInChaos

Trả lời

32

Vấn đề là tất cả các đối số đầu tiên được thăng int trước khi phẫu thuật thay đổi diễn ra:

byte b = (byte) 0xf1; 

b được ký kết, vì vậy giá trị của nó là -15.

byte c = (byte) (b >> 4); 

b là lần đầu tiên đăng nhập mở rộng đến các số nguyên -15 = 0xfffffff1, sau đó chuyển quyền 0xffffffff và cắt ngắn để 0xff bởi các diễn viên để byte.

byte d = (byte) (b >>> 4); 

b là lần đầu tiên đăng nhập mở rộng đến các số nguyên -15 = 0xfffffff1, sau đó chuyển quyền 0x0fffffff và cắt ngắn để 0xff bởi các diễn viên để byte.

Bạn có thể làm (b & 0xff) >>> 4 để nhận được hiệu ứng mong muốn.

+12

Ôi Chúa Java bị hỏng - ai là thằng khốn nói rằng số học không dấu là quá phức tạp đối với các lập trình viên hiểu? –

+1

@PP Sự vắng mặt của các số không dấu trong Java không phải là một vấn đề (ngoại trừ phân chia số nguyên và cuối cùng sẽ được sửa trong JDK 8): http://stackoverflow.com/questions/397867/port-of-random-generator -from-c-to-java/397997 # 397997 – starblue

3

Tôi đoán rằng b là dấu hiệu được mở rộng đến int trước khi chuyển.

Vì vậy, đây có thể làm việc như mong đợi:

(byte)((0x000000FF & b)>>4) 
1

Theo Bitwise and Bit Shift Operators:

Các unsigned dịch phải ">>>" chuyển một số không vào vị trí tận cùng bên trái, trong khi vị trí tận cùng bên trái sau ">>" phụ thuộc vào phần mở rộng dấu.

Vì vậy, với b >> 4 bạn chuyển đổi 1111 0001-1111 1111 (b là số âm, vì vậy nó gắn 1) là 0xff.

0

Java cố gắng tiết kiệm tiền khi có hỗ trợ rõ ràng cho các loại cơ bản chưa được ký bằng cách xác định hai toán tử thay đổi khác nhau thay thế.

Câu hỏi thảo luận về thay đổi quyền chưa ký, nhưng các ví dụ thực hiện cả hai (đã ký và chưa ký) và hiển thị giá trị của ca đã ký (>>).

Tính toán của bạn sẽ phù hợp với ca không dấu (>>>).

Các vấn đề liên quan