1. Sistem Bilangan Floating-Point#

Himpunan bilangan real \(\mathbb{R}\) tak berhingga, karena ia tidak terbatas dan kontinu. Secara komputasi, istilah tak behingga tidak mungkin ditemui. Salah satu sifat yang harus dimiliki oleh suatu algoritma secara adalah keberhinggaan (finiteness). Oleh karena itu, kita perlu mengetahui suatu himpunan berhingga yang dapat dijalankan oleh komputer (sebagai alat komputasi) yang dapat merepresentasikan bilangan real tersebut.

Definisi: Bilangan Floating-Point

Himpunan bilangan floating-point \(\mathbb{F}\) terdiri dari nilai nol dan semua bilangan yang dibentuk dari

(1.1)#\[ \pm (1+f) \times 2^n, \]

dimana \(n\) adalah bilangan bulat yang disebut dengan eksponen, dan \(1+f\) adalah matissa atau significand, dengan

\[ \label{eqn1_2} f = \sum_{i=1}^{d} b_i 2^{-i}, \hspace{1em} b_i \in \{0, 1\}, \]

dan bilangan bulat \(d\) disebut dengan presisi.

Persamaan merepresentasikan significand dengan bilangan di interval \([1, 2)\) dalam bentuk basis-2. Secara ekuivalen,

(1.2)#\[ f = 2^{-d} \sum_{i=1}^{d} b_i 2^{d-i} = 2^{-d}z, \]

untuk suatu bilangan bulat \(z\) di himpunan \(\{ 0, 1, \cdots, 2^d - 1\}\). Konsekunsinya, mulai dari \(2^n\) dan berakhir sebelum \(2^{n+1}\), maka terdapat tepat \(2^d\) evenly spaced numbers yang dimiliki oleh \(\mathbb{F}\).

Contoh 1

Misalkan \(d=2\) dan \(n=0\) di (1.1), kita cacah

\[ 1 + \frac{0}{4}, 1 + \frac{1}{4}, 1 + \frac{2}{4}, 1 + \frac{3}{4}. \]

Angka-angka ini adalah anggota dari \(\mathbb{F}\) yang hanya terdapat di interval \([1, 2)\) dan mereka dipisahkan oleh \(\frac{1}{4}\).

Dari sini kita dapatkan fakta bahwa anggota terkecil dari \(\mathbb{F}\) yang lebih besar dari \(1\) yaitu \(1 + 2^{-d}\) dan dapat kita sebut sebagai machine epsilon.

Definisi: Machine epsilon

Untuk suatu himpunan floating-point dengan presisi digit binary \(d\), machine epsilon (atau machine precision) adalah \(\epsilon_{\text{mach}} = 2^{-d}\).

Kita definisikan fungsi pembulatan \(\text{fl}(x)\) yang memetakan bilangan real \(x\) ke anggota terdekat \(\mathbb{F}\). Jarak antar bilangan floating-point di \([2^n, 2^{n+1})\) adalah \(2^n \epsilon_{\text{mach}} = 2^{n-d}\). Dengan demikian, untuk setiap bilangan real \(x \in [2^n, 2^{n+1})\), jarak anggota di \(\mathbb{F}\) tidak akan lebih dari \(2^{n-d-1}\). Sehingga, kita dapat simpulkan bahwa \(\lvert \text{fl}(x) - x \rvert \leq \frac{1}{2} (2^{n-d})\). Ini berarti

\[ \label{fl_bounded} \frac{\lvert \text{fl}(x) - x \rvert}{|x|} \leq \frac{2^{n-d-1}}{2^n} \leq \frac{1}{2} \epsilon_{\text{mach}}. \]

Persamaan juga berlaku untuk \(x\) yang bernilai negatif. Pernyataan berikut ini ekivalen dengan .

\[ \label{ekui_fl_bounded} \text{fl}(x) = x(1+\epsilon), \hspace{1em} \text{untuk } |\epsilon| \leq \frac{1}{2} \epsilon_{\text{mach}}. \]

Berdasarkan , kita dapat mengatakan bahwa nilai \(\epsilon\) bergantung pada \(x\),

1.1. Presisi dan Akurasi#

Untuk lebih mempermudah kita gunakan bilangan desimal (basis 10):

