Python Max Int: arbitrary precision butun sonlarni tushunish
Python'dagi maksimal butun son qiymati qiziqtiradimi? Arbitrary precision qanday ishlashini, nega overflow muammo emasligini va qochish kerak bo'lgan keng tarqalgan tuzoqlarni bilib oling.
Muallif: Kimberly Fessel
Juda-juda katta sonlarni yaxshi ko'rasizmi? Hech butun sonni o'ta katta darajaga ko'tarish yoki suv tomchisidagi molekulalar sonini sanash istagi paydo bo'lganmi? Agar shunday bo'lsa, Python aynan siz uchun til bo'lishi mumkin. Ba'zi boshqa dasturlash tillaridan farqli o'laroq, Python butun sonlarining kattaligiga chegara qo'ymaydi. U kerak bo'lganda butun sonlar uchun ko'proq joy ajratadi, bu esa ularni arbitrary-precision obyektlarga aylantiradi va ularni faqat kompyuteringiz xotirasi hajmi bilan cheklaydi.
Ushbu maqolada maksimal butun son qiymatining yo'qligi Python kodingiz uchun nimani anglatishini tahlil qilamiz. Python'ning ba'zi funksiyalari katta butun sonlar bilan qanday ishlashini bilib olasiz, shuningdek, data science yoki boshqa Python dasturlaringizda katta butun sonlar paydo bo'lganda duch kelishingiz mumkin bo'lgan bir nechta muhim "tuzoqlar" haqida sizni ogohlantiramiz.
Python'dagi butun sonlar va butun son o'lchami haqida umumiy ma'lumot
Hisoblash yoki matematik ma'nodagi butun sonlar — kasr, ya'ni o'nli qismi bo'lmagan sonlar. Ular musbat, manfiy yoki nol bo'lishi mumkin. Python'da butun sonlar int data type'iga tegishli.
x = 44
type(x)
# Expected result:
# <class 'int'>
Kompyuterlar ma'lumotlarni bit'lar ko'rinishida saqlaydi: bit'lar qancha ko'p bo'lsa, shuncha katta qiymatni ifodalash mumkin. Har bir bit ikki qiymatdan birini (0 yoki 1) qabul qilishi mumkin va mumkin bo'lgan qiymatlar soni qo'shilgan bit'lar bilan eksponensial ravishda o'sadi. Masalan, 8 bit 256 xil qiymatni ifodalay oladi; 64 bit esa taxminan 18 kvintillion qiymatni qabul qila oladi.
Ko'pgina dasturlash tillari int16 yoki int32 kabi turli data type variantlariga ega fixed-width butun sonlardan foydalanadi. Bu fixed-width type'lar har bir qiymat uchun aniq miqdordagi bit'dan foydalanadi va ularning har biri maksimal butun son o'lchamiga ega. Masalan, Java'da int8 yaratsangiz, o'sha butun son uchun 8 bit ajratasiz. Shunda bu butun sonning qiymati -128 dan maksimal 127 gacha bo'lishi mumkin (nolni ham qo'shganda 256 ta mumkin bo'lgan qiymat).
Boshqa tillardan farqli o'laroq, Python qat'iy belgilangan butun son o'lchamlaridan foydalanmaydi. Buning o'rniga butun sonlar arbitrary precision'ga amal qiladi, ya'ni kompyuteringizda yetarli xotira bo'lsa, ular istalgancha kattalashishi mumkin. Butun son joriy bit'lari ruxsat bergan qiymatdan kattalashganda, Python uni saqlash uchun dinamik ravishda ko'proq xotira ajratadi.
Python int type'i
Python'da bir nechta turli butun son data type'lari (int32, int64 va hokazo) o'rniga kichik va katta butun son literal'larini avtomatik ravishda qayta ishlaydigan int nomli yagona data type mavjud. Butun sonlarning minimal yoki maksimal qiymati yo'q; ularning absolyut qiymati xotira tugaguncha o'sishi mumkin.
Tillar har bir butun son uchun qat'iy saqlash hajmini talab qilganda, har bir data type'ning qat'iy minimal va maksimal butun son qiymati bo'ladi. Bu chegaradan chiqishga urinish numerical overflow'ga olib keladi. Aytaylik, C'da x'ni int8 sifatida yaratib, unga 127 qiymatini berdingiz. Agar keyinroq unga 1 qo'shsangiz, x maksimal butun son o'lchamidan oshib ketadi, aylanib boshiga qaytadi va -128 ga aylanadi.
Python bu muammodan arbitrary-precision butun sonlardan foydalanish orqali qochadi: qiymatlar o'sganda kerakligicha ko'proq xotira ajratadi. Bu shuni anglatadiki, Python hisob-kitoblaringizda odatda overflow'ni ko'rmaysiz.
Shunga qaramay, Python'da sys.maxsize deb ataladigan attribute mavjud. sys.maxsize Python'ning maksimal butun son o'lchamini ifodalaydi deb o'ylashingiz mumkin, lekin ma'lum bo'lishicha, sys.maxsize butunlay boshqa maqsadga xizmat qiladi.
sys.maxsize bilan maksimal butun son o'lchami va 32-bit farqlari
sys.maxsize attribute'i Python standart kutubxonasidagi sys modulidan keladi. U sizga tizimga xos parametrlar va funksiyalarga kirish imkonini beradi.
import sys
print(sys.maxsize)
# Expected result:
9223372036854775807
Ba'zi odamlar bu qiymatni o'z tizimlari ruxsat beradigan eng katta butun son deb noto'g'ri talqin qilishadi; biroq sys.maxsize Python'ning maksimal butun son o'lchami emas. U tizimingizdagi Py_ssize_t type'ining eng katta musbat qiymatini ifodalaydi. Ichki tomondan u CPython tomonidan container'ning maksimal uzunligi yoki eng katta yaroqli index kabi narsalar uchun ishlatiladi. U Python saqlay oladigan maksimal butun sonni bermaydi. Siz sys.maxsize'dan ancha katta qiymatlarni hech qanday muammosiz yaratishingiz mumkin.
import sys
print(sys.maxsize + 1)
print(2**100)
# Expected result:
9223372036854775808
1267650600228229401496703205376
64-bit tizimlarda sys.maxsize sifatida 9223372036854775807, ya'ni 2**63 - 1 ni ko'rasiz. Biroq agar eskiroq 32-bit tizimda ishlayotgan bo'lsangiz, kichikroq qiymatni ko'rasiz: 2147483647 yoki 2**31 - 1. Bu shuni anglatadiki, 32-bit Python build'ida list'lar, tuple'lar, string'lar va boshqa container'larning eng katta uzunligi 64-bit build'dagiga qaraganda kichikroq.
sys.maxsize ba'zi implementatsiya tafsilotlarini cheklasa-da, u oddiy butun son arifmetikasiga ta'sir qilmaydi. Python funksiyalari sys.maxsize'dan katta butun sonlar bilan ham ishlashda davom etadi.
Katta butun sonlar bilan ishlaydigan built-in funksiyalar
Python'da butun sonlar an'anaviy int32 yoki int64 chegaralaridan ancha oshib ketishi mumkin. Yaxshiyamki, katta butun sonlar bilan ishlash uchun sizga maxsus operator'lar yoki funksiyalar kerak bo'lmaydi. Ko'pgina built-in funksiyalar butun son ikki xonali bo'ladimi yoki ikki ming xonali bo'ladimi, bir xil ishlaydi. Bu yerda maksimal butun son o'lchami bo'lmagan holda ham izchil ishlaydigan bir nechta funksiyani ko'rib chiqamiz. Istalgancha katta butun sonlarda floor division float division'dan farqli o'laroq aniq bo'lib qoladi.

