Asosiy mazmunga o'tish

3-dars: Sonlarning chegarasi

1-blokHamma narsa bit1–4 darslar

1985-yilda “Pac-Man” o’yinining 256-darajasi butunlay buzilib ketdi — ekranning yarmi tushunarsiz belgilarga aylandi. 2014-yilda esa YouTube “Gangnam Style” videosining ko’rishlar sonini qayta hisoblashga majbur bo’ldi.

Ikkisining sababi bir xil va u shu darsda. Sonlarning chegarasi bor, va chegaradan o’tganda kompyuter xato bermaydi — u jimgina noto’g’ri javob beradi.

Bu darsdan keyin siz

  • overflow nima ekanligini va u qanday paydo bo’lishini tushuntira olasiz
  • manfiy sonlar bitlarda qanday saqlanishini bilasiz
  • nega 0.1 + 0.2 aniq 0.3 bermasligini asoslab bera olasiz
  • programmada “buzuq hisob” belgilarini taniy olasiz

O’tgan darsda bilib oldik: 8 bit bilan 0 dan 255 gacha sanash mumkin. Savol — 255 ga 1 qo’shsak nima bo’ladi?

Qo’lda hisoblaymiz. 11111111 ga 1 qo’shamiz. Eng o’ngdagi ustunda 1 + 1 = 10 bo’ladi, ya’ni 0 yozib 1 ni chapga ko’chiramiz. Bu har ustunda takrorlanadi va oxirida ko’chirma sakkizinchi bitdan chiqib ketadi.

Lekin uni saqlaydigan joy yo’q. Shu sababli natija 00000000 — ya’ni 0.

to'lib ketishoverflow

Hisob natijasi ajratilgan bitlar soniga sig’may qolgan holat. Ortib qolgan qism shunchaki yo’qoladi va son aylanib boshidan boshlanadi.

Bitlarda minus belgisi yo’q — faqat 0 va 1 bor. Unda −5 ni qanday yozamiz?

Yechim: bitlarning bir qismini emas, o’qish qoidasini o’zgartiramiz. Eng chapdagi bit “ishora biti” deb e’lon qilinadi: agar u 1 bo’lsa, son manfiy hisoblanadi.

Eng keng tarqalgan usul to’ldiruvchi kod deb ataladi.

to'ldiruvchi kodtwo's complement

Manfiy sonlarni saqlash usuli: qiymatni topish uchun yuqori bit og’irligi manfiy deb olinadi. 8 bitda diapazon −128 dan +127 gacha.

Masalan 11111011 bitlari:

  • ishorasiz o’qilsa: 251
  • ishorali o’qilsa: 251 − 256 = −5

Bitlar bir xil. Faqat o’qish qoidasi boshqa.

To’ldiruvchi kodning katta afzalligi bor: ayirish uchun alohida sxema kerak emas.

7 − 5 amalini bajarish uchun protsessor 7 + (−5) ni hisoblaydi va oddiy qo’shuvchidan foydalanadi. Natijadagi ortiqcha ko’chirma esa tashlab yuboriladi — va javob to’g’ri chiqadi.

Bu 7-darsda arifmetik qurilma yasaganda juda muhim bo’ladi: bitta qo’shuvchi bilan ham qo’shish, ham ayirishni bajaramiz.

Butun sonlar bilan hammasi tushunarli. Kasr sonlarda esa boshqa turdagi muammo bor.

O’nlik sanoqda 1/3 ni aniq yozib bo’lmaydi — 0.333… cheksiz davom etadi. Qaerda bo’lsa ham kesib olishga majbursiz, va natija taxminiy bo’lib qoladi.

Ikkilik sanoqda aynan shu holat 0.1 bilan sodir bo’ladi. 0.1 ikkilikda 0.0001100110011... — cheksiz takrorlanadi.

Kompyuter uni kesib oladi. Shu sababli xotirada saqlangan son 0.1 dan juda oz farq qiladi. Bu farqlar qo’shilganda ko’zga ko’rinadi:

0.1 + 0.2 = 0.30000000000000004

Shu sababli pul hisob-kitobida kasr sonlar ishlatilmaydi. Bank programmalari summani so’mda emas, tiyinda — ya’ni butun sonda — saqlaydi.

Hisoblagichni 255 gacha ko’taring. Keyin “Ishorali” tugmasini bosib, aynan shu bitlar boshqa sonni berishini ko’ring.

Overflow va to'ldiruvchi kod

Sonni +1 bilan 255 gacha ko'taring va keyin nima bo'lishini ko'ring.

Bu simulyatorda 8-bitli hisoblagich bor. 255 ga yetgandan keyin +1 qilsangiz, son 256 emas, 0 bo'lib qoladi — bitlar tugab qoladi.

