Belajar dengan membaca secara berurutan

Number dan Aritmatika — Type Number dan Math

Pelajari number JavaScript dari type Number: aritmatika, pembulatan Math, dan error desimal.

Banyak hal yang dihitung web app berujung pada number — subtotal order, pajak penjualan, ongkos kirim, poin yang didapat. JavaScript tidak punya type terpisah untuk integer dan desimal; dia menangani keduanya dengan type Number yang sama.

Artikel ini membahas operator aritmatika, termasuk remainder dan exponent, pembulatan dengan Math, meratakan digit dengan toFixed, dan error presisi desimal yang sering menjebak orang dalam perhitungan uang.

1 Type Number — Number dan Operator Aritmatika

Beberapa bahasa memisahkan integer dan desimal jadi type yang berbeda. Konsep "jenis value" ini disebut type (klasifikasi sebuah value — apakah dia number, text, dan seterusnya).

JavaScript tidak membedakan integer dan desimal — 1200 dan 0.08 sama-sama type Number (type yang merepresentasikan angka). Kamu tidak pernah memilih type saat mendeklarasikan variable, tapi trade-off-nya adalah membagi dua integer bisa meninggalkan hasil desimal.

Simbol yang mengarahkan sebuah perhitungan disebut operator aritmatika (simbol yang merepresentasikan perhitungan antar value). Selain penjumlahan +, pengurangan -, perkalian *, dan pembagian /, ada % untuk sisa pembagian dan ** untuk exponent.

Operator Aritmatika dan Hasilnya
a + btambaha - bkuranga * bkalia / bbagia % bsisaa ** bexponent7 / 2→ 3.57 % 2→ 12 ** 10→ 1024
2 baris atas adalah operatornya; baris bawah adalah hasil sebenarnya. Pembagian menyisakan desimal, % mengembalikan sisa, dan ** mengembalikan pangkat.
console.log(1200 + 300);   // 1500
console.log(1200 - 300);   // 900
console.log(1200 * 3);     // 3600

// Bahkan dengan dua integer, sisa desimal tetap ada kalau tidak habis dibagi
console.log(7 / 2);        // 3.5

// % adalah sisa, ** adalah pemangkatan
console.log(7 % 2);        // 1
console.log(2 ** 10);      // 1024

% berguna untuk mencari sisa amount, atau "sisa saat dibagi ke grup dengan ukuran tetap." Untuk total 4380, 4380 % 100 memberimu 80 — jumlah sisa setelah dihitung dalam satuan 100.

** memberimu exponent, memungkinkanmu menghitung hal seperti 2 ** 10 — jumlah byte dalam 1 kilobyte.

Dapatkan total dan rata-rata dari 3 order dalam sehari. Amount tiap order — orderA, orderB, dan orderC — sudah dideklarasikan.

① Tampilkan total dari 3 order tersebut.

② Tampilkan rata-rata amount per order.

③ Tampilkan sisa setelah total dihitung dalam satuan 100.

(Kalau berjalan dengan benar, penjelasan akan muncul.)

JavaScript / TypeScript Editor

Jalankan kode untuk melihat output

Pembulatan dengan Math — Floor, Ceiling, dan Terdekat

Kamu tidak bisa langsung menaruh rata-rata, 1903.3333333333333, di invoice. Amount dan jumlah perlu dibulatkan ke integer di suatu titik, dan apakah kamu membulatkan ke bawah, ke atas, atau ke value terdekat tergantung aturan bisnis.

JavaScript mengelompokkan function pembulatan ini di bawah Math.

Mari kenalkan istilah function dulu (unit bernama yang menjalankan proses tetap pada value yang kamu berikan, dan mengembalikan hasil). Mendapat hasil kembali dari value yang kamu berikan dideskripsikan sebagai "memanggil"-nya dan membuatnya "mengembalikan" value.

Function di bawah Math (koleksi built-in JavaScript berisi function numerik) dipanggil dengan menulis Math, titik, lalu nama function-nya — seperti Math.floor(1903.33).

Math.floor membulatkan desimal ke bawah, Math.ceil membulatkan ke atas, dan Math.round membulatkan ke integer terdekat. Ketiganya hanya mengembalikan number baru — variable yang kamu berikan tetap sama.

3 Function Pembulatan, 3 Hasil Berbeda
Math.floor(149.8)Bulatkandesimal ke bawah149Math.ceil(149.8)Bulatkandesimal ke atas150Math.round(149.8)Bulatkan keinteger terdekat150
Berikan 149.8 yang sama ke masing-masing, dan floor mengembalikan 149, sementara ceiling dan round sama-sama mengembalikan 150.
const points = 149.8;             // Poin dari amount pembelian

