2009-12-10 33 views
9

Câu hỏi này KHÔNG phải là bản sao của this question.Tại sao tôi nhận được kết quả lạ khi chuyển bit bằng một giá trị âm?

Tôi tình cờ thấy một tình huống mà tôi có thể phải chuyển sang trái (số dương) bằng giá trị âm, tức là, 8 < < -1. Trong trường hợp đó, tôi mong đợi kết quả là 4, nhưng tôi chưa từng làm điều này trước đây. Vì vậy, tôi tạo thành một chương trình thử nghiệm nhỏ để xác minh giả thuyết của tôi:

for (int i = -8; i <= 4; i++) 
    Console.WriteLine("i = {0}, 8 << {0} = {1}", i, 8 << i);

để sốc và ngạc nhiên của tôi đã cho tôi kết quả như sau:

i = -8, 8 << -8 = 134217728 
i = -7, 8 << -7 = 268435456 
i = -6, 8 << -6 = 536870912 
i = -5, 8 << -5 = 1073741824 
i = -4, 8 << -4 = -2147483648 
i = -3, 8 << -3 = 0 
i = -2, 8 << -2 = 0 
i = -1, 8 << -1 = 0 
i = 0, 8 << 0 = 8 
i = 1, 8 << 1 = 16 
i = 2, 8 << 2 = 32 
i = 3, 8 << 3 = 64 
i = 4, 8 << 4 = 128

bất cứ ai có thể giải thích hành vi này?

Đây là một phần thưởng nhỏ. Tôi đã thay đổi chuyển dịch sang trái sang phải dịch chuyển và nhận được kết quả này:

i = -8, 8 >> -8 = 0 
i = -7, 8 >> -7 = 0 
i = -6, 8 >> -6 = 0 
i = -5, 8 >> -5 = 0 
i = -4, 8 >> -4 = 0 
i = -3, 8 >> -3 = 0 
i = -2, 8 >> -2 = 0 
i = -1, 8 >> -1 = 0 
i = 0, 8 >> 0 = 8 
i = 1, 8 >> 1 = 4 
i = 2, 8 >> 2 = 2 
i = 3, 8 >> 3 = 1 
i = 4, 8 >> 4 = 0

Trả lời

12

Bạn không thể dịch chuyển theo giá trị âm. Bạn cũng không thể thay đổi theo số dương lớn.

Từ C# spec (http://msdn.microsoft.com/en-us/library/a1sway8w.aspx):

If first operand is an int or uint (32-bit quantity), 
the shift count is given by the low-order five bits of second operand. 

... 


The high-order bits of first operand are discarded and the low-order 
empty bits are zero-filled. Shift operations never cause overflows. 
8

Trong ngôn ngữ C như << -1 không dịch để >> 1. Thay vào đó, ít nhất 5 bit của ca làm việc được thực hiện và phần còn lại bị bỏ qua, do đó, trong trường hợp này, phần bổ sung của hai là -1 chuyển thành << 31.

Bạn sẽ nhận được kết quả tương tự từ ví dụ. JavaScript javascript:alert(8<<-8).

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