2010-02-22 25 views
14

Đây là thiết kế ngôn ngữ nhiều hơn là một câu hỏi lập trình.Lý do ngôn ngữ cấp cao như mặt nạ C#/Java toán hạng bit shift là gì?

Sau đây là một đoạn trích từ JLS 15.19 Shift Operators:

Nếu kiểu thúc đẩy của toán hạng bên trái là int, chỉ có năm bit bậc thấp nhất của toán hạng bên phải được sử dụng như là khoảng cách dịch chuyển .

Nếu loại được thăng hạng của toán hạng bên trái là long, thì chỉ sáu bit bậc thấp nhất của toán hạng bên phải được sử dụng làm khoảng cách dịch chuyển.

Hành vi này cũng là specified in C# và mặc dù tôi không chắc liệu nó có trong thông số chính thức cho Javascript (nếu có), điều này cũng đúng dựa trên thử nghiệm của riêng tôi ít nhất.

Hậu quả là sau đây là đúng:

(1 << 32) == 1 

Tôi hiểu rằng đặc điểm kỹ thuật này có lẽ là "soi" bởi thực tế là phần cứng cơ bản chỉ mất 5 bit cho các toán hạng số khi chuyển 32-bit các giá trị (và 6 bit cho 64-bit), và tôi có thể hiểu hành vi đó được chỉ định ở cấp JVM chẳng hạn, nhưng tại sao các ngôn ngữ cấp cao như C# và Java giữ lại hành vi ở mức độ thấp này? Không nên họ cung cấp một cái nhìn trừu tượng hơn ngoài việc thực hiện phần cứng và hành xử trực quan hơn? (Thậm chí tốt hơn nếu họ có thể tính số âm có nghĩa là dịch chuyển theo hướng KHÁC!)

Trả lời

8

Java và C# không hoàn toàn là "cấp cao". Họ cố gắng thực sự khó để được như vậy mà họ có thể được biên dịch thành mã hiệu quả, để tỏa sáng trong tiêu chuẩn vi mô. Đây là lý do tại sao chúng có "loại giá trị" như int thay vì có, như kiểu số nguyên mặc định, số nguyên thực, là các đối tượng ở bên phải của riêng chúng và không giới hạn trong phạm vi cố định.

Do đó, chúng bắt chước phần cứng. Họ cắt nó một chút, trong đó họ ủy quyền mặt nạ, trong khi C chỉ cho phép nó. Tuy nhiên, Java và C# là các ngôn ngữ "mức trung bình".

+0

Việc xác định liệu một ngôn ngữ có cao cấp hay không là rất chủ quan, tôi hiểu. Tuy nhiên, tôi nghĩ rằng hầu hết mọi người sẽ phân loại Java và C# thành "cao", ít nhất là đối với các ngôn ngữ không viết kịch bản. – polygenelubricants

+0

Tuyệt đối. Nhưng Java và C# vẫn giữ lại các đặc tính ở mức độ thấp, vì lợi ích của hiệu quả (hoặc ít nhất là hiệu suất _perceived_). Loại 'int' 32 bit và mặt nạ đếm số thay đổi là những đặc tính như vậy. Các ngôn ngữ khác, chẳng hạn như Đề án, là "cấp cao hơn" trong vấn đề đó. –

+0

http://therighttool.hammerprinciple.com/statements/this-is-a-high-level-language – starblue

5

Vì trong hầu hết các môi trường lập trình, một số nguyên chỉ là 32 bit. Vì vậy, sau đó 5 bit (đủ để thể hiện 32 giá trị) đã đủ để thay đổi toàn bộ số nguyên. Một lý do tương tự tồn tại cho một 64bit dài: 6 bit là tất cả những gì bạn cần để thay đổi hoàn toàn toàn bộ giá trị.

Tôi có thể hiểu một phần của sự nhầm lẫn: nếu toán hạng bên phải của bạn là kết quả của phép tính kết thúc với giá trị lớn hơn 32, bạn có thể mong đợi nó thay đổi tất cả các bit thay vì áp dụng mặt nạ.

+0

Tôi hiểu lý do tại sao việc chuyển đổi giá trị 32 bit chỉ cần tối đa 5 bit và bất kỳ thứ gì ngoài cơ bản xóa toàn bộ thanh ghi - và là người dùng ngôn ngữ, đôi khi đó chính là điều tôi muốn! Như tôi đã nói, câu hỏi không phải là lý do tại sao các tham số được chọn như vậy, mà là lý do tại sao một cái gì đó quá thấp được giữ lại ở ngôn ngữ cấp cao. – polygenelubricants

+0

'nếu toán hạng bên phải của bạn là kết quả của phép tính kết thúc bằng một giá trị lớn hơn 32' ... 5 bit có thể lưu trữ giá trị 0 ~ 31, do đó không thể thay đổi 32 bit, cũng như không thực hiện vì vậy có ích, như là một 'xor reg, reg' đơn giản sẽ đạt được hiệu quả tương tự. –

5

C# và Java xác định dịch chuyển khi chỉ sử dụng các bit có thứ tự thấp của số lần dịch chuyển vì đó là những gì cả lệnh chuyển hướng sparc và x86 đều thực hiện. Java ban đầu được thực hiện bởi Sun trên bộ xử lý sparc, và C# của Microsoft trên x86.

Ngược lại, C/C++ để không xác định hành vi của lệnh thay đổi nếu số lượng thay đổi không nằm trong khoảng 0..31 (đối với int 32 bit), cho phép bất kỳ hành vi nào. Đó là bởi vì khi C lần đầu tiên được triển khai, các phần mềm xử lý khác nhau xử lý các cách khác nhau. Ví dụ, trên một VAX, dịch chuyển bởi một số âm sẽ chuyển sang hướng khác. Vì vậy, với C, trình biên dịch chỉ có thể sử dụng hướng dẫn thay đổi phần cứng và làm bất cứ điều gì nó làm.

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