Category Archives: C++

Mengganti Vector 2 Dimensi dengan Menggunakan Referensi Pada Fungsi

Beberapa minggu yang lalu, saya kesulitan dalam melewatkan array 2D sebagari referensi dari satu fungsi ke fungsi lain. Di tengah-tengah kesulitan tersebut, saya menemukan sebuah tulisan yang mengatakan bahwa memang cukup sulit untuk melewatkan array 2 dimensi dengan menggunakan referensi alamat. Namun, kita tetap bisa melemparkan (return) sebuah referensi dari sebuah fungsi ke dalam sebuah pointer. Jadi sifatnya hanya 1 arah (return), tidak seperti referensi yang variabelnya akan berubah nilainya di dalam fungsi yang memanipulasinya.

Karena tidak puas, saya mencoba bermain-main dengan vector. Pada awalnya saya memang agak kesulitan, namun setelah dipelajari lebih mendalam, tidak sulit untuk mengontrol vector yang kita buat. Ternyata, vector ini bisa dilewatkan sebagai referensi ke dalam sebuah fungsi :D. Wow, saya cukup senang karena memang itu yang saya inginkan. Penggunaannya juga tidak jauh berbeda dengan melewatkan variabel pada umumnya. Sebagai contoh, di bawah ini adalah sebuah program untuk membuat sebuah vector 2 dimensi, lalu memanggil sebuah fungsi untuk memanipulasi vector tersebut, kemudian menampilkan isi vector yang sudah diganti tersebut.

#include <iostream>
#include <vector>
using namespace std;
 
void manipulasiVector(vector<vector<double> > &);
 
int main()
{
	typedef vector<double> vint;
	vint tmp(4);
	vector<vint> matriks(3);
	int i=0, j=0;
	cout << endl;
	for(i=0; i<3; i++){
		for(j=0; j<4; j++){
			tmp[j]=12*i+j;
			matriks[i]=tmp;
			cout << matriks[i][j] << " ";
		}
		cout << endl;
	}
	manipulasiVector(matriks);
	for(i=0; i<3; i++){
		for(j=0; j<4; j++){
			cout << matriks[i][j] << " ";
		}
		cout << endl;
	}
	return 0;
}
 
 
void manipulasiVector(vector<vector<double> > &v){
	int i=0,j=0;
	vector<double> tmp(10);
	for(i=0; i<3; i++){
		for(j=0; j<4; j++){
			tmp[j]= 8+i+j;
			v[i] = tmp;
		}
		cout << endl;
	}
}

Mengembalikan Pointer Array 2D dari Fungsi

Ketika kita membuat sebuah variabel yang diinisialisasi dengan pointer, variabel tersebut bisa dilewatkan ke dalam sebuah fungsi dan dikembalikan dalam bentuk alamat (pointer). Ketika berpindah-pindah dari satu fungsi ke fungsi lain, nilai pointer akan berubah secara dinamik (pass by address). Namun, saya mencoba membuat sebuah array 2D dan ingin melewatkan alamat pointer tersebut ke sebuah fungsi, yang nantinya fungsi tersebut akan mengganti isi array kemudian mengembalikan alamat pointer array tersebut. Sayang sekali banyak artikel yang mengatakan bahwa kita tidak bisa melewatkan pointer array 2D melalui fungsi yang telah didefinisikan.

Meskipun pointer array tidak bisa dilewatkan melalui fungsi, namun fungsi masih tetap bisa mengembalikan pointer array 2D. Jadi array 2D dibentuk di dalam fungsi, lalu alamatnya dikembalikan dan selanjutnya bisa dimasukkan ke dalam pointer lain.

Kode di bawah ini adalah cara yang saya temukan di internet. Mungkin ada cara lain, tapi saya belum mengetahuinya 🙂

#include <iostream>
using namespace std;
 
int** editArray();
int main(){
	int i=0, j=0;
	int **arr;
	arr=editArray();
	for(i=0; i<2; i++){
		for(j=0; j<4; j++){
			cout << arr[i][j] << " ";
		}
		cout << endl;
	}
	//system("pause");
}
 
