Pecahan, Desimal, dan Persentase

Konversi antar bentuk bilangan serta intuisi presisi dan pembulatan.

Daftar isi

Nilai yang sama dapat ditulis dalam beberapa bentuk, dan pemilihan bentuk menentukan seberapa mudah nilai itu dibaca, dihitung, dan disimpan oleh program. Topik ini membahas pecahan, desimal, dan persentase sebagai tiga penulisan bilangan rasional beserta aturan konversinya. Pembahasan dilanjutkan dengan perilaku pembulatan pada Python serta implikasi presisinya ketika bilangan disimpan sebagai float. Setelah topik ini dipahami, konversi antar bentuk dapat dilakukan dengan sengaja dan batas presisinya dapat diantisipasi.

Tiga bentuk bilangan rasional#

Pecahan menyatakan nilai sebagai perbandingan dua bilangan bulat pq\frac{p}{q}, desimal menempatkan nilai pada sistem posisi basis sepuluh, sedangkan persentase menyatakan banyaknya bagian dari seratus. Kata persen berarti per seratus, sehingga 75%75\% dibaca sebagai 75 bagian dari setiap 100 bagian. Bentuk pecahan dipilih ketika perbandingan eksak dibutuhkan, bentuk desimal lazim pada hasil pengukuran, sedangkan persentase paling nyaman untuk pelaporan. Ketiganya menuliskan nilai yang sama pada bilangan rasional, sebagaimana ditunjukkan oleh hubungan berikut.

34=0.75=75% \frac{3}{4} = 0.75 = 75\%

Desimal berhingga memiliki hubungan yang khusus dengan pecahan. Karena 10=2×510 = 2 \times 5, setiap desimal berhingga dapat ditulis sebagai pecahan yang penyebutnya berupa perkalian bilangan dua dan lima, misalnya 0.75=75100=340.75 = \frac{75}{100} = \frac{3}{4}. Sebaliknya, pecahan yang penyebutnya memuat faktor selain dua dan lima, seperti 13\frac{1}{3}, menghasilkan desimal yang berulang tanpa berhenti. Ciri ini menjadi alat uji cepat, karena penyebut pecahan yang sudah disederhanakan langsung memperlihatkan apakah desimalnya berhingga atau berulang. Pemahaman ini penting pada bagian akhir topik ketika desimal berulang dipertemukan dengan penyimpanan float.

Konversi antar bentuk#

Konversi antar bentuk berjalan melalui tiga aturan yang tetap. Pecahan menjadi desimal melalui pembagian pembilang dengan penyebut, desimal menjadi pecahan dengan menuliskannya di atas persepuluan, perseratusan, dan seterusnya lalu menyederhanakannya, sedangkan arah desimal dan persentase dihubungkan oleh angka seratus. Tabel berikut merangkum aturan tersebut.

Bentuk awalTujuanAturanContoh
Pecahan pq\frac{p}{q}DesimalHitung p÷qp \div q34=0.75\frac{3}{4} = 0.75
DesimalPecahanTulis di atas persepuluan atau perseratusan, lalu sederhanakan0.75=75100=340.75 = \frac{75}{100} = \frac{3}{4}
DesimalPersentaseKalikan dengan 100 lalu beri tanda %\%0.75=75%0.75 = 75\%
PersentaseDesimalBagi dengan 10075%=0.7575\% = 0.75

Aturan tersebut dapat diverifikasi dengan modul fractions yang menyimpan pecahan secara tepat dan menyederhanakannya secara otomatis. Penyederhanaan membagi pembilang dan penyebut dengan faktor persekutuan terbesarnya, sehingga 75100\frac{75}{100} kembali ke 34\frac{3}{4}. Dengan penyederhanaan ini, pecahan yang ditampilkan selalu berada dalam bentuk paling sederhana.

python Contoh: konversi pecahan ke desimal dan persentase
from fractions import Fraction

print(Fraction(3, 4), float(Fraction(3, 4)), Fraction(3, 4) * 100)
print(Fraction("0.75"), Fraction(75, 100))
print(float(Fraction(1, 3)))
text Keluaran
3/4 0.75 75
3/4 3/4
0.3333333333333333

Keluaran di atas memperlihatkan tiga hal sekaligus. Nilai 34\frac{3}{4} dikalikan 100 menghasilkan persentasenya, yaitu 75. Konstruksi Fraction("0.75") dan Fraction(75, 100) menghasilkan pecahan yang sama, yaitu 34\frac{3}{4}, karena penyederhanaan dilakukan saat pecahan dibuat. Terakhir, float(Fraction(1, 3)) menghasilkan 0.3333333333333333, hampiran yang menarik untuk dibahas pada bagian berikutnya.

Desimal berulang dan batas presisi#

