Algoritma adalah rangkaian keputusan: tambah satu elemen, geser bit, bandingkan dua nilai, kombinasikan kondisi. C++ menyediakan kumpulan operator yang kaya untuk mengekspresikan keputusan-keputusan tersebut secara ringkas. Pada Chapter ini kita akan mempelajari operator aritmetika, perbandingan, logika, bitwise, dan shift — khususnya bitwise dan shift yang sangat sering dipakai dalam algoritma optimasi bitmask, struktur fenwick tree, dan representasi himpunan.
Operator Aritmetika #
Operator aritmetika bekerja pada tipe numerik. Untuk dua operan bertipe int, pembagian selalu menghasilkan int dengan membuang pecahan — perilaku yang sering membingungkan pemula.
| Operator | Makna | Contoh | Hasil |
|---|---|---|---|
+ | Penjumlahan | 17 + 5 | 22 |
- | Pengurangan | 17 - 5 | 12 |
* | Perkalian | 17 * 5 | 85 |
/ | Pembagian | 17 / 5 | 3 |
% | Sisa bagi | 17 % 5 | 2 |
Mekanisme: Integer Division vs Floating-Point Division #
Ketika kedua operan bertipe integer, C++ melakukan integer division: hasil dibuang pecahannya, bukan dibulatkan. Sisa bagi ditangani terpisah oleh %. Operator % hanya berlaku untuk tipe integer, tidak untuk double.
Kode: Aritmetika Dasar #
#include <iostream>
int main() {
int a = 17, b = 5;
std::cout << "a + b = " << a + b << '\n';
std::cout << "a - b = " << a - b << '\n';
std::cout << "a * b = " << a * b << '\n';
std::cout << "a / b = " << a / b << '\n'; // integer division
std::cout << "a % b = " << a % b << '\n'; // sisa bagi
return 0;
}Output yang Dihasilkan:
a + b = 22
a - b = 12
a * b = 85
a / b = 3
a % b = 2- Baris
a / b: karenaadanbbertipeint, hasil17/5dipotong menjadi3tanpa pembulatan. - Baris
a % b: menghasilkan sisa2karena5 * 3 + 2 = 17.
Operator Bitwise dan Shift #
Operator bitwise memanipulasi nilai pada level bit. Banyak algoritma DSA memakainya: bitmask DP, pengecekan subset himpunan, dan operasi ringan pada fenwick tree atau segment tree. Operator shift (<<, >>) sangat berguna untuk mengalikan atau membagi dengan pangkat dua secara efisien.
| Operator | Makna | Contoh (x=0b1100, y=0b1010) | Hasil |
|---|---|---|---|
& | AND bitwise | x & y | 0b1000 = 8 |
| | OR bitwise | x | y | 0b1110 = 14 |
^ | XOR bitwise | x ^ y | 0b0110 = 6 |
~ | NOT (invert) | ~x | komplemen |
<< | Shift kiri | x << 2 | 0b110000 = 48 |
>> | Shift kanan | x >> 1 | 0b0110 = 6 |
Mekanisme: Shift sebagai Pangkat Dua #
x << n setara dengan x * 2^n untuk unsigned integer, dan x >> n setara dengan x / 2^n (pembagian bulat). Operasi shift lebih cepat daripada perkalian/pembagian biasa karena langsung berjalan pada register CPU.
Kode: Bitwise dan Shift #
#include <iostream>
int main() {
unsigned int x = 0b1100; // 12
unsigned int y = 0b1010; // 10
std::cout << "x & y = " << (x & y) << '\n';
std::cout << "x | y = " << (x | y) << '\n';
std::cout << "x ^ y = " << (x ^ y) << '\n';
std::cout << "x << 2 = " << (x << 2) << '\n';
std::cout << "x >> 1 = " << (x >> 1) << '\n';
return 0;
}Output yang Dihasilkan:
x & y = 8
x | y = 14
x ^ y = 6
x << 2 = 48
x >> 1 = 6- Baris
x & y: AND bitwise — bit hasil1hanya bila kedua operan1. - Baris
x ^ y: XOR — bit hasil1bila kedua operan berbeda. - Baris
x << 2: shift kiri 2 posisi = kalikan dengan 4 =12 * 4 = 48. - Baris
x >> 1: shift kanan 1 posisi = bagi 2 =12 / 2 = 6.
Pola Bitmask untuk DSA #
Empat operasi dasar pada bitmask sering muncul di soal himpunan atau dynamic programming dengan state bitmask: cek bit, nyalakan bit, matikan bit, dan balik bit.
Kode: Operasi Bitmask #
#include <iostream>
#include <bitset>
int main() {
unsigned int mask = 0b0100; // bit ke-2
unsigned int n = 0b1011; // bit aktif: 0, 1, 3
std::cout << "mask = " << std::bitset<8>(mask) << '\n';
std::cout << "n = " << std::bitset<8>(n) << '\n';
bool on = (n & mask) != 0; // cek bit ke-2
std::cout << "bit ke-2? = " << std::boolalpha << on << '\n';
unsigned int set = n | mask; // nyalakan bit ke-2
std::cout << "set = " << std::bitset<8>(set) << '\n';
unsigned int clear = set & ~mask; // matikan bit ke-2 di 'set'
std::cout << "clear = " << std::bitset<8>(clear) << '\n';
unsigned int toggle = n ^ mask; // balik bit ke-2
std::cout << "toggle = " << std::bitset<8>(toggle) << '\n';
int popcount = __builtin_popcount(n); // jumlah bit 1
std::cout << "popcount = " << popcount << '\n';
return 0;
}Output yang Dihasilkan:
mask = 00000100
n = 00001011
bit ke-2? = false
set = 00001111
clear = 00001011
toggle = 00001111
popcount = 3- Baris
bool on = (n & mask) != 0;:n & maskakan0bila bit ke-2 tidak aktif; kita bandingkan dengan0agar hasilnyabool. Tanpa pembanding, hasil integer0/non-nol bisa salah ditafsirkan. - Baris
n | mask: OR bitwise menyalakan bit yang1dimasktanpa mengubah bit lain. - Baris
set & ~mask: NOT~maskmembalik semua bit, lalu AND mematikan bit ke-2. - Baris
n ^ mask: XOR membalik bit ke-2. Bila awalnya0, jadi1; bila awalnya1, jadi0. - Baris
__builtin_popcount(n): bawaan GCC/Clang yang menghitung jumlah bit1(popcount). Standar C++20 menyediakanstd::popcountdi header<bit>.
Operator Perbandingan, Logika, dan Ternary #
Operator perbandingan menghasilkan bool. Operator logika mengkombinasikan bool dengan short-circuit: bila operan kiri sudah menentukan hasil, operan kanan tidak dievaluasi.
| Operator | Makna | Short-circuit |
|---|---|---|
&& | AND logika | Berhenti bila kiri false |
|| | OR logika | Berhenti bila kiri true |
! | NOT | Membalik bool |
Kode: Perbandingan, Logika, dan Augmented Assignment #
#include <iostream>
int main() {
bool aktif = true;
int nilai = 75;
bool lulus = aktif && (nilai >= 70); // true && true
std::cout << "lulus = " << std::boolalpha << lulus << '\n';
int total = 100;
total += 50; // total = 150
total <<= 1; // total = 300 (shift kiri = kali 2)
std::cout << "total = " << total << '\n';
int a = 17, b = 5;
int maks = (a > b) ? a : b; // ternary
std::cout << "maks = " << maks << '\n';
return 0;
}Output yang Dihasilkan:
lulus = true
total = 300
maks = 17- Baris
aktif && (nilai >= 70): jikaaktifadalahfalse, ekspresi(nilai >= 70)tidak dievaluasi sama sekali. Perilaku ini bermanfaat saat operan kanan memanggil fungsi yang berat atau mengakses pointer yang mungkin null. - Baris
total <<= 1: augmented assignment gabungan dengan shift — ekuivalen dengantotal = total << 1yaitu menggandakan nilai. - Baris
(a > b) ? a : b: ternary operator mengembalikanabila kondisi benar,bbila salah. Sering dipakai untuk memilih nilai tanpa blokif/elsepenuh.
Precedence dan Associativity #
Precedence menentukan urutan evaluasi saat beberapa operator muncul dalam satu ekspresi tanpa tanda kurung. Tabel berikut menampilkan beberapa precedence yang paling sering keliru.
| Precedence | Operator | Asosiativitas |
|---|---|---|
| Tinggi | :: (scope) | — |
++ -- ! ~ (unary) | kanan-ke-kiri | |
* / % | kiri-ke-kanan | |
+ - | kiri-ke-kanan | |
<< >> | kiri-ke-kanan | |
< <= > >= | kiri-ke-kanan | |
== != | kiri-ke-kanan | |
& | kiri-ke-kanan | |
^ | kiri-ke-kanan | |
| | kiri-ke-kanan | |
&& | kiri-ke-kanan | |
|| | kiri-ke-kanan | |
| Rendah | ?: = += <<= | kanan-ke-kiri |
Ringkasan #
- Operator aritmetika pada
intmelakukan integer division; gunakan cast bila butuh pecahan. - Bitwise dan shift adalah pondasi algoritma bitmask; kuasai empat pola: cek, set, clear, toggle.
&&dan||mengevaluasi short-circuit — manfaatkan untuk pengecekan pointer null sebelum akses.- Tanda kurung selalu lebih murah daripada debugging precedence; pakailah saat ragu.