Manipulasi bit bagian 4: ekstraksi bit

Ekstraksi bit adalah proses pengambilan satu atau lebih bit dari sebuah bilangan. Saya contohkan dulu dalam sistem desimal sebelum masuk ke sistem biner.

Waktu kuliah, NIM saya adalah 13598054. Angka ini sebagai desimal bisa dibaca menjadi tiga belas juta lima ratus sembilan puluh delapan ribu lima puluh empat. Tapi. NIM itu bukan untuk dibaca sebagai bilangan, NIM itu dibentuk dari kode: 1 adalah jenjang (1=s1, 2=s2, 3=s3) kode 35 adalah jurusan (informatika), 98 adalah tahun masuk dan 054 adalah nomor urut saya. Dengan mengekstraksi digit desimal maka kita bisa mendapatkan makna baru dari sebuah bilangan.

Bagaimana cara mengekstraksi bagian jurusan (35) dari angka tersebut? Dengan manipulasi string, kita bisa melakukannya dengan substr/substring/fungsi sejenis. Tapi konversi ke string tidak efisien. Operasi aritmatika bisa digunakan untuk ekstraksi 2 digit jurusan.

Pertama kita bisa menggeser semua digit tahun masuk dan nomor urut (5 angka), dengan shift right 5 digit alias membagi dengan 100000 dibulatkan ke bawah. Hasilnya adlah 135. Setelah itu kita bisa menggunakan modulus 100 untuk mendapatkan angka 35.

Dalam biner, hal yang sama bisa kita lakukan. Misalnya kita ingin menyimpan tanggal (1-31) bulan (1-12) dan tahun (00-99) dalam satu angka biner. Cara penyimpanan seperti ini memungkinkan kita mengurutkan tanggal dengan mudah dan cepat.

Kita bisa menyimpan tahun dalam 7 bit (0-127) bulan dalam 4 bit (0-15) dan tanggal dalam 5 bit (0-31). Total kita butuh 16 bit.

Misalnya kita akan menyimpan tahun 12 (0001010) bulan 5 (0101) tanggal 17 (10001):

0001010 0101 10001

Atau:

0001010010110001

Jika dipandang sebagai 1 bilangan 16 bit: 5272.

Angka tersebut kelihatan jauh sekali dari angka awal kita (17-5-12).

Untuk mengekstraksi bulan. Kita perlu mengubah 5272 menjadi biner:

0001010010110001

Kita geser ke kanan sebanyak 5 untuk menghilangkan tanggal:

0000000010100101

Sekarang kita bisa menggunakan operator and untuk mengambil 4 digit terakhir:

0000000010100101

And

0000000000001111

Hasilnya

0000000000000101

Jika kita hilangkan digit 0 di depan:

101 = 5 desimal (bulan 5).

Secara umum untuk mengekstraksi bit, kita perlu menggeser ke kanan untuk menghilangkan bit yang tidak kita inginkan, lalu di-andkan dengan deretan bit 1 sebanyak bit yang ingin kita ekstrak (dalam kasus ini: 4 bit).

Posting ini ditulis dengan wordpress for blackberry sambil tiduran di waktu libur.

Manipulasi bit bagian 2: operator bit

Dalam aljabar boolean kita berurusan dengan dua nilai: 0 dan 1 (atau false dan true). Dalam aljabar boolean, ada banyak operasi, tapi biasanya kita hanya peduli pada beberapa operasi dasar: AND, OR, NOT, dan XOR. Jika kita mengkonversi bilangan desimal ke dalam bentuk biner, maka kita akan mendapatkan banyak angka 0 dan 1 (tergantung berapa besar bilangannya).

Dalam operasi bit, kita akan melakukan operasi pada tiap-tiap bit pada posisi yang sama. Jadi jika kita melakukan sebuah operasi pada dua angka 8 bit A dan B, maka: ambil bit pertama dari A, operasikan dengan bit pertama di B, lalu berikutnya ambil bit kedua dari A, lalu operasikan dengan bit kedua dari B, demikian seterusnya.