int** editArray(){
	int** tmp;
	tmp = 0;
	tmp = new int*[100]; // 100 baris -> tmp [100][x];
	int i=0;
 
	/* Untuk kemudahan, 2 buah contoh cara memasukkan nilai pada variable
		pada array 'tmp' diberikan dalam 1 fungsi. 
		Silahkan berikan komentar pada baris-baris pada salah satu contoh
		agar 1 cara saja yang dipakai.
	*/
 
	/* Contoh 1: memasukkan nilai awal */
	for(i=0; i<2; i++){
		tmp[i] = new int[4];	// 4 kolom -> tmp[100][4]
		tmp[i][0] = (i+2)*1;
		tmp[i][1] = (i+2)*2;
		tmp[i][2] = (i+2)*3;
		tmp[i][3] = (i+2)*4;
	}
 
	/* Contoh 2: mengedit array */
	tmp[0] = new int[4];
	tmp[0][0]=2;
	tmp[0][1]=3;
	tmp[0][2]=4;
	tmp[0][3]=5;
 
	tmp[1] = new int[4];
	tmp[1][0]=20;
	tmp[1][1]=30;
	tmp[1][2]=40;
	tmp[1][3]=50;
 
    return tmp;
}

Melewatkan Fungsi sebagai Parameter Fungsi dalam C++

Bukan hanya variabel yang bisa dilewatkan pada sebuah fungsi dalam pemrograman C/C++. Fungsi juga bisa dilewatkan sebagai parameter. Konsepnya hampir sama saja, namun dengan sedikit tambahan syntax agar fungsi bisa dilewatkan dan berhasil dijalankan. Umumnya, pemanggilan fungsi dilakukan untuk menjalankan fungsi di dalam fungsi. Lebih jelasnya, ketika program memanggil sebuah fungsi, maka kita melewatkan sebuah fungsi sebagai parameter untuk kemudian dijalankan oleh fungsi pertama tadi.

Untuk bisa mendemonstrasikan contoh bagaimana melewatkan fungsi sebagai parameter, dibutuhkan paling tidak 2 fungsi selain fungsi utama (main). Dalam contoh di bawah ini, kita menggunakan 2 fungsi: trigger() dan sum(). Fungsi trigger() akan dipanggil di program utama. Fungsi sum() akan dilewatkan sebagai parameter fungsi trigger() untuk kemudian dijalankan di dalam fungsi trigger() itu sendiri.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
 
int trigger(int (*)(int));
int sum(int end);
 
int main(){
	cout << trigger(&sum) << endl;
	return 0;
}
 
int trigger(int (*f)(int)){
	int end=50;
	return (*f)(end);
 
}
int sum(int end){
	int i, sum=0;
	for(i=0; i<end; i++){
		sum += i;
	}
	return sum;
}

Untuk melewatkan fungsi sebagai parameter, kita harus menuliskan tipe kembalian fungsi, lalu pointer yang menunjuk ke nama fungsi, dan tipe parameter fungsi.

4
int trigger(int (*)(int));

Bentuk int (*)(int) merupakan bentuk yang sama dengan nama fungsi yang akan dipanggil:

int sum(int end);

Untuk deklarasi fungsi tersebut, kita menggunakan pointer agar bisa memanggil fungsi yang dimaksud.

int trigger(int (*f)(int)){
	int end=50;
	return (*f)(end); // dalam kasus ini, artinya sama dengan -> return sum(end);
 
}

Untuk menggunakan fungsi trigger() dalam program utama, kita melewatkan referensi fungsi sum() di dalam parameter fungsi trigger.

trigger(&sum)

Bagaimana jika ingin melewatkan fungsi beserta dengan parameternya? Kita tinggal menambah parameter lain di dalam fungsi yang memanggil tadi. Pada kasus di atas, variabel end dideklarasikan di dalam fungsi trigger. Dalam contoh di bawah ini, variabel end akan dideklarasikan di dalam fungsi main dan akan dilewatkan dalam fungsi trigger.

#include <iostream>
using namespace std;
 
int trigger(int (*)(int), int);
int sum(int end);
 
int main(){
	int end = 50;
	cout << trigger(&sum, end) << endl;
	return 0;
}
 
int trigger(int (*f)(int), int end){
	return (*f)(end);	
}
int sum(int end){
	int i, sum=0;
	for(i=0; i<end; i++){
		sum += i;
	}
	return sum;
}

Secara teknis, kita tidak bisa melewatkan parameter bersamaan dengan nama fungsi yang dipanggil, contohnya:

trigger(&sum(4)); // tidak akan berhasil dicompile