console.log(Math.floor(points));  // 149  bulatkan ke bawah
console.log(Math.ceil(points));   // 150  bulatkan ke atas
console.log(Math.round(points));  // 150  bulatkan ke terdekat

console.log(points);              // 149.8  value aslinya tidak berubah

// max mengembalikan value mana pun yang kamu berikan lebih besar
console.log(Math.max(0, 5000 - 5200));   // 0

Satu lagi yang akan kamu pakai di luar pembulatan adalah Math.max. Dia mengembalikan value mana pun yang kamu berikan lebih besar, jadi Math.max(0, -120) adalah 0.

Itu memberimu batas bawah untuk perhitungan yang tidak boleh turun di bawah nol — berguna untuk hal seperti "berapa lagi sampai gratis ongkir."

Cari berapa lagi yang dibutuhkan untuk gratis ongkir, dan poin yang didapat, dari subtotal cart. Subtotal cartSubtotal dan batas gratis ongkir freeShippingLine sudah dideklarasikan.

① Tampilkan berapa lagi yang dibutuhkan untuk gratis ongkir — jangan sampai negatif kalau subtotal sudah melewati batasnya.

② Tampilkan poin yang didapat — 3.5% dari subtotal — dibulatkan ke bawah ke integer.

③ Tampilkan, dibulatkan ke atas, berapa item lagi seharga 250 yang dibutuhkan untuk mencapai gratis ongkir.

JavaScript / TypeScript Editor

Jalankan kode untuk melihat output

Meratakan Digit dengan toFixed — Mengembalikan String

Kadang, seperti pada rata-rata amount, kamu mau menentukan jumlah digit yang ditampilkan di awal. Menampilkan 1903.3333333333333 apa adanya susah dibaca, jadi kamu rapikan jadi 1 angka desimal dan tampilkan 1903.3.

Pakai toFixed untuk itu.

toFixed adalah method (function yang kamu panggil dengan menulis titik setelah sebuah value) — kamu panggil dengan titik setelah sebuah number. Value yang diberikan di dalam tanda kurung disebut argument (value yang diberikan di dalam tanda kurung sebuah function atau method). Berikan jumlah digit desimal yang mau disimpan, seperti di toFixed(1), dan dia membulatkan di digit berikutnya dan mengembalikan hasilnya sesuai jumlah digit itu. Tapi yang kembali adalah string, bukan number. Pakai ini hanya tepat sebelum menampilkan sebuah value — untuk perhitungan lebih lanjut, pakai number aslinya atau Math.round.

Math.floor(value) memberikan sebuah value ke function yang ada di dalam container Math; value.toFixed(digits) memanggil function yang dibawa oleh value itu sendiri. Apa yang ada sebelum titik memberitahumu bentuk mana yang kamu lihat.

Apa yang Dikembalikan toFixed dan Math.round
toFixed(1)Ratakan digit,kembalikan string"1903.3"toFixed(0)Ratakan digit,kembalikan string"1903"Math.round(x * 10)/ 10Kembalikannumber terbulat1903.3
Keduanya bisa terlihat sama-sama 1903.3, tapi toFixed mengembalikan string, sementara Math.round mengembalikan number.
const averageOrder = 1903.3333333333333;   // Rata-rata amount per order

console.log(averageOrder.toFixed(1));  // 1903.3  dikembalikan sebagai string
console.log(averageOrder.toFixed(0));  // 1903    dikembalikan sebagai string

// Untuk terus menghitung, bulatkan sambil tetap jadi number
console.log(Math.round(averageOrder * 10) / 10);  // 1903.3  tetap number

Hasil toFixed Hanya untuk Ditampilkan

Karena yang dikembalikan toFixed adalah string, menambah atau mengalikan hasil itu berperilaku berbeda dibanding kalau itu number. Perbedaan antara string dan number, dan cara mengecek mana yang kamu punya, dibahas di artikel type conversion.

Format discount rate sebuah item sale jadi sesuatu yang bisa kamu tampilkan. Harga list listPrice dan harga sale salePrice sudah dideklarasikan.

① Tampilkan discount rate yang diberikan, discountRate, tanpa dibulatkan.

② Tampilkan rate yang sama, diratakan ke 1 digit desimal.

③ Tampilkan rate yang sama, diratakan tanpa digit desimal sama sekali.

JavaScript / TypeScript Editor

Jalankan kode untuk melihat output

Error Presisi Desimal — Kenapa 0.1 + 0.2 Bukan 0.3

Rangkai cukup banyak perhitungan yang melibatkan desimal, dan jawabannya bisa sedikit melenceng. Ini yang menyebabkan bug seperti total yang selisih sepersekian, jadi mari lihat kenapa itu terjadi dan cara menghindarinya sebelum menggigitmu.

