Hampir setiap program perlu menghitung sesuatu: total harga belanja, sisa stok, diskon, atau konversi satuan. Operator aritmatika adalah alat PHP untuk mengolah angka, dan PHP menyediakan enam operator dasar plus beberapa fungsi pendukung seperti intdiv(). Pada chapter ini kita akan membedah perilaku setiap operator, termasuk jebakan pembagian nol dan tanda hasil modulo yang sering mengejutkan pemula.

Daftar Operator Aritmatika #

Tabel berikut merangkum enam operator aritmatika PHP. Kolom “Contoh” memakai nilai $a = 7 dan $b = 2.

OperatorNamaContohHasil
+Penjumlahan$a + $b9
-Pengurangan$a - $b5
*Perkalian$a * $b14
/Pembagian$a / $b3.5
%Modulo (sisa bagi)$a % $b1
**Pangkat$a ** $b49

Mari kita lihat keenam operator tersebut bekerja dalam satu program:

php
<?php
$a = 7;
$b = 2;

echo "Penjumlahan: $a + $b = " . ($a + $b) . "\n";
echo "Pengurangan: $a - $b = " . ($a - $b) . "\n";
echo "Perkalian  : $a * $b = " . ($a * $b) . "\n";
echo "Pembagian  : $a / $b = " . ($a / $b) . "\n";
echo "Modulo     : $a % $b = " . ($a % $b) . "\n";
echo "Pangkat    : $a ** $b = " . ($a ** $b) . "\n";

Output yang Dihasilkan:

text
Penjumlahan: 7 + 2 = 9
Pengurangan: 7 - 2 = 5
Perkalian  : 7 * 2 = 14
Pembagian  : 7 / 2 = 3.5
Modulo     : 7 % 2 = 1
Pangkat    : 7 ** 2 = 49

Setiap baris menghitung satu ekspresi aritmatika lalu menggabungkan hasilnya ke dalam string menggunakan operator titik (.) yang akan kita bahas tuntas pada chapter Operator String . Perhatikan bahwa tanda kurung di sekitar ekspresi seperti ($a + $b) wajib ada agar perhitungan angka selesai lebih dahulu sebelum digabungkan dengan teks.

Pembagian, Modulo, dan Pembagian Bulat #

Pembagian PHP punya satu perilaku khusus yang membedakannya dari bahasa seperti C atau Java: operator / mengembalikan integer hanya jika kedua operan adalah integer dan pembagian tersebut habis dibagi. Jika ada sisa, hasil otomatis menjadi float. Perhatikan perbedaannya:

php
<?php
var_dump(10 / 2);   // habis dibagi -> tetap integer
var_dump(7 / 2);    // ada sisa -> menjadi float
var_dump(10 / 4);   // ada sisa -> menjadi float

Output yang Dihasilkan:

text
int(5)
float(3.5)
float(2.5)

Untuk pembagian yang memotong bagian desimalnya (pembulatan menuju nol), PHP menyediakan fungsi intdiv(). Modulo % mengembalikan sisa bagi dan hanya bekerja pada integer. Keduanya saling melengkapi dan memenuhi hubungan matematis: $a sama dengan intdiv($a, $b) * $b + $a % $b.

php
<?php
$a = 17;
$b = 5;

$hasilBagi = intdiv($a, $b); // 17 dibagi 5 = 3 (dibuang sisanya)
$sisa = $a % $b;             // sisa 2

var_dump($hasilBagi, $sisa);
var_dump($hasilBagi * $b + $sisa === $a); // bukti hubungan keduanya
var_dump(intdiv(-17, 5), -17 % 5);        // pembulatan menuju nol

Output yang Dihasilkan:

text
int(3)
int(2)
bool(true)
int(-3)
int(-2)

Fungsi intdiv(-17, 5) menghasilkan -3 karena pembulatan dilakukan menuju nol, bukan menuju negatif tak hingga (-3.4 dipotong menjadi -3). Hasil modulo selalu mengikuti tanda operan di sebelah kiri (dividen), bukan tanda pembagi. Perhatikan tabel kecil berikut:

EkspresiHasilPenjelasan
-5 % 3-2Tanda mengikuti dividen (negatif)
5 % -32Tanda mengikuti dividen (positif)
-5 % -3-2Tanda mengikuti dividen (negatif)