Oleh karena itulah, parameter fungsi yang akan dilewatkan diberikan sebagai parameter tambahan seperti potongan kode di bawah ini.

int trigger(int (*f)(int), int end){
	return (*f)(end);	
}
trigger(&sum, 5);

Pointer dan Reference

Beberapa hari ini saya kembali belajar tentang bahasa pemrograman C++ namun dengan cakupan yang lebih luas dan mendalam. Dari dulu saya berusaha mencoba membaca source code C++ dalam proyek mini seseorang, namun tetap saja dengan pemahaman C++ yang pas-pasan malah membuat saya tidak betah berlama-lama dengan bahasa yang satu ini. Syukurlah dengan pembelajaran yang intensif saya sedikit bisa mengerti konsep dalam bahasa C++ yang sebelumnya tidak saya pahami.

Agar lebih konkrit, saya ingin membawakan sedikit pengetahuan yang saya peroleh mengenai pointer ke dalam sebuah artikel.

Dilihat dari datanya, sebuah variabel sebenarnya menyimpan 2 buah nilai: alamat variabel itu dan nilai variabel itu. Untuk bisa mengakses alamat ini, ada 2 cara yang bisa dipakai: menggunakan referensi atau menggunakan pointer.

Contoh di bawah ini adalah menggunakan referensi. Alamat variabel bisa diakses dengan menggunakan tanda & di depaan variabel yang ingin dilihat. Nilai x bisa berubah setiap saat namun alamatnya tidak akan berubah. Ibaratnya penghuni rumah mungkin akan berganti orang, namun sebuah rumah di sebuah perkampungan akan memiliki alamat yang tetap.

1
2
3
4
5
6
int x = 12;
cout << "Nilai:" << x << endl; //mengakses nilai x=12
cout << "Alamat:" << &x << endl; //mengakses alamat -> A
x = 14;
cout << "Nilai:" << x << endl; //mengakses nilai, x=14
cout << "Alamat:" << &x << endl; //mengakses alamat -> A (alamat tetap)

Potongan kode di bawah ini adalah cara untuk mendeklarasikan sebuah pointer p yang menunjuk ke variabel x. Ada 2 cara untuk mendeklarasikan pointer: pertama adalah dengan mendeklarasikan langsung pada saat inisialisasi (contoh pada baris 2) dan cara lain adalah mendeklarasikan kemudian (contoh baris 3).

1
2
3
4
5
6
7
int x = 12;  // inisialisasi variabel x=12
int *p = &x; // alamat dari x disimpan ke dalam pointer p
p = &x;  // alamat dari x disimpan ke dalam pointer p, fungsinya sama dengan baris 2
*p=13; // nilai berubah menjadi *p=13 dan x=13, namun alamat nya tetap, yaitu yang berasal dari x
 
int y = 15;  // deklarasi variabel y
p = &y;  // alamat pointer p berubah ke alamat y, nilai *p=15

Dalam potongan kode di atas, p adalah sebuah variabel yang menyimpan alamat saja. Memang itulah kegunaan pointer, yaitu menyimpan sebuah alamat, sedangkan nilainya bergantung dari nilai dari alamat yang disimpannya. Ibaratnya, sebuah buku kontak hanya bisa menyimpan alamat rumah saja, namun jika kita pergi ke alamat rumah tersebut, bisa saja penghuninya berbeda tergantung siapa yang memiliki rumah tersebut.

Program Integrasi Numerik dalam C

Untuk menghitung luas suatu daerah di bawah fungsi, yang biasa kita lakukan adalah menghitung nilai integral di bawah fungsi tersebut dengan batas atas dan batas bawah yang kita beriknan. Namun, komputer tidak mengenal integral. Komputer hanya mengenal operasi bilangan yang dasar seperti tambah, kali, bagi, dll.

Metode integrasi numerik memberikan cara pada kita untuk menghitung nilai integral tersebut dengan perhitungan biasa, tanpa perlu tahu apa itu integral tentunya. Tulisan dari wikipedia tentang integrasi numerik memberikan sedikit penjelasan tentang bagaimana integrasi numerik dikerjakan. Ada banyak metode dalam integrasi numerik, yang akan saya berikan di sini adalah metode jumlah atas dan jumlah bawah, metode simpson 1/3, metode trapezoidal, dan metode gauss quadrature. Contoh di bawah ini adalah program untuk menghitung nilai :

