Angka di program CLI sering perlu ditampilkan dengan format tertentu — pemisah ribuan agar mudah dibaca, padding dengan nol untuk ID berstruktur, tanda plus eksplisit untuk perbedaan positif/negatif, atau presisi desimal yang konsisten. Kotlin mewarisi seluruh mekanisme ini dari java.util.Formatter melalui String.format(). Pada chapter ini kita akan membahas flag-flag yang paling relevan untuk angka: koma (grup), nol (padding), plus (tanda positif), dan kombinasi precision dengan width.
Pemisah Grup dengan Flag Koma #
Flag koma , menambahkan pemisah grup sesuai locale default JVM:
val besar = 1234567.89
println("Tanpa grup: ${"%.2f".format(besar)}") // 1234567.89
println("Dengan grup: ${"%,.2f".format(besar)}") // 1,234,567.89Pemisah grup default di locale US adalah koma , untuk ribuan dan titik . untuk desimal. Di locale Jerman, perannya tertukar: titik untuk ribuan dan koma untuk desimal. Topik locale akan kita bahas tuntas pada chapter Locale dan Format Angka.
Padding dengan Nol #
Flag 0 diikuti width memaksa padding dengan karakter nol di depan angka:
val kecil = 42
println("%5d".format(kecil)) // " 42" (spasi)
println("%05d".format(kecil)) // "00042" (nol)
println("%08d".format(kecil)) // "00000042" (lebih lebar)Padding dengan nol berguna untuk ID berstruktur seperti nomor pesanan (ORD-00042) atau kode pos (00123). Tanpa flag 0, padding default menggunakan spasi yang sulit terlihat di output.
Contoh Numeric Formatting #
fun main() {
val besar = 1234567.89
println("Tanpa grup: ${"%.2f".format(besar)}")
println("Dengan grup: ${"%,.2f".format(besar)}")
val kecil = 42
println("Pad spasi: ${"%5d".format(kecil)}")
println("Pad nol: ${"%05d".format(kecil)}")
println("Pad nol lebar 8: ${"%08d".format(kecil)}")
val positif = 3.14
val negatif = -3.14
println("Positif: ${"%+.2f".format(positif)}")
println("Negatif: ${"%+.2f".format(negatif)}")
println("Tanpa plus positif: ${"%.2f".format(positif)}")
val persen = 0.875
println("Persentase: ${"%.1f%%".format(persen * 100)}")
val hex = 255
println("Pad hex: ${"%08x".format(hex)}")
println("Hex upper: ${"%08X".format(hex)}")
val pi = 3.141592653589793
println("Pi 2 desimal: ${"%.2f".format(pi)}")
println("Pi 4 desimal: ${"%.4f".format(pi)}")
println("Pi 8 desimal: ${"%.8f".format(pi)}")
val tabel = listOf(
Triple("Apel", 10, 15.5),
Triple("Jeruk", 3, 4.25),
Triple("Mangga", 100, 250.0)
)
println("--- Tabel Buah ---")
println("%-10s %5s %10s".format("Nama", "Jumlah", "Harga"))
for ((nama, jumlah, harga) in tabel) {
println("%-10s %5d %10.2f".format(nama, jumlah, harga))
}
}Output yang Dihasilkan:
Tanpa grup: 1234567.89
Dengan grup: 1,234,567.89
Pad spasi: 42
Pad nol: 00042
Pad nol lebar 8: 00000042
Positif: +3.14
Negatif: -3.14
Tanpa plus positif: 3.14
Persentase: 87.5%
Pad hex: 000000ff
Hex upper: 000000FF
Pi 2 desimal: 3.14
Pi 4 desimal: 3.1416
Pi 8 desimal: 3.14159265
--- Tabel Buah ---
Nama Jumlah Harga
Apel 10 15.50
Jeruk 3 4.25
Mangga 100 250.00Mari kita telaah baris-baris kode di atas:
- Baris 3 (
"%.2f".format(besar)): specifier%fdengan precision.2menghasilkan 2 angka di belakang koma. Tanpa flag grup, output adalah1234567.89tanpa pemisah. - Baris 4 (
"%,.2f"): penambahan flag,memicu pemisah grup. Angka1234567.89ditampilkan sebagai1,234,567.89. Karakter pemisah tergantung locale default. - Baris 7 (
"%5d"): width5menghasilkan field selebar 5 karakter. Angka42di-padding dengan 3 spasi di depan karena rata kanan secara default. - Baris 8 (
"%05d"): flag0mengubah padding menjadi nol. Output00042. Flag0hanya berlaku untuk angka, tidak untuk%satau%c. - Baris 11 (
"%+.2f".format(positif)): flag+memaksa tanda plus tampil untuk angka positif. Tanpa flag ini, angka positif dicetak tanpa tanda. Untuk angka negatif, tanda minus tetap muncul otomatis. - Baris 17 (
"%.1f%%".format(persen * 100)): kita kalikan0.875dengan100menjadi87.5, lalu format dengan satu desimal. Specifier%%menghasilkan tanda persen literal. - Baris 20–21 (
"%08x"dan"%08X"): bilangan bulat255diformat dalam heksadesimal 8 digit dengan padding nol. Specifier lowercasexmenghasilkan000000ff, sedangkan uppercaseXmenghasilkan000000FF. Pola ini umum untuk kode warna HTML atau hash. - Baris 24–26 (
"%.2f","%.4f","%.8f"): precision mengontrol jumlah desimal. Nilaipidipotong/dibulatkan sesuai precision. PerhatikanPi 4 desimal: 3.1416— angka ke-5 (9) membulatkan angka ke-4 dari5menjadi6. - Baris 34 (
"%-10s %5d %10.2f"): gabungan alignment dan width.%-10srata kiri lebar 10,%5drata kanan lebar 5,%10.2frata kanan lebar 10 dengan 2 desimal. Hasilnya kolom yang rapi meskipun data memiliki panjang berbeda.
Rangkuman Flag untuk Angka #
| Flag | Specifier contoh | Efek |
|---|---|---|
, | %,.2f | Pemisah grup (locale-dependent) |
0 | %08d | Padding dengan nol |
+ | %+.2f | Tampilkan tanda + untuk positif |
( | %(,.2f | Bungkus negatif dalam kurung |
- | %-8d | Rata kiri |
(spasi) | % d | Spasi untuk positif (menggantikan +) |
Flag dapat dikombinasikan: %(,.2f sekaligus menggunakan tanda kurung untuk negatif dan pemisah grup. Output untuk -1234.5 dengan format tersebut adalah (1,234.50) — konvensi akuntansi.
Tabel Numerik Rapi #
Untuk tabel yang rapi, pola umum adalah menyimpan format di variabel dan memanggil berulang:
val baris = "%-10s %5d %10.2f"
println(baris.format("Apel", 10, 15.5))
println(baris.format("Jeruk", 3, 4.25))
println(baris.format("Mangga", 100, 250.0))Karena %-10s selalu menghasilkan field selebar 10 karakter (rata kiri), kolom pertama tetap sejajar meskipun nama buah memiliki panjang berbeda. Pola yang sama untuk kolom numerik dengan %5d dan %10.2f.
Referensi Lanjutan #
- Kotlin stdlib kotlin.text.format
— halaman
kotlin.text.formatuntuk format angka dengan specifier%d,%f, dan flag - Java SE 21 Formatter
— dokumentasi
java.util.FormatterJava SE 21 untuk flag numerik dan conversion
Dengan pemahaman tentang flag-flag numerik, kita siap beranjak ke topik yang erat kaitannya: pengaruh locale terhadap pemisah grup, simbol desimal, dan format mata uang.