Di hampir semua bahasa pemrograman, operasi bit dilakukan sekaligus pada semua bit di sebuah register atau variabel. Berikut ini definisi beberapa operator bit yang sifatnya binary (Operasi dilakukan pada posisi bit yang sama di kedua variabel atau register tersebut):

  1. AND: jika ada dua bit di posisi yang sama nilainya 1, maka nilai bit di posisi tersebut menjadi 1, jika tidak maka 0 (1 AND 1 = 1, 1 AND 0 = 0, 0 AND 1 = 0, 0 AND 0 = 0).
  2. OR: jika salah satu bit atau kedua bit nilainya 1 di posisi yang sama, maka nilai bit di posisi tersebut menjadi 1, jika tidak maka 0 (1 OR 1 = 1, 1 OR 0 = 1, 0 OR 1 = 1, 0 OR 0 = 0).
  3. XOR: jika dua bit di posisi yang sama nilainya berbeda, maka nilai bit di posisi tersebut menjadi 1, jika tidak maka 0 (1 XOR 1 = 0, 1 XOR 0 = 1, 0 XOR 1 = 1, 0 XOR 0 = 0).

Ada juga operator unary, yaitu NOT: membalik bit 0 menjadi 1 dan sebaliknya.

Beberapa contoh:

  1. 5 desimal xor 3 desimal : 0101 xor 0011 = 0110 = 6 desimal.
  2. 5 desimal or 3 desimal : 0101 or 0011 = 0111 = 7 desimal.

Contoh lebih lengkap bisa dilihat di Wikipedia.

Mengetahui operator dasar AND sudah cukup untuk memeriksa apakah suatu bilangan sifatnya ganjil atau genap. Jika kita meng-AND-kan suatu bilangan dengan 1 dan hasilnya sama dengan 1 maka bilangan tersebut adalah ganjil, jika nol maka genap.

Di tulisan berikutnya saya akan membahas mengenai bit shift dan rotate.

Manipulasi bit bagian 1: representasi biner

Kemarin buku yang saya tunggu-tunggu akhirnya tiba juga: The Art of Computer Programming, Volumes 1-4A Boxed Set (Box Set). Dulu waktu kuliah, saya sudah membaca sebagian buku ini, tapi buku ini berat di matematika, jadi kebanyakan saya hanya membaca bagian algoritmanya saja, sambil mencoba-coba sedikit latihannya. Terinspirasi dari banyak programmer di buku Coders at work yang menyukai buku ini, dan minimal memakai buku ini sebagai referensi, maka saya sekarang berusaha membaca ulang koleksi buku Knuth, plus membaca volume yang baru: Volume 4a.

Sebagai catatan: dalam wawancara Knuth sendiri tidak menyarankan seseorang membaca buku ini dari sampul ke sampul sampai habis. Saya membaca buku ini pertama skimming dulu, mencari topik menarik, setelah itu baru saya baca teliti bagian-bagian yang saya perlukan. Jadi jika Anda merasa berat membaca buku ini: coba langsung skip ke bagian yang menarik.
Lanjutkan membaca Manipulasi bit bagian 1: representasi biner

Tools untuk debugging

Di posting ini saya sekedar ingin sharing metode dan tools yang biasa saya pakai untuk debugging program. Di lingkungan yang ideal, kita seharusnya punya debugger yang canggih, cepat dan reliable, tapi sayangnya sering kali ini tidak tersedia. Ini contoh beberapa lingkungan pengembangan yang “mengesalkan” yang pernah saya jumpai:

  • Symbian versi awal (versi 6): untuk bisa mendebug, perlu IDE khusus dengan license khusus yang mahal. Symbian versi terbaru sudah semakin baik (tapi sekarang ini Symbian sudah akan berakhir).
  • BlackBerry: startup time debugger sangat lama, dan debugger sering error. Setiap kali menginstall versi program baru di BlackBerry, perlu restart (butuh sekitar 5 menit tiap kali restart).
  • Mendebug aplikasi Android di emulator. Startup emulator sangat lambat (bahkan di processor AMD quad core 3 ghz memori 16 GB) , lebih cepat mencoba langsung di HP. Masalahnya adalah ketika ada laporan: ada bug kecil di Android versi 2.2, tapi HP saya memakai Android 2.3
  • Debugging PHP di web hosting. Kadang ada masalah yang hanya muncul di web hosting, tapi tidak muncul ketika dicoba di server sendiri. Beberapa kemungkinan adalah karena versi PHP yang tidak sama, versi library yang tidak sama. Di server sendiri bisa mudah menginstall Xdebug, tapi tidak tersedia di tempat hosting.
  • Nurit Point Of Sales. Device ini banyak bugnya, tidak tersedia debugger, dan jika crash, akan memprint isi memori di atas kertas thermal sekitar 1/2 meter.
  • Kernel FreeBSD. Ketika porting tahap awal, sangat sulit mendebug apa yang terjadi di level CPU. Masalahnya karena saya tidak menggunakan development board yang memiliki JTAG.

