Mengapa operator bitwise memiliki prioritas lebih rendah daripada perbandingan?

63

Bisakah seseorang menjelaskan alasannya, mengapa dalam banyak bahasa paling populer (lihat catatan di bawah) operator perbandingan (==,! =, <,>, <=,> =) Memiliki prioritas lebih tinggi daripada operator bitwise (&, |, ^ , ~)?

Saya tidak berpikir saya pernah menemukan penggunaan di mana prioritas ini akan alami. Itu selalu seperti:

  if( (x & MASK) == CORRECT ) ...   // Chosen bits are in correct setting, rest unimportant

  if( (x ^ x_prev) == SET )      // only, and exactly SET bit changed

  if( (x & REQUIRED) < REQUIRED )   // Not all conditions satisfied

Kasing tempat saya menggunakan:

  flags = ( x == 6 | 2 );     // set bit 0 when x is 6, bit 1 always.

hampir tidak ada.

Apa motivasi perancang bahasa untuk memutuskan diutamakan operator seperti itu?


Sebagai contoh, semua kecuali SQL pada 12 bahasa teratas adalah seperti itu pada daftar Bahasa Pemrograman Popularitas di langpop.com: C, Java, C ++, PHP, JavaScript, Python, C #, Perl, SQL, Ruby, Shell, Visual Basic.

SF.
sumber
16
kesalahan dalam desain asli kembali di C
ratchet freak
7
@gnat, apa gunanya keluhan itu? OP tidak mengatakan "semua", hanya "sekelompok bahasa paling populer". Dan sebagian besar mengikuti perintah ini. Dalam tabel ini, hanya satu dari 12 teratas (SQL) yang tidak: langpop.com
3
@ dan1111 intinya adalah, secara alami, untuk membantu penjawab lebih memahami pertanyaan yang diajukan dan memberikan jawaban yang lebih baik. Anda lihat, ini bukan tempat untuk The Guessing Game - atau, seperti yang dikatakan halaman tur , "Ini bukan forum diskusi. Tidak ada obrolan."
Agak
7
@gnat, saya setuju dengan kekhawatiran Anda tentang permainan tebak-tebakan, tapi saya rasa ini tidak memenuhi syarat ketika hampir setiap bahasa populer menunjukkan perilaku yang dijelaskan.
5
@Dunk: Pendekatan "by hunch" yang umum adalah [arithmetics] [logic operator] [arithmetics]. Kebanyakan pemrogram tidak membuat kekacauan tanda kurung seperti if(((x+getLowX()) < getMinX) || ((x-getHighX())>getMaxX())))- kebanyakan akan menganggap diutamakan aritmatika daripada logika dan menulis if( ( x + getLowX() < getMinX ) || ( x - getHighX() > getMaxX() )) dengan asumsi diutamakan di +atas <. Sekarang secara intuitif if( x ^ getMask() != PATTERN ) harus berperilaku sama, XOR menjadi operator aritmatika. Fakta itu ditafsirkan sebagai if( x ^ ( getMask() != PATTERN ) )sepenuhnya kontra-intuitif.
SF.

Jawaban:

72

Bahasa telah menyalin itu dari C, dan untuk C, Dennis Ritchie menjelaskan bahwa pada awalnya, dalam B (dan mungkin awal C), hanya ada satu bentuk &yang tergantung pada konteksnya apakah bitwise dan atau yang logis. Kemudian, setiap fungsi mendapatkan operatornya: &untuk bitwise dan &&untuk yang logis. Lalu dia melanjutkan

Pendahuluan mereka yang lambat menjelaskan kekurangtepatan aturan prioritas C. Di B satu menulis

if (a == b & c) ...

untuk memeriksa apakah asama dengan bdan ctidak nol; dalam ungkapan kondisional seperti itu, lebih baik &memiliki prioritas lebih rendah daripada ==. Dalam mengkonversi dari B ke C, seseorang ingin menggantinya &dengan &&pernyataan seperti itu; untuk membuat konversi kurang menyakitkan, kami memutuskan untuk menjaga prioritas &operator relatif sama ==, dan hanya memisahkan prioritas &&sedikit dari &. Hari ini, tampaknya akan lebih disukai untuk memindahkan prioritas relatif dari &dan ==, dan dengan demikian menyederhanakan idiom C yang umum: untuk menguji nilai bertopeng terhadap nilai lain, kita harus menulis

if ((a & mask) == b) ...

di mana tanda kurung bagian dalam diperlukan tetapi mudah dilupakan.

Pemrogram
sumber
1
Bukankah itu akan gagal jika c=2Atau a==bmenghasilkan ~0dan tidak 1?
SF.
Tampaknya, a == b menghasilkan 0 atau 1, lihat cm.bell-labs.com/cm/cs/who/dmr/kbman.html .
Pemrogram
Periksa referensi dalam jawaban dan baca teks sebelumnya.
SShaheen
1
@MasonWheeler: Terutama di embedded system, kadang-kadang perlu menggunakan macro seperti fungsi [dalam beberapa kasus, mereka dapat menawarkan order-of-magnitude kinerja yang lebih baik daripada fungsi in-line, dan di beberapa embedded system yang bisa kritis]. Deklarasi variabel dalam makro semacam itu tidak dimungkinkan; menggunakan variabel global dalam makro mungkin bekerja, tetapi tampaknya sangat menjengkelkan.
supercat
6
@MasonWheeler: Dapatkah Anda menemukan Raspberry Pi atau Arduino seharga $ 0,50 dalam jumlah 1000?
supercat
7

Operator bitwise terkait dengan operator logis baik secara konseptual maupun tampilan, yang mungkin menjelaskan mengapa mereka saling berdekatan dalam tabel prioritas. Mungkin seseorang bahkan dapat berargumen bahwa akan membingungkan untuk &menjadi lebih tinggi daripada ==, tetapi &&lebih rendah dari itu ==.

Setelah preseden preseden (!) Ditetapkan, mungkin lebih baik bagi bahasa lain untuk mengikutinya demi konsistensi.

Namun, saya cenderung setuju dengan Anda bahwa ini tidak optimal. Dalam penggunaan aktual, operator bit lebih seperti operator matematika daripada operator logis, dan akan lebih baik jika mereka dikelompokkan dengan operator matematika sebagai prioritas.


sumber