Pecahan 13\frac{1}{3} tidak memiliki bentuk desimal berhingga, karena pembagiannya menghasilkan pola 0.333... yang berulang tanpa akhir. Penulisan dengan sejumlah digit apa pun, misalnya 0.3333333333333333, hanyalah penghampiran, dan penambahan digit membuat hampiran itu lebih dekat tetapi tidak pernah sama dengan nilai aslinya. Sifat ini berlaku untuk pecahan yang penyebutnya memuat faktor selain dua dan lima. Polanya dapat diperiksa dengan pembagian bersusun, karena sisa pembagian 13\frac{1}{3} selalu kembali ke nilai semula sehingga digit tiganya terus berulang.

Kondisi yang sama terjadi saat nilai disimpan sebagai float. Penyimpanan float hanya memuat sejumlah digit biner yang tetap, sehingga nilai berulang dipotong pada posisi bit tertentu. Tampilan 0.3333333333333333 pada keluaran sebelumnya adalah hasil pemotongan tersebut, bukan nilai yang lengkap. Karena itu, dua program yang menghitung 13\frac{1}{3} dengan cara berbeda dapat mencetak deretan tiga yang identik padahal bit terakhirnya berbeda. Apabila keputusan program bergantung pada kesamaan nilai semacam ini, kesamaan perlu diuji dengan toleransi, sebagaimana kebiasaan pada perhitungan numerik secara umum.

Pembulatan dan presisi#

Pembulatan mengubah nilai dengan banyak digit menjadi nilai dengan digit lebih sedikit, dan aturannya perlu dipahami karena berbeda dari kebiasaan sehari-hari. Fungsi round() pada Python menggunakan aturan pembulatan ke genap terdekat (round half to even), yaitu nilai yang berada tepat di tengah dibulatkan ke digit genap terdekat. Program berikut menampilkan perilaku tersebut bersama pemformatan persentase.

python Contoh: perilaku pembulatan Python
print(round(2.5), round(3.5), round(-2.5))
print(round(0.125, 2), round(0.135, 2))
print(f"{0.75:.1%}", f"{2/3:.1%}")
text Keluaran
2 4 -2
0.12 0.14
75.0% 66.7%

Baris pertama menunjukkan 2.5 dibulatkan ke 2 dan 3.5 dibulatkan ke 4, karena keduanya menuju digit genap terdekat. Baris kedua lebih halus. Nilai 0.125 tersimpan tepat sebagai 18\frac{1}{8} sehingga berstatus setengah sungguhan dan dibulatkan ke 0.12, sedangkan 0.135 tersimpan sedikit di atas nilai aslinya, sehingga berstatus bukan setengah dan dibulatkan ke 0.14. Baris ketiga memperlihatkan pemformatan persentase dengan tanda %, yaitu nilai dikalikan seratus lalu dibulatkan sesuai digit yang diminta.

Di mana hal ini ditemui dalam kode#

Konversi antar bentuk muncul pada pekerjaan sehari-hari dengan pola yang berulang. Metrik seperti akurasi model dilaporkan dalam persentase, padahal nilainya dihitung sebagai pecahan banyaknya prediksi benar dibagi banyaknya data. Laporan statistik menampilkan desimal dengan digit tetap, dan perubahan persentase pada laporan pemakaian bulanan menggunakan pola serupa, yaitu selisih yang dibagi nilai awal lalu dikalikan seratus, dengan tampilan yang dibulatkan agar ringkas. Konversi satuan seperti senti ke inci melibatkan faktor 12.54\frac{1}{2.54} yang menghasilkan desimal berulang, sehingga hasilnya selalu dihampiri. Demo berikut memungkinkan ketiga bentuk tersebut dicoba secara langsung dengan masukan bebas.

Kode sumber demo
<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="utf-8">
  <title>Konverter pecahan, desimal, dan persentase</title>
  <link rel="stylesheet" href="index.css">
</head>
<body>
  <h1>Konverter tiga bentuk bilangan</h1>
  <p class="petunjuk">Ketik sebuah nilai, pilih bentuknya, kemudian klik tombol konversi untuk melihat bentuk lainnya.</p>
  <div class="baris">
    <label for="nilai">Nilai</label>
    <input id="nilai" type="text" value="3/4" autocomplete="off">
    <select id="bentuk">
      <option value="pecahan" selected>Pecahan</option>
      <option value="desimal">Desimal</option>
      <option value="persen">Persentase</option>
    </select>
    <button id="konversi" type="button">Konversi</button>
  </div>
  <table id="hasil">
    <tr><th>Pecahan</th><td id="hasil-pecahan"></td></tr>
    <tr><th>Desimal</th><td id="hasil-desimal"></td></tr>
    <tr><th>Persentase</th><td id="hasil-persen"></td></tr>
  </table>
  <p id="pesan" class="pesan"></p>
  <script src="index.js"></script>

