Sebuah baris seperti -3^2 + 10 - 3 - 2 mengandung lima keputusan evaluasi yang tak terlihat: mana yang dihitung duluan? Salah memprediksi urutan tersebut menghasilkan nilai yang salah tanpa satu pun pesan galat. MATLAB menyelesaikan kekacauan ini dengan tabel precedence (urutan kekuatan operator) dan aturan associativity (arah evaluasi operator setara). Chapter ini membedah kedua aturan tersebut, lalu melatih kita menulis ekspresi yang tidak lagi bergantung pada keberuntungan.

Tabel Precedence MATLAB #

Dokumentasi resmi MATLAB mengurutkan operator dari kekuatan tertinggi ke terendah. Saat dua operator bertemu dalam satu ekspresi, yang berada di level lebih tinggi dievaluasi lebih dulu:

LevelOperatorKeterangan
1( )kurung selalu menang
2.' .^ ' ^transpose dan pangkat
3+x -x ~xunary plus, unary minus, negasi
4.* ./ .\ * / \perkalian dan pembagian
5+ -penjumlahan dan pengurangan
6:operator kolon
7< <= > >= == ~=pembanding
8&AND elemen
9|OR elemen
10&&AND short-circuit
11||OR short-circuit
12=assignment (terlemah)

Dua fakta dari tabel ini sering mengejutkan pemula. Pertama, operator kolon 1:2:9 berada di bawah penjumlahan — jadi 1:2+1:9 berarti 1:3:9, bukan (1:2)+1:9. Kedua, seluruh operator pembanding berada di bawah aritmetika, sehingga 4 + 3 == 7 membandingkan hasil penjumlahan (7) dengan 7, bukan 4 + (3 == 7).

Associativity: Evaluasi Kiri ke Kanan #

Bila dua operator berada di level yang sama, MATLAB mengevaluasi dari kiri ke kanan — tanpa pengecualian, termasuk pangkat. Perilaku ini berbeda dari konvensi matematika yang mengaitkan pangkat dari kanan. Verifikasinya mudah:

matlab
fprintf('8 / 4 / 2   = %g\n', 8 / 4 / 2);
fprintf('8 / (4 / 2) = %g\n', 8 / (4 / 2));
fprintf('10 - 3 - 2  = %d\n', 10 - 3 - 2);

fprintf('2^3^2   = %d\n', 2^3^2);
fprintf('(2^3)^2 = %d\n', (2^3)^2);
fprintf('2^(3^2) = %d\n', 2^(3^2));

Output yang Dihasilkan:

text
8 / 4 / 2   = 1
8 / (4 / 2) = 4
10 - 3 - 2  = 5
2^3^2   = 64
(2^3)^2 = 64
2^(3^2) = 512

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (8 / 4 / 2): pembagian berjalan kiri ke kanan — (8/4)/2 = 1. Menulis 8/(4/2) menghasilkan 4; arah evaluasi mengubah hasil.
  2. Baris 3 (10 - 3 - 2): sama halnya, (10-3)-2 = 5. Tidak ada pengelompokan otomatis dari kanan.
  3. Baris 5 (2^3^2): pangkat juga dievaluasi kiri ke kanan, sehingga hasilnya (2^3)^2 = 64. Konvensi matematika 2^(3^2) = 512 tidak berlaku di MATLAB — satu jebakan paling klasik bagi yang datang dari buku matematika.

Interaksi Antar Level: Kasus Unary Minus dan Pangkat #

Kombinasi pangkat (level 2) dengan unary minus (level 3) memunculkan kasus terkenal -3^2. Karena pangkat lebih kuat, MATLAB menghitung 3^2 lebih dulu, lalu menegasikan hasilnya. Kurung mengubah segalanya:

matlab
fprintf('-3^2   = %d\n', -3^2);
fprintf('(-3)^2 = %d\n', (-3)^2);

fprintf('2 + 3 * 4   = %d\n', 2 + 3 * 4);
fprintf('(2 + 3) * 4 = %d\n', (2 + 3) * 4);

fprintf('4 + 3 == 7 : %d\n', 4 + 3 == 7);
fprintf('~0 & 1      : %d\n', ~0 & 1);
fprintf('1 | 0 & 0   = %d\n', 1 | 0 & 0);

Output yang Dihasilkan:

text
-3^2   = -9
(-3)^2 = 9
2 + 3 * 4   = 14
(2 + 3) * 4 = 20
4 + 3 == 7 : 1
~0 & 1      : 1
1 | 0 & 0   = 1

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (-3^2): dievaluasi -(3^2) = -9. Kita harus menulis (-3)^2 untuk menguadratkan bilangan negatif.
  2. Baris 4-5 (2 + 3 * 4): perkalian (level 4) mengalahkan penjumlahan (level 5); hasil 14. Kurung memaksa penjumlahan duluan, hasil 20.
  3. Baris 7 (4 + 3 == 7): penjumlahan selesai dulu menjadi 7, lalu 7 == 7 menghasilkan logical 1 — aritmetika mengikat lebih kuat daripada pembanding.
  4. Baris 8 (~0 & 1): negasi ~0 bernilai 1 (level 3), baru digabung dengan & (level 8) — hasil 1.
  5. Baris 9 (1 | 0 & 0): & menang atas |, sehingga ekspresi menjadi 1 | (0 & 0) = 1 | 0 = 1. Bila | dievaluasi duluan, (1|0) & 0 akan menghasilkan 0 — urutan ini benar-benar menentukan hasil.

Tabel precedence memungkinkan kita memprediksi hasil, tetapi memprediksi bukan berarti memudahkan pembaca. Kode produksi sebaiknya tidak menguji hafalan pembacanya. Tiga kebiasaan berikut menjaga ekspresi tetap jujur:

  • Kurung untuk niat, bukan hanya kebutuhan. (-3)^2 dan a | (b & c) masing-masing membutuhkan dan tidak membutuhkan kurung — keduanya tetap layak ditulis eksplisit.
  • Pecah ekspresi panjang. hasil = (a - b) / (c + d); dengan variabel antara sering lebih terbaca daripada satu baris berlapis.
  • Verifikasi dengan menguji. Saat ragu, bungkus ekspresi dalam fprintf('%d\n', ...) seperti contoh-contoh di atas dan biarkan MATLAB menjawab.

Berkas contoh.m pada bagian bawah halaman memverifikasi nilai setiap ekspresi yang dibahas — jalankan, bandingkan, dan biarkan angka memperkuat intuisi kita.

Ringkasan #

Precedence MATLAB memeringkat operator dari kurung (terkuat) hingga assignment (terlemah), dengan operator kolon di tengah dan pembanding di bawah aritmetika. Operator setara dievaluasi kiri ke kanan — termasuk pangkat, berbeda dari konvensi matematika — dengan satu pengecualian: & selalu mengalahkan |. Kurung eksplisit tetap alat terbaik untuk kode yang dimaksudkan terbaca oleh manusia, bukan hanya oleh interpreter.