JavaScript'siz sinash: daftarga 11111111 yozing va unga 1 qo'shib ko'ring. Har ustunda 1 + 1 = 10 bo'ladi, ko'chirma chapga o'tadi va oxirida sakkiz bitdan chiqib ketadi.

Bitlar
00000000
Ishorasiz (0…255)
0

Endi kasr sonlarga o’tamiz. 0.1 + 0.2 ni bosing va “Nega shunday?” bo’limini ochib ko’ring.

Kasr sonlar qaerda buziladi

Ikki kasr son kiritib qo'shing va natijaning to'liq yozuvini ko'ring.

Bu simulyator kasr sonlarni qo'shib, natijaning to'liq yozuvini ko'rsatadi.0.1 + 0.2 aniq 0.3 bermaydi.

JavaScript'siz sinash: kalkulyator ilovasini ochib 0.1 + 0.2 ni hisoblang, keyin natijadan 0.3 ni ayiring. Ko'p kalkulyatorlarda javob nol chiqmaydi.

Kutilgan natija
0.3
Kompyuter bergan natija
0.30000000000000004
Farq
0.00000000000000004

Nega shunday? Ikkilik kasrni ko'rish

0.5 + 0.25 ni ham sinab ko’ring — nega bu juftlik aniq natija berayotganini o’zingizga tushuntirib bering.

  • 8 bitda 255 dan keyin son 0 ga aylanadi — ortiqcha ko’chirmani saqlash joyi yo’q
  • Overflow’da kompyuter ogohlantirmaydi, jimgina noto’g’ri javob beradi
  • To’ldiruvchi kod: yuqori bit 1 bo’lsa son manfiy. 8 bitda −128…+127
  • Bitlar o’zi ma’nosiz — ma’noni o’qish qoidasi beradi
  • Kasr sonlar taxminiy saqlanadi, shuning uchun pul hisobida butun son ishlatiladi

18-bitli hisoblagichda 250 soniga 10 qo'shsak, natija nima bo'ladi?

Javobni ko'rish

260 emas. 8 bitda faqat 0…255 bor, shuning uchun son aylanadi: 260 − 256 = 4. Programma xato bermaydi, shunchaki 4 ni qaytaradi.

210000000 bitlari ishorasiz va ishorali o'qilganda qanday qiymat beradi?

Javobni ko'rish

Ishorasiz: 128. Ishorali (to’ldiruvchi kod): 128 − 256 = −128. Bu 8 bitda yozib bo’ladigan eng kichik manfiy son.

3Nega to'ldiruvchi kod usuli apparat uchun qulay?

Javobni ko'rish

Ayirish uchun alohida sxema kerak bo’lmaydi. a − b amali a + (−b) ga aylantiriladi va oddiy qo’shuvchi bilan bajariladi. Bitta qurilma ikki amalni bajaradi — bu tranzistorlarni tejaydi.

4Nega 0.5 + 0.25 aniq natija beradi, 0.1 + 0.2 esa yo'q?

Javobni ko'rish

0.5 va 0.25 — bu 2⁻¹ va 2⁻². Ular ikkilikda aniq yoziladi: 0.1 va 0.01. 0.1 (o’nlik) esa ikkilikda cheksiz takrorlanuvchi kasr bo’lib, kesib olinadi va aniqlik yo’qoladi.

5Do'koningizni programmalashtirasiz. Narxlarni qanday saqlaysiz va nega?

Javobni ko'rish

Kasr sonda emas, butun sonda tiyinda saqlash kerak. 19.99 so’m o’rniga 1999 tiyin yoziladi. Aks holda minglab operatsiyadan keyin taxminiy xatolar yig’ilib, hisobot haqiqiy summadan farq qila boshlaydi.

Amaliy topshiriq

~30 daqiqaqiyin

Brauzerda konsolni oching (F12 → Console). Quyidagilarni birma-bir yozib, natijani yozib oling:

0.1 + 0.2
0.1 + 0.2 === 0.3
0.3 - 0.1
255 + 1 // bu oddiy son, overflow bo'lmaydi -- nega?
(255 + 1) % 256 // apparat aynan shuni qiladi

Keyin o’zingiz 5 ta “buzuq hisob” topishga harakat qiling — natijasi kutilganidan farq qiladigan amallar.

Har biri uchun yozing: nima kutgansiz, nima chiqdi, va nega shunday bo’ldi.

Topshiriladigan natija: 5 ta misol, har biri uchun uch qatorli izoh.

Darsni belgilash uchun JavaScript kerak. Bu progressni saqlash uchun ishlatiladi — darslikning o'zi JavaScript'siz ham to'liq o'qiladi.