Artikel dadakan yg seadanya ini dibuat untuk merespon artikel perihal random javascript dari sodara Yanmarshus. Artikel ini sekedar sharing pikiran aja..
Berdasarkan analisis pas-pasan, saya menemukan masalahnya terdapat dari satu bagian dari kode dibawah, kode utama untuk me-random nilai 1 - 10:
a = Math.round((Math.random() * 9) + 1);
Jika dilihat & dipahami sejenak, sepertinya ndak ada yg salah dengan kode diatas. Dan memang tidak ada yg salah kok, hanya jika yg dipermasalahkan bukanlah hasil dari random tsb diharapkan mempunyai kesempatan yg sama untuk tampil.
Math.round adalah sumber masalahnya. Karena method ini secara alami mempunyai habit seperti:
- Membulatkan nilai kebawah jika nilai desimalnya dibawah .5 (Contoh: 4.34 dibulatkan menjadi 4)
- Membulatkan nilai keatas jika nilai desimalnya diatas .49 (Contoh: 4.5 dibulatkan menjadi 5)
Sebelumnya kita mampir dulu ke method Math.random, yang menghasilkan nilai acak antara 0 — 1 (menghasilkan nilai desimal). Nilai acak yang dihasilkan adalah desimal, yg saya sendiri ndak tau berapa jumlah digit dibelakang koma. Hehe.. Ketika nilai hasil acak dibungkus oleh Math.round, disinilah hal yg terkesan anomali itu terjadi. Kalo saya jabarkan persentase secara matematis hasil acak nilai 1 — 10 dengan kode Math.round((Math.random() * 9) + 1) kira-kira seperti ini:
| Nilai | Range nilai yang dibulatkan | Selisih range nilai (y - x) | Persentase (y - x) | |
|---|---|---|---|---|
| Terendah (x) | Tertinggi (y) | |||
| 1 | 1 | 1.49 | 0.49 | ± 5% |
| 2 | 1.5 | 2.49 | ± 1 | ± 10% |
| 3 | 2.5 | 3.49 | ± 1 | ± 10% |
| 4 | 3.5 | 4.49 | ± 1 | ± 10% |
| 5 | 4.5 | 5.49 | ± 1 | ± 10% |
| 6 | 5.5 | 6.49 | ± 1 | ± 10% |
| 7 | 6.5 | 7.49 | ± 1 | ± 10% |
| 8 | 7.5 | 8.49 | ± 1 | ± 10% |
| 9 | 8.5 | 9.49 | ± 1 | ± 10% |
| 10 | 9.5 | 10 | 0.49 | ± 5% |
Nah, dari tabel diatas setidaknya keliatan knp itu persentase nilai pertama & terakhir selalu dapet ½ lebih kecil dibanding nilai lainnya. Solusinya? Coba diubah kodenya jadi seperti ini:
a = Math.floor((Math.random() * 9) + 1);
Math.floor menggantikan Math.round pada kode diatas. Karena Math.floor sifat alaminya adalah membulatkan kode kebawah, sehingga persentase setiap angka untuk muncul dari hasil acak bisa didapat sekitar 10%. Kira-kira begini gambarannya:
| Nilai | Range nilai yang dibulatkan | Selisih range nilai (y - x) | Persentase (y - x) | |
|---|---|---|---|---|
| Terendah (x) | Tertinggi (y) | |||
| 1 | 1 | 1.99 | ± 1 | ± 10% |
| 2 | 2 | 2.99 | ± 1 | ± 10% |
| 3 | 3 | 3.99 | ± 1 | ± 10% |
| 4 | 4 | 4.99 | ± 1 | ± 10% |
| 5 | 5 | 5.99 | ± 1 | ± 10% |
| 6 | 6 | 6.99 | ± 1 | ± 10% |
| 7 | 7 | 7.99 | ± 1 | ± 10% |
| 8 | 8 | 8.99 | ± 1 | ± 10% |
| 9 | 9 | 9.99 | ± 1 | ± 10% |
| 10 | 10 | 10.99 | ± 1 | ± 10% |
Dan jika ingin mencoba hasilnya, silahkan klik tombol dibawah: