
Agar kompyuterda kalkulyatorni ochib, 0.1 + 0.2 ni tersangiz va 0.30000000000000004 ni koʻrsangiz, qattiq hayron qolarmidingiz? Dastur buzilib qolgandek tuyulishi mumkin, ammo aslida qarshingizda "suzuvchi vergul" (inglizcha floating point) deb ataladigan narsaning normal ishlashi turibdi.
Kompyuterga 0.1 deganingizda, u buni oʻzining "nollari va birlari" tiliga oʻgiradi. Ikkilik sanoq tizimida faqat 2 ga boʻlinishlarga ruxsat berilgan: 1/2, 1/4, 1/8, 1/16 va h.k. "Pirog"ni faqat shu "yarimta"lar yordamida oʻnta teng boʻlakka boʻlishning imkoni yoʻq - doim sal koʻproq yoki sal kamroq olishga toʻgʻri keladi. Shunday qilib, ideal oʻndan bir hech qachon topilmaydi. Natijada kompyuter xotirasida aniq "0,1" emas, balki uning taqribiy versiyasi saqlanadi:
0.0001100110011...
Bu yerda "0011" guruhi cheksiz takrorlanadi. Lekin kompyuter cheksizlikni saqlay olmaydi: unda kasr qismi (mantissa) uchun qatʼiy ajratilgan joy - 52 ta "katakcha" bor. U shunchaki bu cheksiz qatorning birinchi 52 bitini oladi va qolganini kesib tashlaydi. Natijada salgina notoʻgʻri son hosil boʻladi, ichkarida u taxminan quyidagiga teng:
0.10000000000000000555...
Yaʼni, ideal 0.1 oʻrniga xotirada 0.10000000000000000555... yotibdi, biz esa bu uzun qatorning faqat boshini koʻryapmiz.
Keling, 1/3 kasrini eslaylik. Maktab kalkulyatorida u 0.333333... ga aylanadi - uch raqami cheksiz takrorlanadi. Biz bilamizki, bu sonning oxiri boʻlmaydi, chunki oʻnlik sanoq tizimida birni uchga teng boʻlib boʻlmaydi.
0.1 bilan ham xuddi shunday holat, faqat: oʻnlik tizimda u ideal tasvirlanadi (verguldan keyin bitta raqam - va tamom), ikkilik tizimda esa cheksiz boʻlinadi - har safar goh sal koʻproq, goh sal kamroq olishga toʻgʻri keladi va natijada cheksiz zanjir hosil boʻladi: ...0011 0011 0011.
Bu yerda prinsip muhim: agar kasr maxraji sanoq tizimi bazasida yoʻq boʻlgan tub koʻpaytuvchilarni oʻz ichiga olsa (oʻnlikda bu 2 va 5, ikkilikda - faqat 2), unda kasr takrorlanuvchi raqamlarning cheksiz tasmasiga choʻziladi. Shuning uchun 0.5 (1/2) oʻnlikda ham, ikkilikda ham aniq ifodalanadi. Ammo 0.1 (1/10) ikkilikda "uzilib qoladi", chunki 5 ga boʻlish - nollar va birlar dunyosi uchun yot amal.
Shunday ekan, biz "kasr cheksiz" deganimizda, bu qandaydir ekzotika emas: qogʻozga 0.3333… deb yozganingizda har safar xuddi shu holat yuz beradi. Shunchaki kompyuterda cheksiz uchlik rolini 52 bitga sigʻishi uchun kesib tashlanishi kerak boʻlgan birlar va nollarning cheksiz ketma-ketligi bajaradi.
Kompyuterlar juda katta sonlar (masalan, yulduzlargacha boʻlgan masofa) va juda kichik sonlar (animatsiyadagi soniya ulushlari) bilan ishlay olishi kerak. Har bir sonni oddiy uzun oʻnlik yozuv bilan saqlash, masalan, ulkan 300000000000000000000000 yoki oʻta mikroskopik 0.000000000000000000005 noqulay va sekin boʻlar edi. Shuning uchun suzuvchi nuqtali tizim - yaʼni ilmiy notatsiya (yozuv) oʻylab topilgan.
Qulaylikni tushunish uchun, keling, ikkita sonni bir-biriga koʻpaytirib koʻramiz:
300000000000000000000000 × 0.000000000000000000005
Urinib koʻrish mumkin... lekin keling, boshqa tomondan yondashamiz. Biz bu ikki sonni ilmiy notatsiya koʻrinishida tasvirlashimiz mumkin va amalni bajarish ancha osonlashadi. Bu quyidagicha koʻrinadi:
300 000 000 000 000 000 000 000 = 3 × 10^23 (uch koʻpaytiruv oʻnning yigirma uchinchi darajasi)
0.000 000 000 000 000 000 005 = 5 × 10^(-21) (besh koʻpaytiruv oʻnning minus yigirma birinchi darajasi)
Endi oddiy matematika qoidalari boʻyicha koʻpaytiramiz:
3 × 5 = 1523 + (–21) = 2Natijada:
15 × 10^2 = 1500
Koʻrdingizmi? Ustun qilib yuzlab nollarni yozish oʻrniga, ikki-uchta son va darajalar bilan oddiy arifmetika yetarli. Suzuvchi vergul formati aynan shuni beradi: siz oʻnlab nollari bor uzun "qoʻpol" yozuvlar bilan emas, balki ixcham mantissalar va eksponentalar (darajalar) bilan ishlaysiz.
Endi kompyuterlar va ularning ikkilik tizimiga kelsak. Bu yerda sonlar xuddi shunday tasvirlanadi, faqat sanoq asosi 10 emas, 2 boʻladi, chunki tizim ikkilik. Oddiy soʻzlar bilan aytganda, mantissani biz 10 ning emas, 2 ning darajasiga koʻpaytiramiz.
Maʼnoli qismni olamiz: 1.0010011. Aytaylik, unga 2^(-3) darajasi yozilgan. Bu degani:
1.0010011 × 2^-3 = 0.0010010011
Agar darajani +4 ga oʻzgartirsak, vergul oʻngga "suzib ketadi":
1.0010011 × 2^4 = 10010.011₂
Vergul sonning ichida qayerdadir saqlanmaydi - biz kerakli darajadagi 2 ga koʻpaytirganimiz yoki boʻlganimiz tufayli u xayolan "sakraydi".
Double (64 bit) formatida hamma narsa shunday taqsimlangan:
Mantissa qanchalik uzun boʻlsa, shunchalik koʻp aniq raqamlarni sigʻdirish mumkin; daraja maydoni qanchalik keng boʻlsa, shunchalik katta sonlar diapazoni mavjud boʻladi.
Biz 0.1 taqribiy saqlanishini allaqachon bilamiz. Agar xotirada saqlangan ikkilik mantissani oʻnlik raqamlarga qaytarsak, quyidagini olamiz:
0.1 (xotirada) ≈ 0.10000000000000000555… 0.2 (xotirada) ≈ 0.20000000000000001110…
Bu uzun oʻnlik dumlar - oʻsha "0011 0011..." ni ikkilik tizimdan oʻnlikka qayta hisoblashning oddiy natijasi: aniq moslik yoʻq, shuning uchun koʻplab belgilardan keyin qoʻshimcha beshlar va birlar paydo boʻladi.
Ikkita taqribiy qiymatni binar usulda qoʻshamiz va yangi ikkilik son olamiz, uni yana oʻnlik shaklga oʻgiramiz:
0.30000000000000004441…
Kalkulyator atigi 17 ta maʼnoli raqamni koʻrsatadi, shuning uchun qisqartirilgan variantni koʻramiz: 0.30000000000000004. "Toʻrt" - bu dasturning injiqligi emas, balki yigʻilib qolgan ikkita kichik yaxlitlash xatosining koʻrinadigan choʻqqisidir: biri "oʻndan bir"dan keldi, boshqasi - "yigirmadan bir"dan.
Shunday qilib, kompyuterdagi 0.0001100110011... yozuvi 0.10000000000000000555... ga aylanadi, shunchaki chunki oʻnlik tizimga qayta oʻgirish ikkilik cheksiz kasrni muqarrar kesib tashlashdan keyin yigʻilgan barcha yashirin noaniqliklarni ekranga chiqarib beradi.
Xatolik oʻz-oʻzidan kichik, ammo kattalashishi mumkin. 1991-yilda Patriot zenit tizimi vaqtni 0.1 soniyalik qadamlar bilan hisoblagan. 100 soatlik ishdan soʻng taxminan soniyaning uchdan bir qismi qadar noaniqlik yigʻilib qolgan. Bu radar nishon-raketani oʻtkazib yuborishi uchun yetarli boʻldi. Fojiali holat, ammo xatoning bahosi yuqori boʻlsa, "dumchalar"ni eʼtiborsiz qoldirib boʻlmasligini yaxshi koʻrsatadi.
Mayda qiymatlarni butun son sifatida saqlash. Agar sizga pul muhim boʻlsa, 12.34 ni float sifatida ishlatmang. 1234 tiyinni butun oʻzgaruvchida saqlang. Shunda kutilmagan dumlar paydo boʻlmaydi. Bu "qatʼiy nuqta" (fixed-point) deb ataladi.
Oʻnlik turi. Baʼzi tillarda maxsus decimal turi mavjud boʻlib, u 2 emas, balki 10 asosli sanoq tizimidan foydalanadi. 0.1 kasri aniq ifodalanadi. Faqat bularning barchasi sekinroq ishlaydi.
Hisob-kitoblar oxirida yaxlitlash. Agar baribir float bilan ishlasangiz, hisob-kitoblar zanjirini toʻliq bajarib, keyin kerakli miqdordagi belgilarigacha yaxlitlang. Bu xatoni minimumga tushiradi.