Sebenarnya tidak semua lingkungan itu benar-benar mengesalkan jika kita punya uang, contohnya: jika saya punya uang beberapa ribu dollar, saya akan bisa mendebug Symbian dengan mudah. Jika saya punya beberapa HP Android berbagai versi, debugging Android juga lebih mudah. Jika saya punya development board resmi dengan JTAG, porting kernel akan lebih mudah. Jika saya hosting VPS dengan versi PHP saya sendiri, maka tidak akan ada masalah dengan PHP, dan andaikan ada masalah, saya bisa menginstall XDebug. Pada kenyataannya seringkali tidak tersedia dana untuk menyelesaikan berbagai masalah tersebut.
Lanjutkan membaca Tools untuk debugging

Berpikir Ketika Memprogram dan Menguji Program

Setelah membaca posting reddit ini, saya teringat kembali pada buku Programming Pearl, terutama bagian yang dibahas dalam posting itu yaitu mengenai binary search. Dalam buku programming pearl dinyatakan bahwa para programmer professional yang diberi waktu 2 jam untuk menulis binary search, 90% memiliki bug (terutama di *boundary* condition). Penulis blog memberi tantangan pada pembacanya untuk membuat binary search, boleh beberapa jam, tapi *tanpa testing* sama sekali.

Respon kebanyakan orang bisa dirangkum menjadi tiga kubu. Kubu pertama: ah di dunia nyata kan orang pasti testing, keahlian buat memprogram dengan benar tanpa testing itu tidak berguna. Kubu kedua menyatakan: kalau program sependek itu tidak bisa dibuat tanpa testing, bagaimana mungkin bisa membuat program besar yang rumit, apakah tiap baris program harus ditest?. Kubu terakhir menyatakan: buat apa sih membuat binary search, kan sudah ada di library/API?

Untuk kubu terakhir, jawabannya sederhana: ada kasus di mana hal tersebut masih diperlukan. Misalnya fungsi binary search di library kebanyakan tidak menyatakan elemen mana yang akan dikembalikan jika ada lebih dari 1 data yang cocok, dan tidak akan mengembalikan lokasi di mana data bisa disisipkan jika data belum ada. Contohnya di fungsi bsearch di C (POSIX):

The bsearch() function returns a pointer to a matching member of the array, or NULL if no match is found. If there are multiple elements that match the key, the element returned is unspecified.

Kadang diperlukan fungsi yang mengembalikan elemen pertama yang cocok, atau terakhir yang cocok, atau bahkan elemen random dari antara semua elemen yang cocok. Tentu saja salah satu solusinya adalah membungkus fungsi bsearch, lalu mencari ke depan atau belakang sampai tidak cocok lagi. Tapi dalam hal ini Anda juga tetap perlu memperhatikan batas index ketika mencari, jadi Anda tetap perlu menulis kode (yang perlu testing dan perlu dipikirkan).

Jika Anda mengimplementasikan fungsi binary search sendiri, Anda bisa membuat fungsi yang sekaligus mengembalikan posisi elemen di mana kita harus menyisipkan elemen tersebut jika elemen tidak ditemukan (ini bisa didapat dari lokasi perbandingan terakhir), dalam kasus ini kita tidak bisa membungkus fungsi bsearch, karena fungsi tersebut hanya mengembalikan NULL jika elemen tidak ditemukan.

Beberapa Pelajaran yang bisa dipetik dari posting dan diskusi adalah: testing itu perlu, bahkan untuk program kecil sekalipun. Pelajaran kedua adalah: kita tetap harus teliti dan berpikir ketika memprogram. Pelajaran ketiga adalah: meski isi library di berbagai bahasa sudah cukup lengkap, mengerti algoritma sederhana itu perlu, dan kadang kita perlu mengimplementasikan algoritma tersebut atau variannya.