pow(base, exp, mod)
Python'ning built-in pow() funksiyasi asos qiymatni darajaga ko'taradi va ixtiyoriy ravishda natijaga modulo operator'ni qo'llaydi.
print(pow(3, 2))
print(pow(3, 2, 2))
# Expected result:
# 9
# 1
pow() darajaga ko'tarishni overflow'siz oson bajaradi va natijaviy butun son kattalashib borsa ham ** operator'i bilan bir xil qiymatlarni hosil qiladi.
print(pow(2, 100))
# Expected result:
# 1267650600228229401496703205376
pow()'ning ixtiyoriy uchinchi argumenti darajaga ko'tarish natijasining modulo'sini samarali topish imkonini beradi. Avval to'liq darajaga ko'tarishni bajarib, keyin modulo'ni olish o'rniga Python modular exponentiation'ni bajaradi va ulkan oraliq butun sonni hosil qilish zaruratidan qochadi. Bu ayniqsa kriptografiya va modular arifmetika bilan bog'liq boshqa sohalarda juda foydali.
print(pow(2, 10000000, 17))
# Expected result:
# 1
math.isqrt(n)
math.isqrt() funksiyasi Python standart kutubxonasining bir qismi bo'lgan math modulidan keladi. Undan manfiy bo'lmagan butun sonning butun kvadrat ildizini topish uchun foydalaning; aniqrog'i, u kvadrati kiritilgan qiymatdan kichik yoki unga teng bo'lgan eng katta qiymatni beradi.
import math
math.isqrt(27)
# Expected result:
# 5
math modulidagi oddiy kvadrat ildiz funksiyasi math.sqrt() floating-point natija qaytaradi. math.isqrt() esa buning o'rniga butun son qaytaradi. Bu shuni anglatadiki, u math.sqrt() kabi floating-point diapazoni bilan cheklanmagan. Istalgancha katta kiritilgan qiymatlar uchun ham aniq butun son natijasini olasiz.
import math
print(math.isqrt(10**100))
# Expected result:
# 100000000000000000000000000000000000000000000000000
Yodda tuting, math.isqrt() kiritiladigan qiymat butun son bo'lishini kutadi va float bersangiz TypeError ko'taradi. U sizga aniq butun son natijasi kerak bo'lgan holatlarda, masalan, tub sonlarni yoki to'liq kvadratlarni tekshirishda eng ko'p foyda beradi.
math.factorial(n)
Agar Python'ning hayratlanarli darajada katta butun sonlarini amalda ko'rishni chindan xohlasangiz, xuddi shu math modulidagi math.factorial()'ni sinab ko'ring. Bu funksiya 1 dan kiritilgan qiymatgacha bo'lgan barcha musbat butun sonlarni ko'paytirish orqali manfiy bo'lmagan butun sonning faktorialini beradi:
5!=5⋅4⋅3⋅2⋅1=1205! = 5 \cdot 4 \cdot 3 \cdot 2 \cdot 1 = 1205!=5⋅4⋅3⋅2⋅1=120
import math
print(math.factorial(5))
# Expected result:
# 120
Faktoriallar juda katta qiymatlar hosil qilishi bilan mashhur, lekin yetarli vaqt va bo'sh xotira bo'lsa, Python maksimal butun son o'lchamiga ega bo'lmagani uchun overflow'siz aniq natijalarni bera oladi. Masalan, 1000 ning faktoriali 2 568 xonali natija beradi. (Sizni to'liq qiymatni chiqarishdan xalos qilamiz va shunchaki xonalarini sanab beramiz.)
import math
len(str(math.factorial(1000)))
# Expected result:
# 2568
Ko'pgina tillarda faktoriallar tezda maksimal butun son o'lchamidan oshib ketadi, lekin yetarli bo'sh xotira bo'lsa, Python natija qancha xonadan iborat bo'lishidan qat'i nazar aniq natijalar berishda davom etadi.
Data type'lar, xotira va data science bilan bog'liq jihatlar
Python'ning built-in int data type'i istalgancha katta qiymatlarni qo'llab-quvvatlaydi, lekin har bir kutubxona ham bir xil yondashuvga amal qilmaydi. Data science kutubxonalari tezlik va xotira samaradorligi uchun ko'pincha qat'iy o'lchamli butun sonlardan foydalanadi. Kodingizda ularni hisobga olishingiz uchun bu farqlarning ba'zilarini ko'rib chiqamiz.
NumPy'dagi fixed-width butun sonlar
Mashhur sonli tahlil kutubxonasi NumPy sukut bo'yicha Python'ning built-in int data type'idan foydalanmaydi. Buning o'rniga u np.int8, np.int16, np.int32 va np.int64 kabi fixed-width data type'larga tayanadi, bu yerda np — NumPy uchun keng tarqalgan alias. U katta massivlarni samarali saqlash va sonli hisob-kitoblarni tezlashtirish uchun shu fixed-width type'lardan foydalanadi. Endi bu qiymatlar overflow'ga uchrashi mumkin; biroq NumPy ko'pincha kerak bo'lganda qiymatlarni aqlli tarzda yuqoriroq data type'larga o'tkazadi.
import numpy as np
x = np.int8(127)
print(x)
print(x + 1) # Promoted data type
print(np.int8(x + 1)) # Forced data type, overflow
# Expected result:
# 127
# 128
# -128
Ma'lumotlar tahlili uchun yana bir mashhur kutubxona — pandas NumPy'dan ancha ko'p narsani meros qilib olgan. Natijada u ham sukut bo'yicha fixed-width butun son type'laridan (int16, int32, int64 va hokazo) foydalanadi. pandas NumPy ustiga qurilgani uchun unda ham xuddi shunday qat'iy o'lchamli butun son xatti-harakati va overflow ehtimoli mavjud.
import pandas as pd
import numpy as np
df = pd.DataFrame({
"values": np.array([127], dtype=np.int8)
})
df["values"] = df["values"] + 1
print(df)
print(df.dtypes)
# Expected result:
# values
# 0 -128
# values int8
# dtype: object
Amalda NumPy massivlaringiz va pandas dataframe'laringizning dtype'idan xabardor bo'lishingiz kerak. Mos butun son type'ini tanlash kutilmagan overflow yoki xotira muammolarining oldini olishi mumkin. Har doim Python'ning int data type'iga qaytishingiz mumkin, lekin buni qilayotganda samaradorlik va cheklanmagan butun sonlar o'rtasidagi tradeoff'larni yodda tuting.
Arbitrary precision'ning xotira narxi
Python'ning istalgancha katta butun sonlari sizga erkinlik va moslashuvchanlik beradi, lekin dunyoda tekin narsa yo'q. Yodda tutingki, butun sonlar o'sgani sari ular kompyuteringizda ko'proq xotira talab qiladi. Oxir-oqibat katta qiymatlar kichiklariga qaraganda ko'proq joy egallaydi.
Fixed-width butun sonlarga tayanadigan tillar har bir qiymat uchun oldindan ma'lum miqdordagi xotiradan foydalanadi. Biroq Python'da maksimal butun son o'lchamiga chegara bo'lmagani uchun kerakli joy o'zgarib turadi va butun sonlar o'sgani sari siljishi mumkin.
Amalda katta Python butun sonlari uchun qo'shimcha overhead'ni ko'pincha sezmaysiz. Xotira sarfi va hisoblash vaqtining sekinlashishi ehtimoli faqat o'ta katta butun sonlar yoki ularning katta to'plamlari bilan ishlaganda e'tiborga loyiq bo'ladi. Agar xotira yoki unumdorlik haqiqatan ham muammoga aylansa, NumPy kabi kutubxonalar qilganidek, fixed-width butun son type'lariga o'tishga qaror qilishingiz mumkin.
Katta butun sonlar bilan ishlashdagi keng tarqalgan xatolar
Python'da katta butun sonlar bilan ishlash haqida gap ketganda, bilishingiz kerak bo'lgan yana bir nechta keng tarqalgan "tuzoqlar" bor. Ulardan qoching, shunda kodingiz sizga albatta minnatdor bo'ladi.
Python butun sonlari boshqa tillardagidek ishlashini kutish
Agar C, C++ yoki Java kabi boshqa dasturlash tillariga o'rganib qolgan bo'lsangiz, MAX_INT yoki Integer.MAX_VALUE'ning Python'dagi ekvivalentini qidirayotgan bo'lishingiz mumkin. Python'da bunga ekvivalent maksimal butun son o'lchami yo'q. int data type'i uchun qat'iy belgilangan maksimal yoki minimal qiymat mavjud emas.
Agar fixed-width type'larga ega boshqa tillardan kelayotgan bo'lsangiz, butun sonlar odatda 32 yoki 64 bit joy egallashiga ham o'rganib qolgan bo'lishingiz mumkin. Python'da butun sonlar bunday ishlamaydi. Python butun sonlar kattalashgani yoki kichrayganiga qarab dinamik ravishda ko'proq yoki kamroq joy ajratadi.
Natijada, agar sonli hisob-kitoblarni bajarishda overflow'dan xavotirlansangiz, xavotirlanmang. Python'ning built-in int type'i bilan ishlaganda integer overflow odatda muammo bo'lmaydi. Buning o'rniga sizning amaliy chegaralaringiz — yetarli xotiraga ega bo'lish va o'ta katta qiymatlar uchun unumdorlik.
float('inf') butun son emas
Ba'zan dasturchilarga boshqa har qanday qiymatdan kattaroq (yoki kichikroq) bo'lishi kafolatlangan boshlang'ich placeholder'lar kerak bo'ladi. Python musbat cheksizlikni ifodalash uchun float('inf')'ni taqdim etadi. U foydali bo'lsa-da, uning qanday aniqlanganiga diqqat bilan e'tibor berishingiz kerak; xususan, float('inf') butun son emas.
print(type(float('inf')))
print(type(10**100))
# Expected result:
# <class 'float'>
# <class 'int'>
Bu muhim, chunki float('inf')'ni butun son kiritilishini talab qiladigan Python funksiyalariga uzata olmaysiz. Masalan, float('inf')'ni range(), math.isqrt() yoki math.factorial()'ga argument sifatida bersangiz, TypeError olasiz.
Yodda tuting, float('inf') floating-point hisob-kitoblari uchun cheksizlikni ifodalaydi. Python funksiyasi yoki amali int data type'ini kutganda u butun sonlar uchun mos o'rinbosar emas. Bu, shuningdek, float('inf') Python'ning maksimal butun son qiymati emasligini ham anglatadi. Bundan tashqari, float cheksizlikni butun songa aylantira olmaysiz; bunga urinish paradoksal ravishda OverflowError beradi.
Xulosa
Agar Python'da maksimal butun son qiymatini qidirayotgan bo'lsangiz, uni topa olmaysiz — Python'da maksimal butun son yo'q. Python'da butun sonlar fixed-width butun sonlar (int32, int64 va hokazo) o'rniga arbitrary precision'ga ega. Ular kompyuteringiz xotirasi ruxsat bergancha kattalashishi mumkin. math.factorial() va pow() kabi keng tarqalgan funksiyalar kichik butun sonlarda ham, katta butun sonlarda ham ishlaydi va odatda boshqa dasturlash tillari duch keladigan overflow muammolari haqida qayg'urishingizga hojat qolmaydi.
Bu moslashuvchanlik o'z tradeoff'lari bilan keladi. O'ta katta butun sonlar yoki katta qiymatlarning ulkan to'plamlari bilan ishlaganda xotira yoki unumdorlik muammolarini sezishingiz mumkin. NumPy va pandas kabi unumdorlikka yo'naltirilgan kutubxonalar sukut bo'yicha aynan qat'iy o'lchamli butun sonlarga tayanishining sabablaridan biri shu.
Python'da maksimal butun son nega mavjud emasligini va bu dizaynning tradeoff'larini o'rganish uchun bir oz vaqt ajratib, AI Tutor bilan muloqot qiling. Boshlash uchun mana bu prompt: