Laman

Selasa, 07 Mei 2013

BAB 30 — IEEE 754 Floating Point

Bab ini adalah tentang standar IEEE 754 floating point. Ini adalah standar untuk angka floating point yang digunakan oleh komputer-komputer saat ini dan bahasa pemrograman sejak 1985. Java floating point (ada di virtual processornya) dan MIPS floating point (ada di hardwarenya) sesuai dengan standard ini.

Topik:

  • Kenapa menggunakan floating point?
  • Sejarah floating point
  • Notasi ilmiah
  • Presisi dari floating point
  • Standar IEEE 754 floating point 
  • Konversi ke notasi floating point
Quest 1: Apakah benar-benar penting bahwa processor harus support dengan data jenis floating point?
Jawab: Tidak. Semua yang dibutuhkan processor hanyalah instruksi-intruksi dasar. Segala sesuatu bisa dibuat dari itu termasuk floating point.

Senin, 06 Mei 2013

Menghitung tiap-tiap float

Gunakan jenis loop for untuk mendapatkan hitungan yang aman. Hitunglah nilai-nilai floating dari variable 0 sampai 100.


double x;
int    j;

for ( j = 0; j < 100; j++ )
{
  x = j/10.0;
 
  // do something with x
}

Hampir semua, menghitung floating point dengan jenis double precision bisa berhasil. Dan yang lebih presisi lagi adalah:


double x;
int    j;

for ( j = 0; j < 160; j++ )
{
  x = j/16.0;
 
  // do something with x
}

Hal ini lebih baik karena 1/16 bisa direpresentasikan oleh biner dengan tepat.

Quest 19: apakah representasi floating point sama dengan fixed poin yang sedang kita bahas saat ini?
Jawab: No. Mereka berhubungan namun floating point lebih canggih. Bab selanjutnya kita akan membahas floating point

Berhitung dengan Integer

Jika tujuan fragmen program adalah berhitung sampai 100kali maka, berhitung di dalam loop bisa menggunakan bilangan bulat, berikut adalah contoh perbaikannya:


int x;

for ( x = 0; x < 100; x++ )
{
  System.out.println("Crimson and Clover");
}

(sudah umum untuk menulis program dengan konvensi seperti ini meskipun program bisa mecapai x=100 dengan tepat.) berikut adalah solusi yang buruk:


float x;

for ( x = 0.0; x < 10.0; x += 0.1 )
{
  System.out.println("Crimson and Clover");
}

Solusi tersebut mugkin memang bekerja seperti yang diharapkan. namun terdapat risiko kalau loop berhitung sampai 101 kali

Infinity Loop yang Tersembunyi

Jika kita menggunakan basis 10, maka 0,1 akan ditambahkan ke x sebanyak 100kali sampai mencapai 10,0 dengan tepat. Tapi komputer menggunakan basis dua floating point, yang artinya tidak merepresentasikan nilai 0,1 secara tepat. Variabel x bisa jadi tidak akan mencapai nilai 10,0 dengan tepat dan program tidak akan looping tanpa henti.


float x;

for ( x = 0.0; x != 10.0; x += 0.1 )
{
  System.out.println("Crimson and Clover");
}

Tidak hanya fixed point yang tidak bisa merepresentasikan sepersepuluh dengan benar, tetapi juga floating point yang biasa dipakai di bahasa pemrograman juga memiliki masalah yang sama.


Code yang Berbahaya

Berikut adalah sebuah fragmen program di Java. (Bisa juga di C atau C++). Apakah ada sesuatu di dalam program tersebut yang perlu kamu khawatirkan?


float x;

for ( x = 0.0; x != 10.0; x += 0.1 )
{
  System.out.println("Crimson and Clover");
}

Quest 16: Berapa kali kah Crimson and Clover akan dicetak?
Jawab: Terus menerus

Hasil yang tidak berhenti

Pada gambar di bawah kita menggunakan algoritma untuk mengkonversi 0,110 menjadi biner.