\displaystyle \int_0^1\! e^x.sin(x)\, dx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
    coder       : duken marga
    blog        : http://duken.info
    description : integrasi numerik menggunakan motoda trapezoidal, 
              gauss quadrature, simpson, dan jumlah atas dan bawah
*/
 
#include <stdio.h>
#include <math.h>
 
float jumlah_atas(float, float, float);
float jumlah_bawah(float, float, float);
float trapezoidal(float, float, float);
float simpson(float, float, float);
float gauss_quadrature(float, float);
 
float f(float);
 
int main(){
    float batas_atas;
    float batas_bawah;
    int jumlah_segmen = 20;
 
    printf("Masukkan batas atas : ");
    scanf("%f", &batas_atas);
    printf("Masukkan batas bawah : ");
    scanf("%f", &batas_bawah);
    printf("Masukkan jumlah segmen : ");
    scanf("%d", &jumlah_segmen);
 
    printf("Jumlah atas  : %20.18f \n",
        jumlah_atas(batas_bawah, batas_atas, jumlah_segmen));
    printf("Jumlah bawah : %20.18f \n",
        jumlah_bawah(batas_bawah, batas_atas, jumlah_segmen));
    printf("Rata-rata    : %20.18f \n\n",
        ( jumlah_atas(batas_bawah, batas_atas, jumlah_segmen)
        + jumlah_bawah(batas_bawah, batas_atas, jumlah_segmen) 
        ) /2
        );
    printf("Jumlah trapezoidal  : %20.18f \n",
        trapezoidal(batas_bawah, batas_atas, jumlah_segmen));
    printf("Jumlah simpson  : %20.18f \n",
        simpson(batas_bawah, batas_atas, jumlah_segmen));
    printf("Jumlah gauss_quadrature  : %20.18f \n",
        gauss_quadrature(batas_bawah, batas_atas));
}
 
/*definisi fungsi yang akan dicari nilainya*/
float f(float x){
    return exp(x)*sin(x);
}
 
/* mencari nilai luas dengan metode jumlah atas */
float jumlah_atas(float bwh, float ats, float jlh){
    float i, luas = 0;
    float node1, node2;
    float y_node1, y_node2, y;
    float lebar_segmen = (ats - bwh) / jlh;
    for(i = bwh; i < ats; i += lebar_segmen){
        node1 = i;
        node2 = i + lebar_segmen;
        y_node1 = f(node1);
        y_node2 = f(node2);
        if(y_node1 < y_node2)
            y = y_node1;
        else
            y = y_node2;
 
        luas += lebar_segmen * y;
    }
    return luas;
}
 
/* mencari nilai luas dengan metode jumlah bawah */
float jumlah_bawah(float bwh, float ats, float jlh){
    float i, luas = 0;
    float node1, node2;
    float y_node1, y_node2, y;
    float lebar_segmen = (ats - bwh) / jlh;
    for(i = bwh; i < ats; i += lebar_segmen){
        node1 = i;
        node2 = i + lebar_segmen;
        y_node1 = f(node1);
        y_node2 = f(node2);
        if(y_node1 > y_node2)
            y = y_node1;
        else
            y = y_node2;
 
        luas += lebar_segmen * y;
    }
    return luas;
}
 
/* mencari nilai luas dengan metode trapezoidal */
float trapezoidal(float bwh, float ats, float jlh){
    int i;
    float luas = 0;
    float lebar_segmen = (ats - bwh) / jlh;
    float node, y;
 
    luas = 0.5 * lebar_segmen * (f(ats) + f(bwh));
    for(i = 1; i < jlh; i++){
        node = bwh + i * lebar_segmen;
        y = f(node);
        luas += lebar_segmen * y;
    }
    return luas;
}
 
/* mencari nilai luas dengan metode simpson 1/3 */
float simpson(float bwh, float ats, float jlh){
    int i;
    float luas = 0;
    float lebar_segmen = (ats - bwh) / jlh;
    float node, y;
 
    luas = lebar_segmen * (f(ats) + f(bwh)) / 3;
    for(i = 1; i < jlh; i++){
        node = bwh + i * lebar_segmen;
        y = f(node);
        if(i%2 == 1)
            y *= 4;
        else
            y *= 2;
        luas += lebar_segmen * y / 3;
    }
    return luas;
}
 