Komputer menyimpan number dalam biner. 0.1 dalam desimal tidak habis dibagi dalam biner — jadi menjadi pecahan berulang tak terhingga — jadi dia disimpan sebagai value lain yang sangat dekat sebagai gantinya.

0.1 dan 0.2 sama-sama disimpan sedikit meleset, jadi menjumlahkannya juga mendarat sedikit meleset dari 0.3.

Apa yang Terjadi Saat Desimal Disimpan dalam Biner
0.1Tidak habis dibagidi binerTersimpan sebagaivalue dekat 0.10.2Tidak habis dibagidi binerTersimpan sebagaivalue dekat 0.20.1 + 0.2Jumlahkan 2value yang dekatSedikit lebihdari 0.3
Baik 0.1 maupun 0.2 sudah sedikit meleset begitu disimpan, jadi hasil jumlahnya juga melenceng dari 0.3.
console.log(0.1 + 0.2);   // 0.30000000000000004

// Skalakan ke integer dulu, hitung, lalu skalakan turun lagi — tidak melenceng
console.log((0.1 * 10 + 0.2 * 10) / 10);   // 0.3

Simpan Amount sebagai Integer

Makin banyak penjumlahan desimal yang kamu rangkai, makin bertambah pula lencengannya. Untuk amount uang, simpan sebagai satuan integer dan hanya bagi tepat sebelum ditampilkan — itu menghindari error ini sepenuhnya.

Jumlahkan berat produk untuk perhitungan pengiriman. Dua berat, weightA dan weightB, sudah dideklarasikan.

① Tampilkan hasil menjumlahkan kedua berat langsung.

② Tampilkan total yang sama, dibulatkan ke 1 digit desimal sebagai number.

③ Skalakan kedua berat naik 10 kali jadi integer, jumlahkan, lalu bagi 10, dan tampilkan hasilnya.

JavaScript / TypeScript Editor

Jalankan kode untuk melihat output

Value dari Perhitungan Gagal — NaN dan Infinity

Saat sebuah perhitungan tidak berhasil, JavaScript tidak berhenti — dia mengembalikan value spesial dan terus jalan. Banyak bug di mana total muncul kosong atau amount tampil salah berasal dari value semacam ini yang tercampur ke dalam perhitungan yang terus berjalan.

Hasil yang tidak bisa diekspresikan sebagai number adalah NaN (singkatan dari Not a Number — value yang berarti hasilnya tidak bisa jadi number). 0 / 0, dari mencoba merata-ratakan hari dengan nol order, adalah salah satu contohnya.

Membagi dengan nol dengan cara lain, seperti 5710 / 0, mengembalikan Infinity (value yang merepresentasikan tak terhingga). Keduanya tidak berhenti dengan error, jadi kamu mungkin tidak sadar sampai itu muncul di layar.

const orderTotal = 5710;
const orderCount = 0;                  // Ada 0 order hari itu

console.log(orderTotal / orderCount);  // Infinity
console.log(0 / 0);                    // NaN

// Begitu NaN tercampur, tiap perhitungan setelahnya juga jadi NaN
console.log(0 / 0 + 1000);             // NaN

Sama seperti Math, Number mengelompokkan sekumpulan function terkait number miliknya sendiri. Kamu bisa mengecek apakah sebuah value adalah integer utuh dengan Number.isInteger. Number.isInteger(3) mengembalikan true dan Number.isInteger(2.5) mengembalikan false — sebuah boolean (value yang merepresentasikan salah satu dari dua pilihan: apakah sesuatu berlaku benar) — jadi ini berguna untuk memastikan value seperti jumlah yang tidak boleh mengizinkan desimal.

Cara mengecek apakah dua value sama dibahas di artikel berikutnya, tapi NaN adalah satu pengecualian — dia bahkan tidak sama dengan dirinya sendiri kalau memakai method itu.

Jadi mengecek NaN memakai pengecekan khusus sebagai gantinya. Itu dibahas, bersama mengonversi string ke number, di artikel type conversion.

console.log(Number.isInteger(3));      // true
console.log(Number.isInteger(2.5));    // false
console.log(Number.isInteger(6 / 2));  // true   pembagian genap adalah integer utuh

NaN dan Infinity mengalir ke perhitungan berikutnya tanpa pernah berhenti dengan error. Saat total atau rata-rata tampil salah, curigai pembagian dengan nol dulu — itu biasanya cara tercepat menemukan penyebabnya.

QUIZ

Cek Pemahaman

Jawab setiap pertanyaan satu per satu.

Soal 1Apa yang terjadi saat kamu menjalankan console.log(10 / 4);?

Soal 2Apa yang dikembalikan saat memanggil toFixed(2) pada sebuah number?

Soal 3Apa yang ditampilkan console.log(0.1 + 0.2);?