Praktikum P2 membahas representasi bilangan dalam biner. Pada praktikum ini dilakukan konversi desimal ke biner, konversi biner ke desimal, serta pengujian bilangan yang dapat atau tidak dapat berhenti secara tepat dalam representasi biner.
dec_to_bin_powers <- function(d, max_iter = 60, tol = 1e-9) {
powers <- c()
for (i in 1:max_iter) {
p <- floor(log2(d))
d <- d - 2^p
powers <- c(powers, p)
if (d < tol) break
}
powers # posisi digit '1' pada bentuk biner
}
dec_to_bin_powers(13) # bandingkan dengan hitungan manual di kelas
## [1] 3 2 0
dec_to_bin_powers(11.5625) # bandingkan dengan hitungan manual di kelas
## [1] 3 1 0 -1 -4
dec_to_bin_powers(0.1) # perhatikan baik-baik apa yang terjadi!
## [1] -4 -5 -8 -9 -12 -13 -16 -17 -20 -21 -24 -25 -28 -29
Apakah hasil dec_to_bin_powers(13) dan
dec_to_bin_powers(11.5625) sesuai dengan hitungan manual
(1101)₂ dan (1011.1001)₂ yang kita kerjakan di
kelas?
Jawaban:
Untuk 13:
\[ 13 = 8 + 4 + 1 = 2^3 + 2^2 + 2^0 \]
Jadi posisi digit 1 adalah 3, 2, dan 0, sehingga bentuk
binernya adalah 1101. Maka hasil
dec_to_bin_powers(13) sesuai dengan hitungan manual.
Untuk 11.5625:
\[ 11.5625 = 8 + 2 + 1 + 0.5 + 0.0625 \]
\[ =2^3+2^1+2^0+2^{-1}+2^{-4} \]
Jadi posisi digit 1 adalah 3, 1, 0, -1, dan -4, sehingga
bentuk binernya 1011.1001. Jadi hasil
dec_to_bin_powers(11.5625) juga sesuai dengan hitungan
manual.
Untuk dec_to_bin_powers(0.1), fungsi berhenti
karena mencapai max_iter=60, BUKAN karena
d<tol. Jelaskan kenapa — kaitkan dengan pembahasan
“Kenapa 0.1 Tidak Pernah Tepat dalam Biner”.
Jawaban:
Bilangan desimal 0.1 tidak dapat direpresentasikan tepat sebagai pecahan yang penyebutnya merupakan pangkat 2.
\[ 0.1=\frac{1}{10}=\frac{1}{2\times5} \]
Penyebutnya masih mempunyai faktor 5, sehingga representasi binernya
tidak berhenti dan terus menghasilkan digit biner. Akibatnya, nilai
d tidak menjadi lebih kecil dari tol secara
tepat. Dalam program ini, fungsi akhirnya berhenti karena sudah mencapai
max_iter = 60.
Jadi, hal tersebut menunjukkan bahwa 0.1 tidak memiliki representasi biner yang berhenti.
bin_to_dec <- function(powers) sum(2^powers)
bin_to_dec(dec_to_bin_powers(13)) # harus kembali ke 13
## [1] 13
bin_to_dec(dec_to_bin_powers(11.5625)) # harus kembali ke 11.5625
## [1] 11.5625
# Sekarang coba arah sebaliknya secara manual:
# ubah (110101.101)_2 ke vektor pangkat dulu, baru konversi
bin_to_dec(c(5, 4, 2, -1, -3))
## [1] 52.625
Apakah bin_to_dec(dec_to_bin_powers(13)) dan
bin_to_dec(dec_to_bin_powers(11.5625)) benar-benar kembali
ke nilai semula? Jelaskan kenapa dua fungsi ini disebut “saling
invers”.
Jawaban:
Ya.
Untuk 13:
bin_to_dec(dec_to_bin_powers(13))
menghasilkan kembali 13.
Untuk 11.5625:
bin_to_dec(dec_to_bin_powers(11.5625))
menghasilkan kembali 11.5625.
Kedua fungsi disebut saling invers karena fungsi pertama mengubah bilangan desimal menjadi daftar posisi pangkat 2 pada bentuk biner, sedangkan fungsi kedua mengubah daftar pangkat tersebut kembali menjadi bilangan desimal. Jadi prosesnya dapat digambarkan sebagai:
\[ \text{desimal} \rightarrow \text{biner} \rightarrow \text{desimal} \]
dan untuk bilangan yang representasi binernya berhenti rapi, hasil akhirnya kembali ke nilai awal.
Tuliskan langkah manual (jumlahkan tiap digit dikali pangkat
2) untuk memverifikasi hasil bin_to_dec(c(5, 4, 2, -1, -3))
— apakah cocok dengan output R-nya?
Jawaban:
Vektor pangkat:
c(5, 4, 2, -1, -3)
berarti:
\[ 2^5+2^4+2^2+2^{-1}+2^{-3} \]
Hitung satu per satu:
\[ 2^5=32 \]
\[ 2^4=16 \]
\[ 2^2=4 \]
\[ 2^{-1}=0.5 \]
\[ 2^{-3}=0.125 \]
Kemudian:
\[ 32+16+4+0.5+0.125=52.625 \]
Jadi:
\[ \boxed{52.625} \]
Hasil tersebut cocok dengan output R.
cek_berhenti <- function(d, max_iter = 30, tol = 1e-9) {
length(dec_to_bin_powers(d, max_iter, tol)) < max_iter
}
for (d in c(0.5, 0.3, 0.7, 0.125, 0.6, 0.375)) {
cat(sprintf('d=%.3f berhenti sebelum max_iter? %s\n', d, cek_berhenti(d)))
}
## d=0.500 berhenti sebelum max_iter? TRUE
## d=0.300 berhenti sebelum max_iter? TRUE
## d=0.700 berhenti sebelum max_iter? TRUE
## d=0.125 berhenti sebelum max_iter? TRUE
## d=0.600 berhenti sebelum max_iter? TRUE
## d=0.375 berhenti sebelum max_iter? TRUE
Kelompokkan keenam bilangan di atas menjadi dua: yang
berhenti rapi, dan yang tidak pernah berhenti. Apa pola yang membedakan
keduanya (petunjuk: lihat bentuk pecahan a/b tersederhana
dari masing-masing)?
Jawaban:
\[ 0.5=\frac12 \]
\[ 0.125=\frac18 \]
\[ 0.375=\frac38 \]
Ketiga penyebutnya hanya mempunyai faktor 2, sehingga representasi binernya dapat berhenti.
Jadi:
\[ \boxed{0.5,\ 0.125,\ 0.375} \]
termasuk bilangan yang berhenti rapi.
\[ 0.3=\frac{3}{10} \]
\[ 0.7=\frac{7}{10} \]
\[ 0.6=\frac35 \]
Penyebut pecahan tersebut masih mempunyai faktor selain 2, yaitu faktor 5. Oleh karena itu, representasi binernya tidak berhenti.
Jadi:
\[ \boxed{0.3,\ 0.7,\ 0.6} \]
tidak berhenti.
Pola: setelah pecahan disederhanakan, jika penyebut hanya berbentuk \(2^k\), maka representasi binernya berhenti. Jika ada faktor selain 2, representasi binernya tidak berhenti.
Prediksi TANPA menjalankan kode: apakah 0.45 akan berhenti atau tidak? Jalankan untuk memverifikasi, lalu jelaskan alasannya.
Jawaban:
Ubah 0.45 menjadi pecahan:
\[ 0.45=\frac{45}{100} \]
Sederhanakan:
\[ \frac{45}{100}=\frac{9}{20} \]
Kemudian:
\[ 20=2^2\times5 \]
Karena penyebut masih mempunyai faktor 5, maka 0.45 tidak akan berhenti dalam representasi biner.
Jadi prediksi:
\[ \boxed{0.45\text{ tidak berhenti}} \]
Ketika dijalankan dengan fungsi cek_berhenti() yang
memiliki max_iter = 30, hasilnya akan menunjukkan bahwa
bilangan tersebut tidak berhenti sebelum batas iterasi.
Praktikum ini menunjukkan bahwa tidak semua bilangan desimal dapat direpresentasikan secara tepat dan berhenti dalam biner. Bilangan seperti 0.5, 0.125, dan 0.375 dapat berhenti karena penyebut pecahan sederhananya hanya berupa pangkat 2. Sebaliknya, 0.1, 0.3, 0.6, 0.7, dan 0.45 tidak mempunyai representasi biner yang berhenti karena penyebut pecahannya masih memiliki faktor selain 2.