Mundarija (33)
- Bu darsda
- 1. Nega bu kerak?
- 2. Muammoning ildizi
- 3. Yechim: pulni tiyinda saqlash
- 3.1 Eng kichik birlik
- 3.2 So'mdan tiyinga: faqat Math.round
- 3.3 Satrdan tiyinga — kasr sonsiz
- 3.4 Tiyindan ko'rsatishga
- 4. Yaxlitlash qoidalari
- 4.1 Qachon yaxlitlash kerak?
- 4.2 Asosiy strategiyalar
- 4.3 Kodda
- 5. Foiz va chegirma
- 6. QQS 12%
- 6.1 Narxga QQS qo'shish
- 6.2 Narx ichidan QQS'ni ajratish
- 6.3 Har qatorda yoki jamida?
- 7. Hisobni bo'lish
- 8. So'mni chiroyli ko'rsatish: Intl.NumberFormat
- 9. Kutubxonalar: qachon tiyin yetmaydi
- 10. Hujumchi nigohi
- 11. Ko'p uchraydigan xatolar
- 11.1 Pulni toFixed bilan "tuzatish"
- 11.2 So'mdan tiyinga Math.floor bilan o'tish
- 11.3 Qismlarni alohida yaxlitlab, jamini tekshirmaslik
- 11.4 Formatlangan satrni solishtirish
- 11.5 Foizni kasr bilan saqlash
- 12. Mashqlar
- 1-mashq (oson): Savatcha
- 2-mashq (o'rta): Chegirma va QQS
- 3-mashq (qiyin): Taksi hisobini bo'lish
- 13. Real ishda
- Xulosa
JavaScript'da pul hisoblash: tiyinda saqlash, yaxlitlash, chegirma va QQS
Qisqacha: Pulni JavaScript'da kasr son bilan hisoblamang:
72500 * 1.12—81200.00000000001. Pulni eng kichik birlikda — tiyinda — butun son sifatida saqlang: 12 500,50 so'm =1250050tiyin. Foiz va bo'lishdan keyin tiyinni aniq qoida bilan yaxlitlang, faqat ekranga chiqarishda so'mga aylantiring. Murakkab moliyaviy hisob uchundecimal.jskabi kutubxonalar bor.
Bu darsda
- Nega pul uchun oddiy kasr son xavfli ekanini aniq misollarda ko'rsata olasiz.
- Pulni tiyinda saqlab, so'mdan tiyinga va qaytarib to'g'ri aylantira olasiz.
- Yaxlitlash qoidalarini (yuqoriga, noldan uzoqqa, "bank" usuli) farqlay olasiz.
- Chegirma, QQS 12% va hisobni bo'lishni bir tiyin ham yo'qotmasdan hisoblay olasiz.
Intl.NumberFormatbilan so'mni ko'rsata olasiz va uning haqiqiy natijasidagi tuzoqlarni bilasiz.
Oldin bilishingiz kerak: Number turi JS'da, Matn ↔ son va sonni tekshirish, Math obyekti.
1. Nega bu kerak?
Oldingi darsda omonat foizini hisoblaganimizda 17279999.999999996 chiqdi. Bu tasodif emas. Keling, oddiy do'kon hisob-kitobini ko'ramiz.
Mahsulot narxi 72 500 so'm, unga 12% QQS qo'shiladi:
const narx = 72500;
const jami = narx * 1.12;
console.log(jami); // 81200.00000000001
console.log(jami === 81200); // falseKassada 81 200 so'm yozilgan. Dastur esa "bu 81 200 emas" deydi. Endi hamyon balansini ko'ramiz. Mijoz uch marta 0,1 so'mlik keshbek oldi:
let balans = 0;
balans += 0.1;
balans += 0.1;
balans += 0.1;
console.log(balans); // 0.30000000000000004
console.log(balans === 0.3); // falseBir marta bu arzimas xato. Lekin to'lov tizimi kuniga millionlab amal bajaradi. Kun oxirida bank hisoboti bilan dastur hisoboti bir tiyinga ham farq qilsa, hisob mos kelmaydi. Buxgalter bu farqni qo'lda qidiradi, soliq tekshiruvi savol beradi.
Hayotdan o'xshatish: bozorda bir kilo guruchni "taxminan" tortish mumkin. Bankda esa pulni "taxminan" sanab bo'lmaydi. Pul — dasturlashdagi aniqlik talab qilinadigan eng muhim joylardan biri.
2. Muammoning ildizi
Number turi darsida sababini ko'rgandik. JavaScript sonlarni ikkilik tizimda saqlaydi. 0.1 va 1.12 kabi o'nlik kasrlarni ikkilik tizimda aniq yozib bo'lmaydi — xuddi 1/3 ni o'nlik tizimda 0.3333... deb oxirigacha yoza olmaganimiz kabi.
Muhim kuzatuv: butun sonlar bilan bunday muammo yo'q.
console.log(45500 * 0.07); // 3185.0000000000005
console.log((45500 * 7) / 100); // 3185Birinchi qatorda kasr 0.07 bor — xato chiqdi. Ikkinchi qatorda faqat butun sonlar: 45500 * 7 — aniq, bo'lish esa bir marta, eng oxirida. Natija aniq. Butun yechim shu g'oyaga qurilgan.
3. Yechim: pulni tiyinda saqlash
3.1 Eng kichik birlik
1 so'm = 100 tiyin. Tiyin tangalari kundalik hayotda deyarli uchramaydi, lekin banklar va to'lov tizimlari hisobni aynan tiyinda yuritadi. Masalan, Payme API va Telegram botlardagi to'lovlarda summa tiyinda yuboriladi: 50 000 so'm → 5000000.
Qoida: pulni eng kichik birlikda, butun son sifatida saqlang. Inglizcha bu minor units ("kichik birliklar") deyiladi. Dollar uchun — sent, yevro uchun — yevrosent, so'm uchun — tiyin.
const narxTiyin = 1_250_050; // 12 500,50 so'm
console.log(Number.isSafeInteger(narxTiyin)); // trueButun sonlar Number.MAX_SAFE_INTEGER gacha aniq. Tiyinda bu taxminan 90 trillion so'm — oddiy do'kon yoki ilova uchun yetarli. Undan katta summalar uchun BigInt bor, uni keyingi darsda o'rganamiz.
Maslahat: Ba'zi valyutalarda kichik birlik boshqacha. Yapon iyenasida kasr yo'q (0 xona), Quvayt dinorida esa 3 xona (1 dinor = 1 000 fils). Xalqaro ilova yozsangiz, har valyutaning xonalar sonini ISO 4217 standartidan oling.
3.2 So'mdan tiyinga: faqat Math.round
Foydalanuvchi 1.15 so'm kiritdi (masalan, valyuta kursi kasr bo'lganda). Uni tiyinga aylantiramiz:
const som = 1.15;
console.log(som * 100); // 114.99999999999999
console.log(Math.floor(som * 100)); // 114
console.log(Math.round(som * 100)); // 1151.15 * 100 aniq 115 emas. Math.floor yoki Math.trunc bilan bir tiyin yo'qoladi. Qoida: so'mdan tiyinga faqat Math.round(som * 100) bilan o'ting.
3.3 Satrdan tiyinga — kasr sonsiz
Undan ham ishonchlisi — kasr songa umuman tegmaslik. Foydalanuvchi "12 500,50" yozdi. Satrni vergul bo'yicha bo'lib, so'm va tiyinni alohida o'qiymiz:
const kiritilgan = "12 500,50";
const qismlar = kiritilgan.replaceAll(" ", "").split(",");
const som = Number(qismlar[0]);
const tiyin = Number((qismlar[1] ?? "").padEnd(2, "0"));
console.log(som * 100 + tiyin); // 1250050split(",")— Kesish, bo'lish va to'ldirish darsidan:["12500", "50"].qismlar[0]vaqismlar[1]— massivning birinchi va ikkinchi bo'lagi. Ular satrdagi belgilar kabi indeks bilan olinadi, sanash 0 dan boshlanadi (massiv darsida batafsil).qismlar[1] ?? ""— vergul bo'lmasa, ikkinchi qism yo'q (undefined).??operatori uni bo'sh satr qiladi.padEnd(2, "0")—"5"ni"50"ga to'ldiradi:12 500,5— bu 50 tiyin, 5 emas. Bo'sh satr esa"00"bo'ladi.
Bu yerda hech qanday kasr son yo'q — faqat butun sonlarni ko'paytirish va qo'shish. Real loyihada natijani oldingi darsdagidek tekshirishni ham unutmang: Number.isSafeInteger va > 0.
3.4 Tiyindan ko'rsatishga
Hisob-kitob tugadi, endi mijozga ko'rsatamiz. Faqat shu yerda bo'lamiz:
const jamiTiyin = 1250050;
console.log((jamiTiyin / 100).toFixed(2)); // 12500.50Butun sonni 100 ga bo'lish va darhol toFixed(2) qilish ko'rsatish uchun xavfsiz. Natija — satr, u bilan boshqa hisob qilinmaydi. Chiroyliroq ko'rinishni 8-bo'limda ko'ramiz.
Tekshirib ko'ring: Foydalanuvchi
"350,7"yozdi. 3.3 dagi kod necha tiyin qaytaradi?
Javob
35070. split(",") → ["350", "7"]. "7".padEnd(2, "0") → "70". 350 * 100 + 70 = 35070. Ya'ni 350 so'm 70 tiyin — to'g'ri, chunki 350,7 va 350,70 bir xil summa.
4. Yaxlitlash qoidalari
4.1 Qachon yaxlitlash kerak?
Tiyinda qo'shish, ayirish va butun songa ko'paytirish har doim butun natija beradi. Lekin foiz yoki bo'lish kasr tiyin beradi: 1 tiyinning uchdan biri. Bunday tiyin yo'q — yaxlitlash majburiy.
Savol faqat qanday qoida bilan. Bu dasturchi emas, biznes qarori: buxgalteriya, shartnoma yoki qonun belgilaydi. Dasturchining vazifasi — qoidani aniq bilish va uni kodda aniq yozish.
4.2 Asosiy strategiyalar
| Qiymat | Yuqoriga (Math.round) |
Noldan uzoqqa | Bank usuli |
|---|---|---|---|
2.5 |
3 |
3 |
2 |
3.5 |
4 |
4 |
4 |
-2.5 |
-2 |
-3 |
-2 |
2.4 / 2.6 |
2 / 3 |
2 / 3 |
2 / 3 |
Farq faqat aynan o'rtada, .5 da ko'rinadi:
- Yuqoriga (
Math.round) — Math darsidan:.5doim katta tomonga. Manfiy summada kutilmagan natija beradi:-2.5→-2. - Noldan uzoqqa (half away from zero) — maktabdagi qoida, musbat va manfiyda bir xil:
2.5→3,-2.5→-3. - Bank usuli (banker's rounding, half to even) —
.5ni eng yaqin juft songa:2.5→2,3.5→4.
Bank usuli nega kerak? Yuqoriga yaxlitlashda .5 holatlar doim bir tomonga suriladi. Million amalda bu tizimli "ortiqcha" to'planadi. Bank usulida .5 larning yarmi yuqoriga, yarmi pastga ketadi va yig'indi muvozanatda qoladi. Shuning uchun buxgalteriya va bank tizimlarida ko'p ishlatiladi.
4.3 Kodda
Noldan uzoqqa yaxlitlash — Math darsidagi abs va sign bilan:
const qaytarish = -250.5; // mijozga qaytariladigan tiyin
const yuqoriga = Math.round(qaytarish);
const noldanUzoq =
Math.sign(qaytarish) * Math.round(Math.abs(qaytarish));
console.log(yuqoriga); // -250
console.log(noldanUzoq); // -251Mantiq: ishorani vaqtincha olib tashlaymiz (abs), musbat sonni yaxlitlaymiz, ishorani qaytaramiz (sign).
Bank usuli biroz uzunroq. Hozircha ternary bilan yozamiz:
const x = 2.5; // yaxlitlanadigan tiyin
const butun = Math.floor(x);
const kasr = x - butun;
const juftmi = butun % 2 === 0;
const bank =
kasr > 0.5 ? butun + 1
: kasr < 0.5 ? butun
: juftmi ? butun : butun + 1;
console.log(bank); // 2x ni 3.5, 2.4, 2.6 ga o'zgartirib ko'ring — jadvaldagi natijalar chiqadi. Keyinchalik funksiyalarni o'rgansangiz, bunday kodni bir marta yozib, hamma joyda chaqirasiz.
Diqqat: Yaxlitlashni kam va aniq joylarda qiling. Har oraliq qadamni yaxlitlasangiz, xatolar to'planadi. Odatda qoida: har bir foiz yoki bo'lishdan keyin darhol, bir marta, belgilangan strategiya bilan.
5. Foiz va chegirma
Kiyim do'konida 89 990 so'mlik ko'ylakka 15% chegirma. Hammasini tiyinda hisoblaymiz va foizni butun son sifatida saqlaymiz (0.15 emas, 15):
const narx = 8_999_000; // 89 990 so'm, tiyinda
const foiz = 15;
const chegirma = Math.round((narx * foiz) / 100);
const tolov = narx - chegirma;
console.log(chegirma); // 1349850
console.log(tolov); // 7649150Mijoz 76 491,50 so'm to'laydi. E'tibor bering: tolov ni narx * 0.85 deb emas, narx - chegirma deb hisobladik. Shunda chegirma + tolov doim aniq narx ga teng — bir tiyin ham "yo'qolmaydi".
Foiz kasrli bo'lsa-chi, masalan 12,5%? Uni bazis punktda saqlang: 1 bazis punkt = 0,01%. 12,5% = 1250 bazis punkt, va hisob narx * 1250 / 10000. Banklar kredit va omonat foizlarini aynan shunday saqlaydi.
Tekshirib ko'ring: Nega
const foiz = 0.15emas,15saqlash yaxshiroq?
Javob
0.15 — kasr son, u ikkilik tizimda aniq saqlanmaydi. narx * 0.15 ba'zan ...0000005 kabi "dum" beradi (45500 * 0.07 misolini eslang). 15 esa butun son: narx * 15 aniq, keyin bitta bo'lish va bitta yaxlitlash.
6. QQS 12%
O'zbekistonda qo'shilgan qiymat solig'i (QQS) — 12%. Hisoblashning ikki holati bor.
6.1 Narxga QQS qo'shish
Narx QQS'siz berilgan (masalan, ulgurji narx). QQS ustiga qo'shiladi:
const sofNarx = 11_500_000; // 115 000 so'm, QQS'siz
const qqs = Math.round((sofNarx * 12) / 100);
const jami = sofNarx + qqs;
console.log(qqs); // 1380000
console.log(jami); // 128800006.2 Narx ichidan QQS'ni ajratish
Chakana narx odatda QQS bilan yoziladi. Chekda "shu jumladan QQS 12%" degan qator bor — ya'ni narx ichidagi QQS ulushi. 129 000 so'mlik mahsulotda QQS qancha?
Xato yo'l — 129000 * 0.12. Narx QQS bilan birga 112% ni tashkil qiladi, sof narx — 100%, QQS — 12%. Demak QQS = narx × 12 / 112:
const narx = 12_900_000; // 129 000 so'm, QQS bilan
const qqs = Math.round((narx * 12) / 112);
const sofNarx = narx - qqs;
console.log((narx * 12) / 112); // 1382142.857142857
console.log(qqs); // 1382143
console.log(sofNarx); // 11517857QQS 13 821,43 so'm. Yana o'sha hiyla: sofNarx ni alohida bo'lish bilan emas, ayirish bilan topdik. Shunda sofNarx + qqs aniq narx ga teng.
6.3 Har qatorda yoki jamida?
Chekda ikki mahsulot: choy 5 000 so'm va non 8 500 so'm. QQS'ni har mahsulot uchun alohida yaxlitlash va jamidan hisoblash — har xil natija beradi:
const choy = 500_000;
const non = 850_000;
const qatorlab =
Math.round((choy * 12) / 112) + Math.round((non * 12) / 112);
const jamidan = Math.round(((choy + non) * 12) / 112);
console.log(qatorlab); // 144642
console.log(jamidan); // 144643Bir tiyin farq! Ikkala usul ham matematik jihatdan "to'g'ri", faqat yaxlitlash har xil joyda. Qaysi biri kerakligini soliq qoidasi va kompaniya buxgalteriyasi belgilaydi. Dasturchi uchun muhimi — bitta usulni tanlab, hamma joyda izchil qo'llash. Aks holda chekdagi va hisobotdagi QQS mos kelmaydi.
7. Hisobni bo'lish
Uch do'st kafeda 100 000 so'mlik hisobni teng bo'lishmoqchi. 100000 / 3 — 33333.333.... Har kim 33 333 so'm to'lasa, jami 99 999 bo'ladi — bir so'm yetmaydi.
To'g'ri usul: butun qismni hammaga beramiz, qoldiqni esa birinchi odamlarga bittadan taqsimlaymiz. Arifmetika darsidagi % qoldiq operatori yordam beradi:
const hisob = 100_000;
const odamlar = 3;
const ulush = Math.floor(hisob / odamlar);
const qoldiq = hisob % odamlar;
console.log(ulush); // 33333
console.log(qoldiq); // 1Natija: birinchi odam ulush + 1 = 33 334 so'm, qolgan ikkitasi 33 333 so'mdan. Jami aniq 100 000. Qoldiq doim odamlar sonidan kichik, shuning uchun hech kim boshqalardan 1 so'mdan ortiq to'lamaydi.
Ulushlar teng bo'lmasa-chi? Masalan, sheriklar foydani 70/30 bo'lishadi. Yana ayirish hiylasi — oxirgi ulushni "qolganicha" beramiz:
const foyda = 99_999;
const birinchi = Math.round((foyda * 70) / 100);
const ikkinchi = foyda - birinchi;
console.log(birinchi); // 69999
console.log(ikkinchi); // 3000069999.3 yaxlitlandi, ikkinchisi esa qolganini oldi. Ikkalasini qo'shsangiz — aniq 99 999. Bu naqsh inglizcha allocation (taqsimlash) deyiladi va pul kutubxonalarida alohida funksiya sifatida bor.
Tekshirib ko'ring: 50 000 so'mni 7 kishiga bo'lsak,
ulushvaqoldiqqancha? Nechta odam 1 so'm ko'proq to'laydi?
Javob
ulush = 7142, qoldiq = 6. 7142 × 7 = 49994, yetmagan 6 so'm — 6 kishiga bittadan. Ya'ni 6 kishi 7 143 so'm, bitta kishi 7 142 so'm to'laydi. Jami: 6 × 7143 + 7142 = 50000.
8. So'mni chiroyli ko'rsatish: Intl.NumberFormat
Math darsida Intl.NumberFormat bilan minglarni ajratishni ko'rgandik. Endi valyuta bilan:
const somFormat = new Intl.NumberFormat("uz-UZ", {
style: "currency",
currency: "UZS",
});
console.log(somFormat.format(12000)); // 12 000,00 soʻm
console.log(somFormat.format(1250050 / 100)); // 12 500,50 soʻmJingalak qavs ichidagi style: "currency", currency: "UZS" — formatlovchiga beriladigan sozlamalar: "valyuta sifatida ko'rsat, valyuta — so'm". Bu yozuv shakli obyekt deyiladi, uni keyinroq to'liq o'rganamiz. UZS — so'mning xalqaro kodi.
Yuqoridagi natijalar Node 22 da haqiqatan chiqqan. Endi ularga yaqinroq qaraymiz — ikki kutilmagan narsa bor:
const somFormat = new Intl.NumberFormat("uz-UZ", {
style: "currency",
currency: "UZS",
});
const matn = somFormat.format(12000);
console.log(matn.includes(" ")); // false
console.log(matn.includes("'")); // false
console.log(matn.codePointAt(2).toString(16)); // a0
console.log(matn.codePointAt(12).toString(16)); // 2bb- Minglar orasida oddiy bo'sh joy yo'q. U yerda Matn ↔ son darsida ko'rgan uzilmas bo'sh joy turibdi (kodi
U+00A0). so'mdagi belgi — oddiy apostrof emas,ʻ(kodiU+02BB). Bu o'zbek lotin alifbosining rasmiy "o'" belgisi.codePointAtni Unicode darsida ko'rgandik.
Oqibati:
const somFormat = new Intl.NumberFormat("uz-UZ", {
style: "currency",
currency: "UZS",
});
console.log(somFormat.format(12000) === "12 000,00 so'm"); // false
console.log(Number(somFormat.format(12000))); // NaNQoida: formatlangan matn — faqat ko'rsatish uchun. Uni boshqa satr bilan solishtirmang, testlarda qo'lda yozilgan satrga tenglashtirmang va qaytarib songa aylantirmang. Pul doim tiyinda, butun son holida saqlanadi.
Tiyinsiz ko'rsatish uchun maximumFractionDigits: 0 sozlamasi bor:
const somFormat = new Intl.NumberFormat("uz-UZ", {
style: "currency",
currency: "UZS",
maximumFractionDigits: 0,
});
console.log(somFormat.format(12000)); // 12 000 soʻmBoshqa tilda formatlasak, natija butunlay boshqacha:
| Til kodi | format(12000) natijasi |
|---|---|
"uz-UZ" |
12 000,00 soʻm |
"ru-RU" |
12 000,00 UZS |
"en-US" |
UZS 12,000.00 |
Diqqat: Formatlash natijasi Node va brauzer versiyasiga bog'liq. Til qoidalari ICU degan xalqaro ma'lumotlar bazasidan olinadi va u vaqti-vaqti bilan yangilanadi. Boshqa versiyada
soʻmo'rnigaso'myokiUZSchiqishi mumkin. Bu ham formatlangan matnga tayanmaslikka yana bir sabab. Batafsil —Intl.NumberFormatdarsida.
9. Kutubxonalar: qachon tiyin yetmaydi
Tiyin usuli do'kon, kafe, yetkazib berish va obunalar uchun yetarli. Lekin ba'zi hisoblar murakkabroq: kredit foizini kunlab hisoblash, valyuta kursi 4–6 xonali kasr bilan, investitsiya ulushlari. Bunday joyda decimal kutubxonalar ishlatiladi. Ular sonni o'nlik tizimda saqlaydi va 0.1 + 0.2 ni aniq 0.3 qiladi.
Kutubxona — boshqa dasturchilar yozgan tayyor kod, uni loyihaga npm (JavaScript paketlari "do'koni") orqali qo'shasiz. Npm'ni kursda alohida o'rganamiz, hozir nomlarini bilib qo'ying:
- decimal.js (10-versiya) — eng to'liq: aniqlik va yaxlitlash rejimini sozlash, daraja, ildiz.
- big.js (7-versiya) — o'sha muallifning kichik va sodda varianti: faqat asosiy amallar.
- dinero.js (2-versiya) — sonni emas, pulni ifodalaydi: summa va valyuta birga, taqsimlash (allocation) tayyor.
Ma'lumotlar bazasida ham xuddi shu tamoyil: pul NUMERIC (aniq o'nlik) yoki BIGINT (tiyinda) ustunida saqlanadi, kasr turida emas. Buni SQL qismida ko'rasiz.
10. Hujumchi nigohi
To'lov bor joyda buzishga urinish ham bor. Eng ko'p uchraydigan hujumlar:
- Narxni brauzerdan olish. Hujumchi sahifadagi narxni 89 990 dan 1 so'mga o'zgartirib, serverga yuboradi. Himoya: server narxni hech qachon brauzerdan olmaydi. U faqat mahsulot ID si va sonini oladi, narxni o'z bazasidan o'qiydi.
- Manfiy son. Savatchada
-3ta mahsulot — jami manfiy, ya'ni do'kon mijozga pul to'laydi. Himoya: oldingi darsdagiNumber.isInteger(soni) && soni > 0. - Kasr tiyin bilan o'ynash. Hujumchi 0,005 so'mlik minglab o'tkazma qiladi. Har biri yuqoriga yaxlitlanib 1 tiyin bo'lsa, u "bo'sh joydan" pul yasaydi. Himoya: kiritilgan summa tiyinda butun bo'lishi shart, kasr qism rad etiladi.
NaNvaInfinity."1e999"summasiInfinityga aylanib, hisob-kitobni buzadi. Himoya:Number.isSafeInteger(tiyin).
Hammasi serverda qayta tekshiriladi — brauzer tekshiruvi faqat qulaylik uchun.
11. Ko'p uchraydigan xatolar
11.1 Pulni toFixed bilan "tuzatish"
(0.1 + 0.2).toFixed(2) — "0.30". Ko'rinishi to'g'ri, lekin bu satr. Undan keyin hisoblasangiz, yopishtirish chiqadi. Qolaversa, toFixed ham adashadi: 1.005-bob.toFixed(2) — "1.00". Yechim — butun tiyin.
11.2 So'mdan tiyinga Math.floor bilan o'tish
Math.floor(1.15 * 100) — 114. Faqat Math.round.
11.3 Qismlarni alohida yaxlitlab, jamini tekshirmaslik
Hisobni uchga bo'lib, har birini yaxlitlasangiz, jami asl summaga teng bo'lmaydi. Doim oxirgi qismni ayirish bilan toping yoki qoldiqni taqsimlang.
11.4 Formatlangan satrni solishtirish
format(12000) === "12 000,00 so'm" — false. Solishtirish — faqat tiyindagi butun sonlar bilan.
11.5 Foizni kasr bilan saqlash
narx * 0.07 o'rniga narx * 7 / 100, keyin bitta yaxlitlash.
12. Mashqlar
1-mashq (oson): Savatcha
Savatchada: 2 ta sut (9 900 so'm), 3 ta non (4 500 so'm) va 1 ta pishloq (38 750,50 so'm). Narxlarni tiyinda yozib, jamini tiyinda hisoblang. Keyin (jami / 100).toFixed(2) bilan so'mda chiqaring.
Yechim
const sut = 990_000;
const non = 450_000;
const pishloq = 3_875_050;
const jami = sut * 2 + non * 3 + pishloq;
console.log(jami); // 7205050
console.log((jami / 100).toFixed(2)); // 72050.50Hamma amal butun sonlar bilan — natija aniq. So'mga faqat eng oxirida, ko'rsatish uchun o'tdik.
2-mashq (o'rta): Chegirma va QQS
Televizor narxi — 4 990 000 so'm (QQS bilan). Aksiyada 20% chegirma. Hisoblang (hammasi tiyinda):
chegirmavatolov(chegirmadan keyingi narx);tolovichidagi QQS 12% va sof narx.
Tekshiring: tolov + chegirma narxga teng, sofNarx + qqs esa tolov ga teng bo'lsin.
Ishora: 5- va 6.2-bo'limlardagi "ayirish hiylasi". Katta sonlarni 4_990_000 kabi yozing — Son yozish shakllari.
Yechim
const narx = 499_000_000; // 4 990 000 so'm, tiyinda
const chegirma = Math.round((narx * 20) / 100);
const tolov = narx - chegirma;
const qqs = Math.round((tolov * 12) / 112);
const sofNarx = tolov - qqs;
console.log(chegirma); // 99800000
console.log(tolov); // 399200000
console.log(qqs); // 42771429
console.log(sofNarx); // 356428571
console.log(tolov + chegirma === narx); // true
console.log(sofNarx + qqs === tolov); // trueMijoz 3 992 000 so'm to'laydi, uning ichida QQS 427 714,29 so'm. (tolov * 12) / 112 — 42771428.57..., yaxlitlab 42771429 tiyin.
3-mashq (qiyin): Taksi hisobini bo'lish
Uch hamkasb taksida 87 350 so'mlik yo'l haqini bo'lishmoqchi. Ilova "tiyingacha adolatli" bo'lishi kerak:
- Summani tiyinda yozing.
ulushvaqoldiqni toping.- Birinchi
qoldiqta odamulush + 1tiyin to'laydi — unikattadeb nomlang. Ikki xil ulushni so'mda (toFixed(2)) chiqaring. - Oxirida tekshiring:
katta * qoldiq + ulush * (odamlar - qoldiq)aniq umumiy summaga teng —truechiqishi kerak.
Yechim
const summa = 8_735_000; // 87 350 so'm, tiyinda
const odamlar = 3;
const ulush = Math.floor(summa / odamlar);
const qoldiq = summa % odamlar;
const katta = ulush + 1;
console.log(ulush); // 2911666
console.log(qoldiq); // 2
console.log((katta / 100).toFixed(2)); // 29116.67
console.log((ulush / 100).toFixed(2)); // 29116.66
const tekshir = katta * qoldiq + ulush * (odamlar - qoldiq);
console.log(tekshir === summa); // trueIkki kishi 29 116,67 so'm, bittasi 29 116,66 so'm to'laydi. Jami — aniq 87 350 so'm.
odamlar ni 4 ga o'zgartirib ko'ring. Bu safar qoldiq = 0: summa to'rtga qoldiqsiz bo'linadi, hamma 21 837,50 so'm to'laydi. Tekshiruv yana true — formula qoldiq bo'lmaganda ham to'g'ri ishlaydi.
13. Real ishda
- To'lov tizimlari: Payme, Click va Telegram to'lovlari bilan ishlaganda summani tiyinda yuborish — birinchi va eng ko'p uchraydigan talab. To'lov ekotizimi darsida real integratsiya qilasiz.
- Onlayn do'kon va chek: chegirma, promo-kod, QQS, yetkazish narxi — hammasi tiyinda, ayirish hiylasi bilan.
- Buxgalteriya va bank: yaxlitlash strategiyasi hujjatda yozilgan bo'ladi. Dasturchi uni aynan bajaradi.
- Intervyu: "
0.1 + 0.2nega0.3emas va pulni qanday saqlaysiz?" — frontend va backend intervyularidagi eng mashhur savollardan biri. Kutilgan javob: "eng kichik birlikda butun son yoki decimal kutubxona".
Xulosa
- Pul uchun kasr son (
numberdagi0.1,1.12) xavfli:72500 * 1.12—81200.00000000001. - Pulni tiyinda, butun son sifatida saqlang. So'mdan tiyinga — faqat
Math.round(som * 100), satrdan esa kasr sonsiz. - Foiz va bo'lishdan keyin bir marta, biznes belgilagan qoida bilan yaxlitlang: yuqoriga, noldan uzoqqa yoki bank usuli.
- Oxirgi qismni ayirish bilan toping (
narx - chegirma,foyda - birinchi) — shunda bir tiyin ham yo'qolmaydi. - QQS narx ichidan:
narx * 12 / 112. Qatorlab yoki jamidan — bittasini tanlab, izchil qo'llang. Intl.NumberFormatnatijasi — faqat ko'rsatish uchun: unda uzilmas bo'sh joy vaʻbor.
Keyingi dars: BigInt: juda katta butun sonlar — MAX_SAFE_INTEGER dan katta sonlar bilan aniq ishlash va uning oddiy sonlar bilan aralashmasligi.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!