2012-02-09 10 views
11

Tại sao các phép dịch chuyển trên int không dấu cho kết quả chưa được ký, nhưng thao tác trên toán hạng chưa ký kết quả dẫn đến int đã ký?Tại sao hoạt động dịch chuyển luôn dẫn đến int đã ký khi toán hạng là <32 bits

int signedInt = 1; 
int shiftedSignedInt = signedInt << 2; 

uint unsignedInt = 1; 
uint shiftedUnsignedInt = unsignedInt << 2;  //OK. unsigned result 

short signedShort = 1; 
int shiftedsignedShort = signedShort << 2; 

ushort unsignedShort = 1; 
uint shiftedUnsignedShort = unsignedShort << 2; //CS0266: Can't cast int to uint 

sbyte signedByte = 1; 
int shiftedSignedByte = signedByte << 2; 

byte unsignedByte = 1; 
uint shiftedUnsignedByte = unsignedByte << 2; //CS0266: Can't cast int to uint 
+0

Cũng thêm 'uint shiftedUnsignedByte = (uint) unsignedByte << 2U;' để có thông tin chi tiết hơn. –

Trả lời

11

Các shift operators được định nghĩa trước chỉ dành cho những trường hợp này (shift trái):

int operator <<(int x, int count); (1) 
uint operator <<(uint x, int count); (2) 
long operator <<(long x, int count); (3) 
ulong operator <<(ulong x, int count); (4) 

Khái niệm uint shiftedUnsignedShort = unsignedShort << 2 được hiểu như là (1) -st trường hợp (implicit up-casting from ushort to int(int)2), vì vậy nó thực hiện một cảnh báo về đúc bất hợp pháp (không có diễn viên tiềm ẩn từ kết quả int đến ushort).
Tình huống tương tự chúng ta có thể thấy cho uint shiftedUnsignedByte = unsignedByte << 2. Nó cũng được hiểu là (1) -st trường hợp (ẩn lên đúc từ byte đến int và (int)2, nhưng không có diễn viên tiềm ẩn của giá trị kết quả để uint).

Bạn có thể giải quyết những vấn đề này bằng cách sử dụng phương pháp sau đây:

uint shiftedUnsignedShort = (uint)unsignedShort << 2 //force use the (2)-nd shift operator case 
uint shiftedUnsignedByte = (uint)unsignedByte << 2; //force use the (2)-nd shift operator case 
0

Theo Wikipedia<<>> đại diện cho hai nhà khai thác khác nhau. Một thay đổi hợp lý vor ulong và uint và một sự thay đổi số học cho int và dài.

Bây giờ tôi đoán (!) Là, rằng "không xác định" ushort hoặc ubyte có được đúc thành một int thay vì một uint.

Xin lỗi, nhưng đó là tất cả những gì tôi có thể cung cấp.

3

Trong Shift operators bài viết MSDN có một đề cập rằng các nhà khai thác dịch chuyển được xác định trước chỉ tồn tại cho int, uint, dài, loại ulong. Đối với tất cả các loại khác, chúng bị quá tải. Đối với tất cả các thao tác dịch, toán hạng thứ hai phải luôn là loại int. Do đó bất kỳ loại ngắn nào cũng luôn được đúc thành int trước khi thực hiện thao tác dịch chuyển.