Algoritma ini tidak pernah berhenti dan menghasilkan pola yang sama 0,2 0,4 0,8 1,6 0,6 1,2 0,2 tanpa henti. Hasilnya pola biner 0011 juga tidak akan berhenti seterusnya.

Fakta yang tidak terduga: nilai "sepersepuluh" tidak bisa direpresentasikan secara presisi oleh pecahan biner. 
Hal ini benar di dalam biner notasi posisi maupun floating point yang digunakan di bahasa pemrograman. Kadang kadang hal ini membutuhkan pertimbangan penting ketika akurasi tinggi diperlukan.
DecimalBinary so far
Start0,10,
×20,20,0
×20,40,00
×20,80,000
×21,60,0001
,60,0001
×21,20,00011
0,20,00011
×20,40,000110
×20,80,0001100
×21,60,00011001
,60,00011001
×21,20,000110011
0,20,000110011
×20,40,0001100110
×20,80,00011001100
Result0,00011001100...

Quest: 15: Bisakah satu per tiga direpresentasikan secara presisi oleh desimal?
Jawab: Tidak 1/3 akan menghasilkan 0,3333.... secara tak terhingga

Masalah dengan sepersepuluh bukanlah masalah spesial yang perlu dihindari, karena dengan semua basis yang ada pasti mempunyai pecahan yang tidak presisi.

Konversi Representasi dari Desimal ke Biner

Seringkali kamu membutuhkan mengkonversi angka desimal semisal 7,625 menjadi sebuah angka biner. Pertama-tama konversi angka bulat nya (dalam kasus ini 7) menjadi biner (111 dalam kasus ini). Tambahkan koma sebagai pemisah pecahan kemudian konversi angka pecahan tersebut menjadi biner.

Untuk mengkonversi pecahan desimal menjadi pecahan biner: Kalikan angka tersebut dengan dua, kemudian ambil angka yang berada di depan koma, lakukan ini sampai isi dari pecahan tersebut menjadi nol.
 DecimalBinary so far
Start0,6250,
×21,2500,1
 ,2500,1
×20,5000,10
 ,5000,10
×21,0000,101
Result,0000,101
 Sebagai contoh 7,625 adalah 111,1012 di kasus ini konversi berhenti setelah pecahan mencapai angka nol. Hal seperti ini tidak selamanya berhasil.

Geser ke kiri satu bit

Mari kita kembali ke corat-coret kertas dan pensil. Berikut adalah angka biner:

0001.0100 = 1.2510

Dan dari pola di atas kita geser ke kiri sejauh 1 langkah

0010.1000 = 2.5010

Quest 12: Apa yang dihasilkan dari geser ke kiri sejauh 1 langkah?
Jawab: Dikalikan dengan dua

Minggu, 05 Mei 2013

Infinity angka yang hilang

Presisi yang terbatas dari fixed point (ataupun floating point) merupakan sebuah masalah bagi programmer. Bahkan menggunakan 64bit double precision floating point (misal type data java double) presisi masih terbatasi. Hanya 264 angka yang bisa di representasikan. Ini memang banyak tapi tetap saja ada sejumlah infinity real number yang tidak bisa direpresentasikan.

(Jika kamu belum paham kalkulus tidak usah khawatir, hanya berpikirlah bahwa kamu bisa membuat pecahan yang tidak terbatas)

Quest 11: Berapa banyak digit yang dimiliki oleh nilai phi?
Jawab: infinity

Presisi yang terbatas

Ini pertanyaan mudah. Jika N bit digunakan maka akan ada sejumlah 2banyaknya yang bisa direpresentasikan oleh digit tersebut, tidak peduli apa jenis yang direpresentasikannya itu. 8bit bisa merepresentasikan sejumlah 256 integer unsigned, 256 integer two complement, maupun 256 angka pecahan (fixed point) dan seterusnya. Berikut adalah gambar garis yang menunjukkan 256 nilai yang bisa direpresentasikan oleh fixed point.

Nilai terkecil adalah zero 00000000 nilai terbesar adalah 15,9375. Angka terkecil setelah nol adalah 0,0625 Semua nilai yang direpresentasikan oleh bilangan ini adalah merupakan kelipatan dari 0,0625.

Cara lain untuk memahami fixed point notation adalah dengan menganggap bahwa 8bit akan menghasilkan 0-255 angka yang angka terkecilnya merupakan 0,0625. dan setiap naik satu angka merupakan kelipatan dari nilai dasarnya yaitu 0,0625. Misal jika
00000001 tanpa koma = 1
00000010 tanpa koma =  1+1 = 2
0000,0001 dengan koma = 0,0625
0000,0010 dengan koma = 0,0625+0,0625 = 0,125

Jarak antara dua buah bilangan bulat jika menggunkan metode ini hanya 16 pembagian, secara 1/16 = 0,0625. hal ini membuat metode bilangan menjadi tidak efektif karena akan menimbulkan banyak gaps diantara tiap angka.

Masalah penting: dalam sebuah pecahan dituntut sebuah presisi yang dinamis, dan tingkat ketelitian yang sesuai agar bisa layak dipakai sebagai sebuah representasi pecahan.

Quest 10: (ingat kalkulus) berapakah jumlah real number yang berada di antara 0,0 sampai 0,0625?
Jawab: Tak terhingga

Algoritma penambahan biner sudah benar

Algoritma penambahan biner, berhasil digunakan sebagai penjumlahan untuk pecahan fixed point. Dulu komputer jadul dan kalkulator menggunakan rangkaian elektronik yang sama untuk digunakan sebagai penjumlahan integer biner (baik two complemen maupun unsigned) dan penjumlahan biner pecahan fixed point. Hal ini sepertinya menjanjikan.

Bagaimanapun fixed point tidak sebagus daripada floating point yang sekarang sudah menggantikannya. Floating point akan dibahas di bab selanjutnya.

Quest 9: berapa banyak nilai yang bisa direpresentasikan menggunakan 8bit fixed point notation?
Jawab: 28 = 256

Cara menjumlahkan fixed point

Berikut adalah angka yang lain 00010100. Angka ini merepresentasikan desimal 1,25 . dan berikut adalah algoritma umum yang biasa digunakan untuk menjumlahkan dua buah pecahan biner

fixed point      as decimal
01101001      6,5625
00010100      1,2500

     
01111101       7,8125

Quest 8: Tentu saja yang jadi pertanyaan adalah apakah penjumlahan pecahan biner menghasilkan hasil yang benar seperti pada penjumlahan pecahan desimal?

Notasi Fixed Point

Dengan kertas dan pensil, kamu bebas menulis berapa digit yang kamu mau. Tapi komputer (biasanya) menggunakan digit yang dibatasi sebagai perwakilan dari jenis data tertentu. Sebagai contoh interger 32bit, jadi bisakah jumlah bit yang terbatas ini digunakan untuk mewakili pecahan?

Ya. Mari kita lihat sejenak metode kuno yang sekarang sudah jarang lagi digunakan. Pada zaman dahulu, kalkulator elektronik dan komputer menggunakan notasi titik tetap untuk mengekspresikan pecahan. Dengan notasi titik tetap, angka diekspresikan dengan cara menganggap sejumlah digit tertentu (misal delapan) dan  koma/titik yang memisahkan antara bilangan bulat dan pecahan ini di anggap pasti berada di sela-sela digit tersebut.

Sebagai contoh, mari kita anggap sebuah angka biner yang menggunakan notasi titik tetap, sebuah koma berada di tengah-tengah 8bit angka ini. Sekarang coba kamu terjemahkan angka tersebut menjadi sebuah bilangan desimal:

Quest 7:
Di skema berikut ini pola bit 01101001 merepresentasikan angka berapa?
Power of 20110,1001
8421,0.50.250.1250.0625











Jawab: 4 + 2 + 0,5 + 0,0625 = 6,5625