Terakhir, operator % hanya menerima integer. Operan float akan dikonversi secara implisit menjadi integer dan memicu pesan Deprecated: Implicit conversion from float ... loses precision pada PHP 8. Untuk sisa bagi bilangan desimal, gunakan fungsi fmod():

php
<?php
var_dump(fmod(10.5, 3)); // 10.5 = 3*3 + 1.5

Output yang Dihasilkan:

text
float(1.5)

Operator Pangkat #

Operator ** diperkenalkan pada PHP 5.6 dan mengikuti aturan associativity kanan: ketika beberapa pangkat dirangkai, evaluasi dilakukan dari kanan ke kiri. Ekspresi 2 ** 3 ** 2 berarti 2 ** (3 ** 2), yaitu 2 ** 9 = 512, bukan (2 ** 3) ** 2 = 64. Pangkat negatif juga sah dan menghasilkan float:

php
<?php
var_dump(2 ** 10);
var_dump(2 ** 3 ** 2); // kanan ke kiri: 2 ** (3 ** 2)
var_dump(2 ** -2);     // 1/(2*2) = 0.25
var_dump(-2 ** 2);     // ** lebih kuat dari tanda minus: -(2**2)
var_dump((-2) ** 2);   // kurung memaksa -2 dijadikan basis

Output yang Dihasilkan:

text
int(1024)
int(512)
float(0.25)
int(-4)
int(4)

Baris var_dump(-2 ** 2); sering menjadi jebakan: hasilnya -4 karena operator pangkat mengevaluasi 2 ** 2 terlebih dahulu, lalu tanda minus diterapkan pada hasilnya. Tulis (-2) ** 2 jika yang Anda maksud adalah basis negatif.

Pembagian dengan Nol #

PHP 8 mengubah pembagian nol dari warning menjadi error yang bisa ditangkap. Ada tiga operasi yang melempar DivisionByZeroError: operator / dengan pembagi nol (termasuk float 0.0), operator % dengan pembagi nol, dan fungsi intdiv() dengan pembagi nol. Ketiganya adalah Throwable, sehingga bisa ditangani dengan try/catch:

php
<?php
$pembagi = 0;

try {
    echo "5 / $pembagi = " . (5 / $pembagi) . "\n";
} catch (DivisionByZeroError $e) {
    echo "5 / $pembagi gagal: " . $e->getMessage() . "\n";
}

try {
    echo "5 % $pembagi = " . (5 % $pembagi) . "\n";
} catch (DivisionByZeroError $e) {
    echo "5 % $pembagi gagal: " . $e->getMessage() . "\n";
}

try {
    echo "intdiv(5, $pembagi) = " . intdiv(5, $pembagi) . "\n";
} catch (DivisionByZeroError $e) {
    echo "intdiv(5, $pembagi) gagal: " . $e->getMessage() . "\n";
}

Output yang Dihasilkan:

text
5 / 0 gagal: Division by zero
5 % 0 gagal: Modulo by zero
intdiv(5, 0) gagal: Division by zero

Setiap blok try mencoba satu operasi berbahaya; kata kunci catch menangkap DivisionByZeroError yang dilempar PHP sebelum program berhenti, lalu mencetak pesan errornya sehingga program tetap berjalan sampai selesai. Perhatikan bahwa pesannya berbeda-beda: operator / dan intdiv() melempar pesan Division by zero, sedangkan operator % melempar Modulo by zero. Pembagian float seperti 5.0 / 0.0 juga melempar DivisionByZeroError yang sama. Materi penanganan error secara mendalam akan kita pelajari pada Section Error Handling.

Jika Anda benar-benar membutuhkan pembagian float yang menghasilkan tak hingga alih-alih error, gunakan fungsi fdiv(): fdiv(5, 0) mengembalikan INF dan fdiv(-5, 0) mengembalikan -INF. Fungsi ini berguna di perhitungan matematis yang memang mengizinkan nilai tak hingga.

Urutan Evaluasi (Sekilas) #