/* mencari nilai luas dengan metode gauss quadrature */
/* menggunakan orde 3, bisa diganti dengan orde lain */
/* yang perlu diganti : orde, weight[], x[] */
float gauss_quadrature(float bwh, float ats){
    int i;
    int orde = 3;
    float luas = 0;
    float t;
    float weight[] = { (float) 8/9, (float)5/9, (float)5/9 };
    float x[] = { 0, sqrt((float) 3/5), -sqrt((float) 3/5) };
 
    for(i = 0; i < orde; i++){
        t = ((ats - bwh) * x[i] + (ats + bwh)) / 2 ;
        luas += weight[i] * f(t);
    }
    luas *= (ats - bwh) / 2;
    return luas;
}

Metode Secant

Referensi : http://en.wikipedia.org/wiki/Secant_method

Sama seperti metode newton-raphson, metode secant adalah salah satu dari metode numerik untuk mencari solusi persamaan dari sebuah fungsi. Referensi di atas sangat jelas dan bisa menerangkan lebih banyak daripada tulisan di sini.

Saya hanya ingin memberi contoh program dalam C.

\displaystyle x_n=x_{n-1}-f(x_{n-1})\dfrac{x_{n-1}-x_{n-2}}{f(x_{n-1})-f(x_{n-2})}

Fungsi yang digunakan dalam contoh ini adalah f(x)  = x^2 + x - cos(x), jika ingin mencoba dengan fungsi lain, tinggal mengganti fungsi f(x) dalam program di bawah ini.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
 * program untuk mencari solusi persamaan suatu fungsi
 * dengan menggunakan metode secant
 * coder : duken
*/
 
#include <stdio.h>
#include <math.h>
#define PHI 3.141592654
#define TOLERANCE 10E-10
 
float f(float x);
int main()
{
    float x1, x2, x3;
    int i, loop;
 
    printf("Masukkan nilai bilangan inisiasi pertama : ");
    scanf("%f", &x1);
 
    printf("Masukkan nilai bilangan inisiasi kedua : ");
    scanf("%f", &x2);
 
    printf("Masukkan jumlah maksimum perulangan : ");
    scanf("%d", &loop);
 
    printf(" x1 \t  x2 \t   x3\n ");
 
    for(i = 0; i < loop; i++){
        x3 = x2 - f(x2) * (x1 - x2) / (f(x1) - f(x2));
        printf("%f %f %f\n ", x1, x2, x3);
        if( x2 - x3 < TOLERANCE){
            break;
        }
        x1 = x2;
        x2 = x3;
    }
    printf("Solusi persamaan adalah : %20.10f", x3);
}
 
/*
 * 
 * f(x)  = x^2 + x - cos(x)
*/
float f(float x){
    return x*x + x - cos(x * PHI / 180);
}

Metode Newton-Raphson

Referensi : http://en.wikipedia.org/wiki/Newton_Raphson

Referensi di atas cukup lengkap dalam menerangkan apa itu metode Newton-Raphson. Singkatnya, metode Newton Rapshon adalah metode yang digunakan untuk mencari solusi sebuh persamaan menggunakan metode numerik.

