13. Angka dan matematika
Angka di Go terbagi dua jenis utama, bisa melakukan aritmetika biasa, dan bisa dipakai bersama package standard library untuk bantuan tambahan. Bab ini membahas apa yang kamu butuhkan untuk logika game: pembulatan, angka acak, matematika dasar, dan berpindah di antara kedua jenis angka.
Integer dan float
Go punya dua tipe angka yang umum:
- int. Bilangan bulat tanpa bagian desimal:
0,7,-42. - float64. Bilangan dengan titik desimal:
3.14,0.5,-1.0.
Di Go kamu harus memperhatikan mana yang mana. 7 adalah
int, 7.0 adalah float64, dan kedua jenis ini tidak bisa
dicampur dalam variabel, seperti yang akan kamu lihat di bawah.
%T memberi tahu mana yang kamu punya:
fmt.Printf("%T\n", 7) // int
fmt.Printf("%T\n", 7.0) // float64
fmt.Printf("%T\n", 3.14) // float64Aritmetika
Operator yang sudah kamu kenal semuanya ada di sini:
| Operator | Nama | Contoh | Hasil |
|---|---|---|---|
+ |
penjumlahan | 3 + 2 |
5 |
- |
pengurangan | 7 - 4 |
3 |
* |
perkalian | 6 * 7 |
42 |
/ |
pembagian, bilangan bulat | 7 / 2 |
3 |
/ |
pembagian, desimal | 7.0 / 2 |
3.5 |
% |
modulo (sisa bagi) | 7 % 3 |
1 |
Dua di antaranya perlu dilihat lebih dekat:
Pembagian / tergantung pada tipenya.
Membagi dua bilangan bulat menghasilkan bilangan bulat, dan semua yang
ada setelah titik desimal dibuang: 7 / 2 adalah
3. Pembuangannya menuju nol, jadi -7 / 2
adalah -3. Kalau ada desimal dalam perhitungan, hasilnya
desimal: 7.0 / 2 adalah 3.5.
Modulo % adalah sisa setelah pembagian
bilangan bulat. 7 % 3 adalah 1 karena
7 = 2 * 3 + 1. Ini cara standar untuk bertanya "apakah
angka ini genap?" — n % 2 bernilai 0 untuk
bilangan genap dan 1 untuk bilangan ganjil positif.
Operator ini hanya berlaku untuk bilangan bulat.
fmt.Println(7 / 2) // 3
fmt.Println(7.0 / 2) // 3.5
fmt.Println(7 % 2) // 1Go tidak punya operator pangkat. ^ memang ada, tapi
fungsinya sama sekali lain: 2 ^ 8 bisa dikompilasi,
berjalan, dan menghasilkan 10. Untuk memangkatkan angka,
gunakan math.Pow dari bagian berikutnya.
Buka exercises/13/01-arithmetic.go. Tebak setiap hasil
yang tercetak sebelum menjalankannya, lalu jalankan dan periksa.
Package math
Package math di Go punya alat bantu yang paling sering
kamu pakai. Impor di samping fmt:
import (
"fmt"
"math"
)| Fungsi | Kegunaannya |
|---|---|
math.Floor(x) |
Nilai bulat terbesar yang tidak lebih dari x.
Floor(3.7) adalah 3. |
math.Ceil(x) |
Nilai bulat terkecil yang tidak kurang dari x.
Ceil(3.2) adalah 4. |
math.Abs(x) |
Nilai mutlak. Abs(-5) adalah 5. |
math.Sqrt(x) |
Akar kuadrat. |
math.Pow(x, y) |
x pangkat y. Pow(2, 8) adalah
256. |
min(a, b) |
Yang lebih kecil dari dua angka. Bawaan, tanpa import. |
max(a, b) |
Yang lebih besar dari dua angka. Bawaan, tanpa import. |
math.Pi |
Konstanta 3.1415... (sebuah nilai, bukan fungsi). |
Panggil seperti fungsi lainnya:
fmt.Println(math.Floor(3.7)) // 3
fmt.Println(math.Ceil(3.2)) // 4
fmt.Println(math.Sqrt(16)) // 4
fmt.Println(min(7, 3)) // 3
fmt.Println(math.Pi) // 3.141592653589793Panggilan-panggilan ini, dan sisa isi tabel, ada di
exercises/13/02-math-package.go.
Fungsi-fungsi math menerima dan mengembalikan
float64, meskipun hasilnya tercetak sebagai 3.
fmt.Println tidak menampilkan titik desimal kalau float64
tidak punya angka di belakangnya. min dan max
sudah bawaan Go dan selalu tersedia; keduanya mengembalikan tipe yang
sama dengan yang kamu berikan.
Menampilkan desimal dengan
%.2f
fmt.Println mencetak float64 dengan caranya sendiri.
Untuk jumlah desimal yang tetap, gunakan penanda %.2f di
fmt.Printf. Angka 2 adalah jumlah desimal yang
ditampilkan, dan nilainya dibulatkan agar pas:
price := 3.14159
fmt.Printf("Price: %.2f\n", price) // Price: 3.14Gunakan untuk apa pun yang dibaca orang.
fmt.Println(1000000.0) mencetak 1e+06, dan
0.1 + 0.2, kalau disimpan dalam variabel, mencetak
0.30000000000000004, karena komputer hanya menyimpan
desimal secara mendekati. %.2f menampilkannya sebagai
1000000.00 dan 0.30.
Angka acak
Angka acak ada di package math/rand. Impor di samping
fmt, dan panggil dengan bagian terakhir namanya,
rand:
import (
"fmt"
"math/rand"
)rand.Float64()memberikan float64 dari0.0sampai, tapi tidak termasuk,1.0.rand.Intn(n)memberikan bilangan bulat dari0sampain-1. Untuk dadu enam sisi, tambahkan satu:rand.Intn(6) + 1.
fmt.Println(rand.Float64()) // misalnya 0.6238...
fmt.Println(rand.Intn(6) + 1) // misalnya 4
fmt.Println(rand.Intn(100) + 1) // misalnya 73Baris-baris ini ada di exercises/13/03-random.go.
rand.Intn(6) tidak pernah memberikan 6.
Hasilnya 0, 1, 2, 3,
4, dan 5, jadi + 1 itulah yang
membuatnya menjadi dadu. Lupa menambahkannya adalah bug yang umum, dan
mudah terlewat, karena hasilnya tetap terlihat acak.
Mencampur int dan float64
Di sini Go lebih ketat daripada matematika. Dua variabel dengan tipe angka yang berbeda tidak bisa digabungkan.
Buka exercises/13/05-mixed-types.go. File ini tidak bisa
dikompilasi:
# command-line-arguments
exercises\13\05-mixed-types.go:12:14: invalid operation: level * bonus (mismatched types int and float64)
level adalah int dan bonus adalah float64.
Perbaiki baris itu dengan konversi yang dijelaskan di bawah.
Konversi membuat nilai baru dengan tipe yang kamu sebutkan. Tulis tipenya seperti fungsi:
level := 7
bonus := 1.5
fmt.Println(float64(level) * bonus) // 10.5
total := 7
count := 2
fmt.Println(total / count) // 3
fmt.Println(float64(total) / float64(count)) // 3.5
price := 3.99
fmt.Println(int(price)) // 3Go mewajibkan kamu menulis ini supaya tidak ada yang berubah tipe
tanpa sengaja. Baris terakhir menunjukkan mengapa itu penting:
int(price) membuang bagian desimalnya. Nilainya tidak
dibulatkan, jadi 3.99 menjadi 3. Baris-baris
ini ada di exercises/13/04-conversions.go.
Angka yang ditulis langsung di dalam kode, seperti 2
atau 1.5, lebih fleksibel daripada variabel. Go menyebutnya
konstanta, dan konstanta mengambil tipe angka apa pun
yang dibutuhkan perhitungan selama nilainya muat. Jadi
bonus * 2 bisa berjalan meskipun bonus adalah
float64 dan 2 terlihat seperti int.
level * 1.5 tidak bisa, karena 1.5 tidak muat
dalam int:
1.5 (untyped float constant) truncated to int
PR
Starter PR yang membutuhkan package lain menyebutkannya di komentar paling atas. Ingat bahwa ekstensi Go untuk VS Code mungkin menambahkan baris import untukmu saat kamu menyimpan file.
Soal 1 — Luas persegi panjang
Buka exercises/13/homework/01-rectangle-area.go. Dua
variabel menyimpan width dan height sebuah
persegi panjang. Hitung luasnya dan cetak dengan label, misalnya
Area: 24.
Soal 2 — Floor dan ceil
Buka exercises/13/homework/02-floor-and-ceil.go. Sebuah
variabel menyimpan float64 3.7. Cetak apa adanya, setelah
math.Floor, dan setelah math.Ceil. Tambahkan
satu baris komentar yang menjelaskan perbedaan floor dan ceil.
Soal 3 — Lempar dua dadu
Buka exercises/13/homework/03-roll-two-dice.go. "Lempar"
dua dadu enam sisi dan cetak hasilnya seperti ini:
Die 1: 4
Die 2: 6
Total: 10
Gunakan rand.Intn untuk lemparannya. Lempar setiap dadu
secara terpisah supaya kedua nilainya tidak saling bergantung.
Tantangan — Hipotenusa
Buka exercises/13/homework/04-hypotenuse.go. Dua
variabel int menyimpan dua sisi pendek segitiga siku-siku
(a dan b). Hitung dan cetak hipotenusa
c dengan teorema Pythagoras: c adalah akar
kuadrat dari a*a + b*b.
math.Sqrt menerima float64, jadi kamu butuh konversi.
Cetak ketiga nilai dengan label. Tampilkan hipotenusa dengan dua angka
desimal menggunakan %.2f.
Stuck atau sudah selesai? Buka halaman solusi PR.