Ketika beberapa operator bergabung dalam satu ekspresi, PHP menentukan urutan evaluasi lewat aturan operator precedence. Perkalian dan pembagian dievaluasi lebih dahulu daripada penjumlahan dan pengurangan, sehingga 2 + 3 * 4 menghasilkan 14, bukan 20. Operator dengan kekuatan sama dievaluasi dari kiri ke kanan (kecuali **):

php
<?php
var_dump(2 + 3 * 4);   // * lebih dulu: 2 + 12
var_dump((2 + 3) * 4); // kurung memaksa penjumlahan lebih dulu
var_dump(20 - 4 - 3);  // kiri ke kanan: (20 - 4) - 3

Output yang Dihasilkan:

text
int(14)
int(20)
int(13)

Tanda kurung adalah alat paling aman untuk memaksa urutan evaluasi sekaligus membuat maksud kode lebih jelas. Kita akan membedah tabel precedence lengkap beserta jebakan-jebakannya pada chapter Operator Precedence .

Berkas contoh.php pada bagian bawah halaman merangkum seluruh contoh chapter ini dalam satu program utuh yang bisa Anda jalankan langsung dengan php contoh.php.

Referensi #

Ringkasan #

PHP menyediakan enam operator aritmatika (+, -, *, /, %, **) dengan perilaku khas: pembagian menghasilkan float saat ada sisa, modulo mengikuti tanda dividen, pangkat bersifat kanan-ke-kiri, dan pembagian nol melempar DivisionByZeroError. Fungsi intdiv(), fmod(), dan fdiv() melengkapi kasus-kasus khusus. Setelah mampu menghitung, langkah alami berikutnya adalah menyimpan hasil perhitungan itu secara ringkas ke variabel — tugas operator assignment yang menjadi fokus chapter berikutnya.

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

contoh.php

Unduh berkas
php
<?php
// contoh.php — rangkuman Operator Aritmatika
// Jalankan dengan: php contoh.php

$a = 7;
$b = 2;

echo "== Enam operator dasar ==\n";
echo "Penjumlahan: $a + $b = " . ($a + $b) . "\n";
echo "Pengurangan: $a - $b = " . ($a - $b) . "\n";
echo "Perkalian  : $a * $b = " . ($a * $b) . "\n";
echo "Pembagian  : $a / $b = " . ($a / $b) . "\n";
echo "Modulo     : $a % $b = " . ($a % $b) . "\n";
echo "Pangkat    : $a ** $b = " . ($a ** $b) . "\n";

echo "\n== Pembagian, modulo, dan intdiv ==\n";
var_dump(10 / 2, 7 / 2, 10 / 4);

$nilai = 17;
$pembagi = 5;
$hasilBagi = intdiv($nilai, $pembagi);
$sisa = $nilai % $pembagi;
echo "intdiv(17, 5) = $hasilBagi, 17 % 5 = $sisa\n";
var_dump($hasilBagi * $pembagi + $sisa === $nilai); // bukti hubungan

echo "\n== Tanda hasil modulo mengikuti dividen ==\n";
var_dump(-5 % 3, 5 % -3, -5 % -3);

echo "\n== Operator pangkat ==\n";
var_dump(2 ** 10, 2 ** 3 ** 2, 2 ** -2, -2 ** 2, (-2) ** 2);

echo "\n== Modulo untuk float: fmod ==\n";
var_dump(fmod(10.5, 3));

echo "\n== Pembagian nol ditangani try/catch ==\n";
$pembagiNol = 0;
try {
    echo "5 / 0 = " . (5 / $pembagiNol) . "\n";
} catch (DivisionByZeroError $e) {
    echo "5 / 0 gagal: " . $e->getMessage() . "\n";
}
try {
    echo "5 % 0 = " . (5 % $pembagiNol) . "\n";
} catch (DivisionByZeroError $e) {
    echo "5 % 0 gagal: " . $e->getMessage() . "\n";
}
try {
    echo "intdiv(5, 0) = " . intdiv(5, $pembagiNol) . "\n";
} catch (DivisionByZeroError $e) {
    echo "intdiv(5, 0) gagal: " . $e->getMessage() . "\n";
}

echo "\n== Urutan evaluasi ==\n";
var_dump(2 + 3 * 4, (2 + 3) * 4, 20 - 4 - 3);