(1.3)#\[ \pm \left( b_0 + \sum_{i=1}^{d} b_i 10^{-i}\right) \times 10^n = \pm(b_0. b_1b_2 \cdots b_d) \times 10^n, \]

dimana setiap \(b_i \in \{ 0, 1, \cdots, 9 \}\) dan \(b_0 \neq 0\). Ini secara sederhana disebut dengan notasi saintifik dengan \(d+1\) significant digit. Contohnya, konstanta Planck adalah \(6.626068 \times 10^{-34}\text{ m}^2. \text{kg}/\text{sec}\) dan memiliki tujuh significant digit. Jika kita ganti digit terakhir dari konstanta tersebut dari \(8\) ke \(9\), maka perubahan relatifnya adalah

\[ \frac{0.000001 \times 10^{-34}}{6.626068 \times 10^{-34}} \approx 1.51 \times 10^{-7}. \]

Dengan demikian kita dapat katakan bahwa konstanta tersebut memiliki presisi 7 digit desimal. Setiap hasil yang direpresentasikan menggunakan \(d\) binary digit, tapi tidak semua digit tersebut dengan akurat merepresentasikan suatu nilai. Misalkan \(x\) adalah bilangan yg ingin direpresentasikan, \(\hat{x}\) adalah aproksimasinya. Akurasi absolut dari \(\hat{x}\) adalah

\[ |x-\hat{x}|, \]

dan akurasi relatif adalah

\[ \frac{|x-\hat{x}|}{|x|}. \]

Kita bisa mengekspresikan akurasi relatif untuk menentukan banyaknya digit yang akurat, dihitung dalam basis 10

\[ -\log_{10} \frac{|x-\hat{x}|}{x}. \]
@show p = 22/7
p = 22 / 7 = 3.142857142857143
3.142857142857143
@show float(pi)
float(pi) = 3.141592653589793
3.141592653589793
accuracy = abs(p - pi)
println("akurasi absolut = $accuracy")
println("akurasi relatif = $(accuracy/pi)")
akurasi absolut = 0.0012644892673496777
akurasi relatif = 0.0004024994347707008
digit = floor(-log10(accuracy/pi))
println("Banyaknya digit yang akurat = $digit")
Banyaknya digit yang akurat = 3.0

1.2. Double precision#

Hampir semua komputasi numerik menggunakan standar IEEE 754. Single precision dengan \(d=23\) dan double precision dengan \(d=52\). Di double precision,

\[ \epsilon_{\text{mach}} = 2^{-52} \approx 2.2 \times 10^{-16}. \]

Kita dapat mengatakan bahwa bilangan floating-point double precision memiliki 16 digit desimal.

@show typeof(1);
@show typeof(1.0);
typeof(1) = Int64
typeof(1.0) = Float64
bitstring(1.0)
"0011111111110000000000000000000000000000000000000000000000000000"
[bitstring(1.0), bitstring(-1.0)]
2-element Vector{String}:
 "0011111111110000000000000000000000000000000000000000000000000000"
 "1011111111110000000000000000000000000000000000000000000000000000"
x = 1.0
@show sign(x), exponent(x), significand(x);
(sign(x), exponent(x), significand(x)) = (1.0, 0, 1.0)
x = 0.25
@show sign(x), exponent(x), significand(x)
(sign(x), exponent(x), significand(x)) = (1.0, -2, 1.0)
(1.0, -2, 1.0)
x = -0.25
@show sign(x), exponent(x), significand(x)
(sign(x), exponent(x), significand(x)) = (-1.0, -2, -1.0)
(-1.0, -2, -1.0)
eps()
2.220446049250313e-16
log2(eps())
-52.0
eps(1.618)
2.220446049250313e-16
eps(161.8)
2.842170943040401e-14
nextfloat(161.8)
161.80000000000004
@show floatmin(), floatmax();
(floatmin(), floatmax()) = (2.2250738585072014e-308, 1.7976931348623157e308)
1/7
0.14285714285714285
37.3 + 1
38.3
2^(-4)
0.0625
@show 5.0, Int(5.0);
(5.0, Int(5.0)) = (5.0, 5)

penjelasan mengenai floating-point di Julia dapat dilihat di Manual Julia: Floating point numbers.