<style>
body {
  font-family: "Segoe UI", Arial, sans-serif;
  color: #1c2b3a;
  margin: 16px;
}
h1 {
  font-size: 1.1rem;
  margin: 0 0 8px;
}
.petunjuk {
  font-size: 0.9rem;
  color: #40566c;
  margin: 0 0 12px;
}
.baris {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 12px;
}
input, select, button {
  font-size: 0.95rem;
  padding: 6px 8px;
  border: 1px solid #4a7ab5;
  border-radius: 4px;
}
button {
  background: #35618e;
  color: #ffffff;
  cursor: pointer;
}
table {
  border-collapse: collapse;
}
th, td {
  border: 1px solid #b9c9d8;
  padding: 6px 12px;
  font-size: 0.95rem;
  text-align: left;
}
th {
  background: #e8eff8;
}
.pesan {
  color: #a03030;
  font-size: 0.9rem;
}

</style>
<style>
body {
  font-family: "Segoe UI", Arial, sans-serif;
  color: #1c2b3a;
  margin: 16px;
}
h1 {
  font-size: 1.1rem;
  margin: 0 0 8px;
}
.petunjuk {
  font-size: 0.9rem;
  color: #40566c;
  margin: 0 0 12px;
}
.baris {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 12px;
}
input, select, button {
  font-size: 0.95rem;
  padding: 6px 8px;
  border: 1px solid #4a7ab5;
  border-radius: 4px;
}
button {
  background: #35618e;
  color: #ffffff;
  cursor: pointer;
}
table {
  border-collapse: collapse;
}
th, td {
  border: 1px solid #b9c9d8;
  padding: 6px 12px;
  font-size: 0.95rem;
  text-align: left;
}
th {
  background: #e8eff8;
}
.pesan {
  color: #a03030;
  font-size: 0.9rem;
}

</style>
<script>
// ---- logika konversi ----

function gcd(a, b) {
  a = Math.abs(a);
  b = Math.abs(b);
  while (b !== 0) {
    [a, b] = [b, a % b];
  }
  return a === 0 ? 1 : a;
}

function sederhanakan(p, q) {
  const g = gcd(p, q);
  return { p: p / g, q: q / g };
}

// membaca desimal berhingga, koma diterima sebagai pemisah desimal
function kePecahan(teks) {
  const m = teks.match(/^\s*(-)?(\d+)(?:[.,](\d+))?\s*$/);
  if (!m) return null;
  const tanda = m[1] === "-" ? -1 : 1;
  const des = m[3] || "";
  if (des === "") return { p: tanda * Number(m[2]), q: 1 };
  return { p: tanda * Number(m[2] + des), q: 10 ** des.length };
}

function dariPecahan(teks) {
  const m = teks.match(/^\s*(-)?(\d+)\s*\/\s*(\d+)\s*$/);
  if (!m) return null;
  const penyebut = Number(m[3]);
  if (penyebut === 0) return null;
  const tanda = m[1] === "-" ? -1 : 1;
  return sederhanakan(tanda * Number(m[2]), penyebut);
}

function konversi(teks, bentuk) {
  let fr = null;
  if (bentuk === "pecahan") {
    fr = dariPecahan(teks);
  } else if (bentuk === "desimal") {
    const c = kePecahan(teks);
    if (c !== null) fr = sederhanakan(c.p, c.q);
  } else if (bentuk === "persen") {
    const c = kePecahan(teks.replace("%", ""));
    if (c !== null) fr = sederhanakan(c.p, c.q * 100);
  }
  return fr;
}

function formatPecahan(fr) {
  return fr.q === 1 ? String(fr.p) : fr.p + "/" + fr.q;
}

function formatDesimal(fr) {
  return String(Number((fr.p / fr.q).toFixed(6)));
}

function formatPersen(fr) {
  const nilai = Number(((fr.p / fr.q) * 100).toFixed(4));
  return String(nilai) + "%";
}

// ---- pengikatan antarmuka ----

function perbarui() {
  const teks = document.getElementById("nilai").value;
  const bentuk = document.getElementById("bentuk").value;
  const fr = konversi(teks, bentuk);
  const pesan = document.getElementById("pesan");
  const keluaran = document.getElementById("hasil");
  if (fr === null) {
    keluaran.style.display = "none";
    pesan.textContent = "Masukan tidak dapat dibaca. Gunakan bentuk seperti 3/4, 0.75, atau 75%.";
    return;
  }
  pesan.textContent = "";
  keluaran.style.display = "";
  document.getElementById("hasil-pecahan").textContent = formatPecahan(fr);
  document.getElementById("hasil-desimal").textContent = formatDesimal(fr);
  document.getElementById("hasil-persen").textContent = formatPersen(fr);
}