\displaystyle x_{n+1} = x_n - \dfrac{f(x_n)}{f'(x_n)}.\,\!

dengan f(x) adalah fungsi yang ingin kita cari solusinya, f'(x) adalah turunan dari fungsi f(x), dan n adalah bilangan asli mulai dari 1. Rumus di atas cukup menggambarkan secara sederhana apa itu metode Newton-Raphson.

Contoh sederhana, kita ingin mencari solusi persamaan: x^2 + x = cos(x)

Fungsi di atas kita ubah menjadi fungsi: f(x) = x^2 + x - cos(x)

Maka turunan dari fungsi di atas adalah f'(x) = 2x + 1 + sin(x)


x_1 = x_0 - \dfrac{f(x_0)}{f'(x_0)}
x_2  = x_1 - \dfrac{f(x_1)}{f'(x_1)}
x_3  = x_2 - \dfrac{f(x_2)}{f'(x_2)} \vdots
x_4  =  \vdots
x_5  =  \vdots

untuk n = 0, maka \displaystyle  x_1 = x_0 - \frac{(x_0^2 + x_0 - cos(x_0)}{2x_0 + 1 + sin(x_0))} dengan nilai awal x_0 = 10 dan akan menghasilkan nilai x_1.

untuk n = 1, maka \displaystyle x_2 = x_1 - \frac{(x_1^2 + x_1 - cos(x_1)}{2x_1 + 1 + sin(x_1)})

Demikian seterusnya cara di atas kita ulangi hingga mendapatkan nilai x_n yang konstan. Biasanya dengan 5 kali perulangan, sudah bisa mendapatkan nilai x_n yang konstan. Nilai akhir x_n ini adalah solusi dari persamaan f(x) kita tadi.

Contoh program dalam c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* 
 * program untuk mencari solusi persamaan 
 * dari fungsi x^2 + x = cos(x)
 * 
 * f(x)  = x^2 + x - cos(x)
 * f(x)' = 2x + 1 + sin(x)
*/
 
#include <stdio.h>
#include <math.h>
#define PHI 3.141592654
 
int main()
{
    int i, loop;
    float init, x;
 
    printf("Masukkan bilangan inisiasi : ");
    scanf("%f", &init);
    x = init;
    printf("Masukkan banyak pengulangan : ");
    scanf("%d", &loop);
 
    for(i = 0; i < loop ; i++){
        x = x - ((x*x + x - cos(x * PHI / 180)) / (2*x + 1 + sin(x * PHI / 180)));
        printf("%f\n", x);
    }
 
    printf("Solusi persamaan x^2 + x = cos(x) adalah x = %f", x);
 
}

Contoh program dalam fortran:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
! program untuk mencari solusi persamaan 
! dari fungsi x^2 + x = cos(x)
 
! f(x)  = x^2 + x - cos(x)
! f(x)' = 2x + 1 + sin(x)
 
 
program newtonRaphson
    integer::i, loop
    real::init, x
    real, parameter::PHI = 3.141592654
 
    write(*, "(A)", advance="NO"), "Masukkan bilangan inisiasi : "
    read*, init
    write(*, "(A)", advance="NO"), "Masukkan banyak looping : "
    read*, loop
 
    x = init
 
    do i = 0, loop
        x = x - ((x**2 + x - cos(x * PHI / 180)) / (2*x + 1 + sin(x * PHI / 180)))
        print*, x
    end do
 
    print*, "Solusi persamaan x^2 + x = cos(x) adalah x = ", x
end program newtonRaphson

Mencari Nilai Akar dengan Menggunakan Metode Babylon

Dari dulu saya selalu bingung cara mencari nilai suatu akar dengan pasti. Setiap kalkulator scientific bisa “menebak” nilai dari suatu akar bilangan. Sampai suatu saat di kelas TPB di kampus dalam mata kuliah kalkulus, saya mengenal lebih dalam apa itu limit. Kita bisa menggunakan limit untuk mencari pendekatan suatu nilai dari fungsi yang kita cari termasuk mencari nilai dari fungsi akar. Dasar saya emang bodoh, saya tidak begitu memahami prinsip limit ini.

Pada sebuah buku pemrograman, saya menemukan algoritma bagaimana mencari nilai akar dengan menggunakan fungsi Babylon. Fungsi ini menggunakan looping atau perulangan untuk mendapatkan nilai yang lebih presis. Syarat agar perhitungan kita berhenti dari perulangan, kita harus menetapkan suatu batasan atau nilai toleransi.

Algoritma Babylon bisa dituliskan seperti ini:

  1. Ambil nilai yang akan dicari nilai akarnya, misalkan bilangan ini adalah x.
  2. Kita akan menggunakan variabel lain yaitu y. Jika x>2, maka nilai y kita set nilainya menjadi x/2, namun jika 0<x<=2, maka kita set nilai y=1
  3. Cari nilai y baru yang diperoleh lewat perhitungan y = { (y + x/y)/2 }. Ingat nilai y yang di sebelah kiri adalah nilai y yang ingin kita cari, sedangkan nilai y yang di sebelah kanan adalah nilai y yang kita peroleh dari langkah 2 di atas.
  4. Tentukan batas toleransi, misalnya Epsilon E = 5×10-15.
  5. Jika E < | y*y – x |, ulang dan kembali ke langkah 3 dengan nilai y adalah nilai y yang terakhir. Jika E > | y*y -x |, ikuti langkah 6.
  6. Nilai akar x yang kita cari adalah nilai y yang tadi kita peroleh.

Contohnya kita ingin mencari nilai akar 5.

  1. Nilai x = 5.
  2. x > 2, maka nilai y=x/2 atau y = 2,5
  3. y = { (y + x/y)/2 } = (2,5 + 5/2,5)/2 = 2,25
  4. E = 5×10-8
  5. y*y – x = 2,25*2,25 – 5 = 0,0625
  6. x – y*y = 5 – 2,25*2,25 = -0,0625
  7. Kita bandingkan nilai Epsilon dengan hasil di atas. E =5×10-8 lebih kecil dari salah satu nilai di atas. 5×10-8 < -0,0625, jadi kita ulangi lagi langkahnya.
  8. y = { (y + x/y)/2 } = (2,25 + 5/2,25)/2 = 2,2361..
  9. E = 5×10-15
  10. y*y – x = 2,2361*2,361 – 5 = 1,929×10-4
  11. x – y*y = 5 – 2,2361*2,361 = -1,929×10-4
  12. Kita bandingkan nilai Epsilon dengan hasil di atas. E =5×10-8 lebih kecil dari salah satu nilai di atas. 5×10-8 < 1,929×10-4, jadi kita ulangi lagi langkahnya.
  13. y = { (y + x/y)/2 } = (2,2361 + 5/2,2361)/2 = 2,236067978..
  14. E = 5×10-15
  15. y*y – x = 2,23606*2,3606 – 5 = 1,88×10-9
  16. x – y*y = 5 – 2,23606*2,3606 = -1,88×10-9
  17. Kita bandingkan nilai Epsilon dengan hasil di atas. E = 5×10-8 lebih besar dari salah satu nilai di atas. 5×10-8 > 1,88×10-9. Karena syarat E > | y*y -x | sudah terpenuhi, maka perulangan dihentikan.

Nilai akhir y adalah hasil akar dari nilai x. Jadi akar 5 adalah 2,236067978. Tentunya nilai ini adalah pendekatan. Jika teman-teman menghitung nilai akar 5 langsung dari kalkulator, nilainya (hampir) sama dengan nilai dengan menggunakan cara Babylon. Untuk mendapatkan nilai yang lebih presisi, kita bisa menggunakan nilai Epsilon yang lebih rendah dari nilai di atas, namun dengan nilai di atas pun, saya bisa mendapatkan kepresisian 9 angka di belakang koma dengan 2 kali perulangan. Jangan-jangan hasil perhitungan akar dari kalkulator yang sering kita pakai, itu menggunakan cara Babylon ya 😀

Untuk programnya, bisa menggunakan C++ atau bahasa lain. Contoh di bawah ini adalah program mencari akar dengan nilai epsilon 5×10-15.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
	compile with g++ (MinGW)
	ex : g++ square.cpp -o square
*/
 
#include <iostream>
#include <iomanip>
using namespace std;
 
/*deklarasi fungsi babylon*/
double	babylon(double);
 
/*fungsi utama*/
int main()
{
	double X;
	cout << "Input bilangan yang akan dicari akarnya : ";
	cin >> X;
	cout << "==============================\n";
	cout << "\t Y \t Y*Y \n";
	cout << "==============================\n";
 
	/*panggil fungsi babylon dengan parameter nilai akar yang dicari*/
	double y = babylon(X);
	cout << "==============================\n";
 
	/*set nilai kepresisian jika perlu*/
	cout << "Akar " << X << " adalah : " << setprecision(20) <<y << endl;
 
	return 0;
}
 
/*detail fungsi babylon*/
double babylon(double x){
	/*
		batas nilai toleransi (epsilon), atau epsilon
		usahakan nilai ini jangan terlalu besar atau terlalu kecil
	*/
	const double TOLERANSI = 5e-15;
	if(x < 0)
		return 0.0;
 
	/*jika
		x > 2 -> y = x/2
		x <= 2 -> y = 1
	*/
	double y = (x > 2 ? x/2 : 1);
 
	/*
		ulangi sampai syarat dipenuhi : epsilon > | y*y - x |
		jika sudah memenuhi syarat, maka nilai akar adalah nilai y
	*/
	do{
		y = (y + x/y) / 2;
		cout << setw(10) << y << setw(12) << y*y << "\n";
	}while(x > y*y + TOLERANSI || y*y > x + TOLERANSI);
	return y;
}