Sebagian orang berpikir: ah tidak perlu terlalu teliti ketika memprogram, nanti akan ketauan salahnya ketika testing. Sebagian lagi berpikir: program ini sudah saya pikirkan, jadi gak perlu ditest. Sikap yang benar adalah: kedua hal tersebut berhubungan, kita harus teliti ketika memprogram, dan harus teliti juga dalam membuat testing. Mengapa tidak menggantungkan diri pada testing saja? ada beberapa masalah dengan testing, pertama testing itu sulit, untuk membuat test case yang baik perlu kasus yang sangat besar dan kedua testing tidak selalu bisa dilakukan.
Lanjutkan membaca Berpikir Ketika Memprogram dan Menguji Program

Kritik PHP

PHP merupakan bahasa yang kurang bagus, designnya tidak dipikirkan dengan matang. Banyak sekali keanehan PHP dibanding bahasa lain, dan meskipun PHP sudah mulai agak membaik di versi 5.3 (yang baru dirilis 3 minggu yang lalu), saya masih menunggu PHP6 untuk mencoba lagi.

Kebanyakan orang tidak menyadari bahwa mereka butuh sesuatu, atau bahwa sesuatu itu jelek, sampai mereka diberikan sesuatu yang lebih baik. Di artikel ini saya ingin mengkritik PHP, tapi sebelumnya akan saya contohkan apa yang saya maksud dengan melihat sejarah MySQL.

Awalnya MySQL tidak mendukung transaksi. Komentar pendukung MySQL waktu itu: transaksi itu tidak perlu, yang penting cepat (Bahkan pembuat mysql pun berpikir demikian, coba lihat http://www.genome.ou.edu/mysql_manual.html#Bugs, bagian ” Some things we don’t have any plans to do”). Tapi kemudian transaksi ditambahkan, dengan catatan: kalau mau cepat jangan pakai transaksi. Lalu berikutnya: transaksi adalah salah satu fitur yang kami banggakan.

Nah, saya cukup yakin, isi kritik saya ini kemungkinan akan banyak ditolak oleh orang yang cinta buta pada PHP, setidaknya saat ini. Tapi ketika PHP sudah berkembang, baru akan bisa diterima. Memang begitulah sifat penggemar sesuatu, jadi saya bisa memakluminya.

Saya sendiri pernah memprogram PHP dari sejak PHP3, lalu PHP4, dan sampai awal PHP5. Semakin lama saya mempelajari dan memakai PHP, saya semakin merasakan keterbatasannya. Saya tidak menyangkal bahwa PHP merupakan bahasa yang sangat populer. Namun tidak semua yang populer itu bagus (ingat DBase? Ingat Visual Basic 6? dsb). Bagi pencinta PHP, Anda mungkin bisa berbangga PHP semakin membaik, meski caranya dengan “tambal sulam”, dan meski Anda harus sering menyesuaikan program agar berjalan di PHP terbaru. Mungkin saya akan mencoba lagi PHP di versinya yang keenam, tapi saat ini mari kita bahas satu persatu kelemahan PHP.

Lanjutkan membaca Kritik PHP

DataStore di Google AppEngine (RDBMS bukan segalanya)

Google AppEngine adalah sebuah layanan Google, di mana kita bisa membuat aplikasi dalam Python atau Java (atau bahasa lain yang memakai virtual machine Java) di infrastruktur milik Google. Secara teori, Anda akan bisa melayani 5 juta pengunjung per bulan secara gratis. Anda bisa membayar ekstra jika ingin mendapatkan resource yang lebih banyak.

Saya akan menceritakan salah satu pengalaman development dengan google appengine, yaitu mengenai bagian pembuatan aplikasi yang scalable, dengan fokus pada DataStore. Menurut saya DataStore merupakan implementasi penyimpanan data yang menarik, yang berbeda dari database relasional yang umum dipakai saat ini.

Ilmu relational database dan SQL hampir tidak dipakai sama sekali di sini. Bahkan operasi Join yang sangat lazim di basis data tidak bisa dilakukan dengan DataStore. Lalu apa kelebihan DataStore? datastore memiliki aneka batasan yang memungkinan Google mendistribusikan data di berbagai server di seluruh dunia. DataStore diiimplementasikan di atas teknologi google yang sudah terbukti, yaitu BigTable.


Di DataStore kita bisa menyimpan banyak jenis entitas, setiap entitas punya satu atau lebih property.  Sebuah property berupa nama dengan tipe tertentu, atau bisa merujuk ke entitas lain. Setiap entitas merupakan instance dari suatu Kind. Entitas dalam kind yang sama tidak selalu memiliki property yang sama.

Lanjutkan membaca DataStore di Google AppEngine (RDBMS bukan segalanya)