document.getElementById("konversi").addEventListener("click", perbarui);
document.getElementById("nilai").addEventListener("keydown", (kejadian) => {
  if (kejadian.key === "Enter") perbarui();
});
perbarui();

</script>
<script>
// ---- logika konversi ----

function gcd(a, b) {
  a = Math.abs(a);
  b = Math.abs(b);
  while (b !== 0) {
    [a, b] = [b, a % b];
  }
  return a === 0 ? 1 : a;
}

function sederhanakan(p, q) {
  const g = gcd(p, q);
  return { p: p / g, q: q / g };
}

// membaca desimal berhingga, koma diterima sebagai pemisah desimal
function kePecahan(teks) {
  const m = teks.match(/^\s*(-)?(\d+)(?:[.,](\d+))?\s*$/);
  if (!m) return null;
  const tanda = m[1] === "-" ? -1 : 1;
  const des = m[3] || "";
  if (des === "") return { p: tanda * Number(m[2]), q: 1 };
  return { p: tanda * Number(m[2] + des), q: 10 ** des.length };
}

function dariPecahan(teks) {
  const m = teks.match(/^\s*(-)?(\d+)\s*\/\s*(\d+)\s*$/);
  if (!m) return null;
  const penyebut = Number(m[3]);
  if (penyebut === 0) return null;
  const tanda = m[1] === "-" ? -1 : 1;
  return sederhanakan(tanda * Number(m[2]), penyebut);
}

function konversi(teks, bentuk) {
  let fr = null;
  if (bentuk === "pecahan") {
    fr = dariPecahan(teks);
  } else if (bentuk === "desimal") {
    const c = kePecahan(teks);
    if (c !== null) fr = sederhanakan(c.p, c.q);
  } else if (bentuk === "persen") {
    const c = kePecahan(teks.replace("%", ""));
    if (c !== null) fr = sederhanakan(c.p, c.q * 100);
  }
  return fr;
}

function formatPecahan(fr) {
  return fr.q === 1 ? String(fr.p) : fr.p + "/" + fr.q;
}

function formatDesimal(fr) {
  return String(Number((fr.p / fr.q).toFixed(6)));
}

function formatPersen(fr) {
  const nilai = Number(((fr.p / fr.q) * 100).toFixed(4));
  return String(nilai) + "%";
}

// ---- pengikatan antarmuka ----

function perbarui() {
  const teks = document.getElementById("nilai").value;
  const bentuk = document.getElementById("bentuk").value;
  const fr = konversi(teks, bentuk);
  const pesan = document.getElementById("pesan");
  const keluaran = document.getElementById("hasil");
  if (fr === null) {
    keluaran.style.display = "none";
    pesan.textContent = "Masukan tidak dapat dibaca. Gunakan bentuk seperti 3/4, 0.75, atau 75%.";
    return;
  }
  pesan.textContent = "";
  keluaran.style.display = "";
  document.getElementById("hasil-pecahan").textContent = formatPecahan(fr);
  document.getElementById("hasil-desimal").textContent = formatDesimal(fr);
  document.getElementById("hasil-persen").textContent = formatPersen(fr);
}

document.getElementById("konversi").addEventListener("click", perbarui);
document.getElementById("nilai").addEventListener("keydown", (kejadian) => {
  if (kejadian.key === "Enter") perbarui();
});
perbarui();

</script></body>
</html>

Demo di atas menerima masukan berbentuk pecahan, desimal, maupun persentase, kemudian menampilkan ketiga bentuknya. Pecahan disederhanakan menggunakan faktor persekutuan terbesar, dan masukan yang tidak dapat dibaca ditolak dengan pesan. Logika konversinya sengaja ditulis terpisah dari antarmuka agar setiap aturan pada tabel sebelumnya dapat ditelusuri satu per satu dalam kode.

Ringkasan#

  • Pecahan, desimal, dan persentase adalah tiga penulisan untuk nilai yang sama, dengan hubungan 34=0.75=75%\frac{3}{4} = 0.75 = 75\% sebagai pola dasarnya.
  • Konversi menggunakan tiga aturan tetap, yaitu pembagian untuk pecahan menuju desimal, penyebut persepuluan lalu penyederhanaan untuk arah sebaliknya, dan faktor 100 untuk persentase.
  • Desimal berulang seperti 13\frac{1}{3} tidak pernah tepat dalam desimal berhingga maupun float, sehingga setiap konversinya menghasilkan hampiran.
  • Fungsi round() menggunakan pembulatan ke genap terdekat, dan kebutuhan aturan lainnya disediakan modul decimal dengan mode pembulatan yang eksplisit.

Referensi#