Кіріспе
Сандардың дәлдігі тек компьютер жадымен шектелген есептеулер. Компьютер ғылымында, кез келген дәлдіктегі арифметика, сондай-ақ "бигнум" арифметикасы, көп дәлдікті арифметика немесе кейде шексіз дәлдіктегі арифметика деп аталады, бұл есептеулердің дәлдік таңбалары тек қана хост жүйесінің қолда бар жадымен ғана шектелген сандармен орындалатынын білдіреді. Бұл, әдетте 8-ден 64-ке дейінгі дәлдікті ұсынатын арифметикалық-логикалық құрылғылардың (ALU) аппараттық құралдарында кездесетін жылдам, белгілі бір дәлдіктегі арифметикадан өзгеше. Көптеген қазіргі заманғы бағдарламалау тілдері "бигнумдарды" қолдауға ендірілген, ал басқаларында кез келген дәлдіктегі бүтін сандар мен қозғалмалы нүктелі математика үшін кітапханалар бар. Процессор тіркегішіндегі биттердің белгілі бір саны ретінде мәндерді сақтаудың орнына, осы жүзеге асырулар әдетте өзгермелі ұзындығы бар сандар тізімдерін пайдаланады. Кез келген дәлдік, арифметика жылдамдығы шектеуші фактор болмайтын немесе өте үлкен сандармен нақты нәтижелер қажет болған жағдайларда қолданылады. Оны көптеген компьютерлік алгебра жүйелері ұсынатын символдық есептеумен шатастыруға болмайды, олар сандарды π·sin(2) сияқты өрнектермен көрсетеді және осылайша кез келген есептелетін санды шексіз дәлдікпен көрсете алады.
In computer science, arbitrary precision arithmetic, also called bignum arithmetic, multiple precision arithmetic, or sometimes infinite precision arithmetic, indicates that calculations are performed on numbers whose digits of precision are potentially limited only by the available memory of the host system. This contrasts with the faster fixed precision arithmetic found in most arithmetic logic unit (ALU) hardware, which typically offers between 8 and 64 bits of precision. Several modern programming languages have built in support for bignums, and others have libraries available for arbitrary precision integer and floating point math. Rather than storing values as a fixed number of bits related to the size of the processor register, these implementations typically use variable length arrays of digits. Arbitrary precision is used in applications where the speed of arithmetic is not a limiting factor, or where precise results with very large numbers are required. It should not be confused with the symbolic computation provided by many computer algebra systems, which represent numbers by expressions such as π·sin(2), and can thus represent any computable number with infinite precision.
Қолданбалар
Жалпы қолданылатын тәсіл – ашық кілт криптографиясы, оның алгоритмдері көбінесе жүздеген цифрлары бар бүтін сандармен арифметиканы қолданады. Тағы бір қолданылуы – жасанды шектеулер мен ағып кетудің қажетсіз болатын жағдайларда. Бұл сондай-ақ белгілі бір дәлдіктегі есептеулердің нәтижелерін тексеруге және формулалардағы коэффициенттердің оңтайлы немесе жақын оңтайлы мәндерін анықтауға, мысалы, Гаусс интеграциясында қолданылады. Кез келген дәлдіктегі арифметика π сияқты миллиондаған немесе одан да көп цифрлары бар негізгі математикалық тұрақтыларды есептеу үшін де, цифрлар тізбегінің қасиеттерін талдау үшін немесе жалпы алғанда Риманның зета-функциясы сияқты функциялардың нақты мінез-құлқын зерттеу үшін қолданылады, мұнда кейбір сұрақтарды талдау әдістерімен зерттеу қиын. Тағы бір мысал – Мандельброт жиынындағыдай, өте жоғары үлкейтумен фракталды суреттерді көрсету. Кез келген дәлдіктегі арифметиканы ағып кетуді болдырмау үшін де пайдалануға болады, ол белгілі бір дәлдіктегі арифметиканың өзіндік шектеуі болып табылады. Бес цифрлы спидометрдің 99999-дан 00000-ға дейін өзгеруіне ұқсас, егер сандар белгілі бір дәлдік деңгейінде көрсету үшін тым үлкен болса, белгілі бір дәлдіктегі бүтін сан оралып қайтуы мүмкін. Кейбір процессорлар ағып кетуді қанығу арқылы шеше алады, яғни егер нәтиже көрсетілмейтін болса, ол ең жақын көрсетілетін мәнмен ауыстырылады. (16 биттік қанығу кезінде 65535-ке кез келген оң санды қоссаңыз, нәтиже 65535 болады.) Кейбір процессорлар арифметикалық нәтиже қол жетімді дәлдіктен асып кетсе, қателік хабарламасын (exception) тудыра алады. Қажет болған жағдайда, қателік хабарламасы ұсталып, түзетілуі мүмкін – мысалы, операция кез келген дәлдіктегі арифметиканы қолдана отырып, бағдарламалық қамтамасыз етуде қайта басталуы мүмкін. Көп жағдайда тапсырма немесе бағдарламашы белгілі бір қолданбадағы бүтін сандардың мәні ағып кетуге себеп болатындай үлкен болмайтынын кепілдік бере алады. Мұндай кепілдіктер нақты шектеулерге негізделуі мүмкін: мектепке қатысуды есептеу бағдарламасында 4000 оқушыға шектеу қойылуы мүмкін. Бағдарламашы есептеуді аралық нәтижелер белгіленген дәлдік шегінде қалуы үшін жобалай алады. Lisp, Python, Perl, Haskell, Ruby және Raku сияқты кейбір бағдарламалау тілдері барлық бүтін сандық арифметика үшін кез келген дәлдіктегі сандарды қолданады немесе оны қолдануға мүмкіндік береді. Бұл өнімділікті төмендеткенмен, қарапайым ағып кетуден туындаған дұрыс емес нәтижелерді (немесе қателік хабарламаларын) болдырмайды. Сонымен қатар, ол арифметикалық нәтижелердің барлық машиналарда бірдей болатынына кепілдік береді, машинаның сөз көлеміне қарамастан. Бағдарламалау тілінде кез келген дәлдіктегі сандарды ғана пайдалану тілді жеңілдетеді, өйткені сан – сан болып табылады және әртүрлі дәлдікті білдіретін бірнеше түрдің қажеті жоқ.
Орындау мәселелері
Кездейсоқ дәлдіктегі арифметика, процессор тіркелгіштеріне толығымен сыйып отыратын сандарды қолданатын арифметикадан едәуір баяу, себебі соңғысы әдетте аппараттық арифметикада іске асырылады, ал алғашқысы бағдарламалық қамтамасыз етуде іске асырылуы тиіс. Компьютерде белгілі бір операцияларды (мысалы, бүтін санды бөлу немесе барлық қозғалатын нүктелік операцияларды) орындауға арналған аппараттық құралдар болмаса, оның орнына бағдарламалық қамтамасыз ету ұсынылса да, ол қолданыстағы аппараттық тіркелгіштерге жақын сандық өлшемді пайдаланады: бір немесе екі сөз ғана. Бірақ 1950 және 1960 жылдардағы кейбір өзгермелі сөз ұзындығы машиналары, атап айтқанда IBM 1620, IBM 1401 және Honeywell 200 сериясы, тек қолданыстағы жад көлемімен шектелген сандарды, сондай-ақ мәнді шектеу үшін қосымша битпен өңдей алатын ерекшеліктері болды. Сандар белгілі бір нүкте форматында немесе қозғалатын нүкте форматында, маңызды бөлігін кездейсоқ көрсеткішпен көбейтіп сақталуы мүмкін. Дегенмен, бөлу операциясы бірден сандардың шексіз қайталану тізбектерін (мысалы, ондық жүйеде 4/7 немесе екілік жүйеде 1/10) енгізеді. Егер мұндай жағдай туындаса, өрнек белгілі бір қанағаттанарлық өлшемде қысқартылады немесе рационал сандар қолданылады: алымы мен бөлімі үшін үлкен бүтін сандар. Тіпті ең үлкен ортақ бөлгіш бөлінгеннен кейін де рационал сандармен арифметикалық операциялар тез арада қиынға соғуы мүмкін: 1/99 − 1/100 = 1/9900, ал 1/101 қосылса, нәтиже 10001/999900 болады. Кездейсоқ дәлдіктегі сандардың мөлшері практикада қолданыстағы жад көлемімен және есептеу уақытымен шектеледі. Кез келген дәлдіктегі сандармен арифметикалық операцияларды тиімді орындау үшін көптеген алгоритмдер әзірленді. Атап айтқанда, N цифр қолданылса, алгоритмдер үлкен N үшін асимптотикалық күрделілікті азайтуға бағытталған. Қосу және алу үшін ең қарапайым алгоритмдер, цифрларды тізбектеп қосу немесе алу, қажет болған жағдайда, O(N) алгоритмін береді (үлкен O белгісін қараңыз). Салыстыру да өте қарапайым: айырмашылық табылғанға дейін жоғары реттік цифрларды (немесе машиналық сөздерді) салыстырыңыз. Қалған цифрларды/сөздерді салыстырудың қажеті жоқ. Ең жаман жағдайда (N), бірақ көбінесе ол әлдеқайда жылдам орындалады. Көбейту үшін, сандарды қолмен көбейтуге қолданылатын ең қарапайым алгоритмдер (бастауыш мектепте оқытылатындай) (N²) операцияларды қажет етеді, бірақ O(N log(N) log(log(N))) күрделілігіне жететін көбейту алгоритмдері, мысалы, жылдам Фурье түрлендірулеріне негізделген Шёнхаге-Страссен алгоритмі ойлап табылды. Сондай-ақ, күрделілігі сәл нашаррақ, бірақ кіші N үшін нақты әлемде жақсы өнімділік көрсететін алгоритмдер де бар. Каратсуба көбейтуі осындай алгоритм болып табылады. Бөлу үшін, бөлу алгоритмін қараңыз. Алгоритмдердің тізімі және күрделілік бағалаулары үшін математикалық операциялардың есептеу күрделілігін қараңыз. x86 тіліндегі мысалдар үшін сыртқы сілтемелерді қараңыз.
The simplest algorithms are for addition and subtraction, where one simply adds or subtracts the digits in sequence, carrying as necessary, which yields an O(N) algorithm (see big O notation). Comparison is also very simple. Compare the high order digits (or machine words) until a difference is found. Comparing the rest of the digits/words is not necessary. The worst case is (N), but usually it will go much faster. For multiplication, the most straightforward algorithms used for multiplying numbers by hand (as taught in primary school) require (N^(2)) operations, but multiplication algorithms that achieve O(N log(N) log(log(N))) complexity have been devised, such as the Schönhage–Strassen algorithm, based on fast Fourier transforms, and there are also algorithms with slightly worse complexity but with sometimes superior real world performance for smaller N. The Karatsuba multiplication is such an algorithm. For division, see division algorithm. For a list of algorithms along with complexity estimates, see computational complexity of mathematical operations. For examples in x86 assembly, see external links.
Алдын ала орнатылған дәлдік
Кейбір тілдерде, мысалы REXX-те, барлық есептеулердің дәлдігі есептеу жасау алдында белгіленуі тиіс. Python және Ruby сияқты басқа тілдер ағып кетуді болдырмау үшін дәлдікті автоматты түрде кеңейтеді.
Тарих
IBM-нің алғашқы бизнес-компьютері, IBM 702 (вакуумдық түтіктермен жұмыс істейтін машина) 1950-ші жылдардың ортасында 1-ден 511-ге дейінгі кез келген ұзындықтағы цифрлар тізбегінде бүтін сандар арифметикасын толығымен аппараттық түрде іске асырды. Кез келген дәлдіктегі арифметиканың ең алғашқы кең таралған бағдарламалық іске асырылуы, балама жолымен Maclisp-те болды. Кейін, шамамен 1980 жылы, VAX/VMS және VM/CMS операциялық жүйелері үлкен сандармен жұмыс істеу мүмкіндіктерін бір жағынан тізбек функциялары жиынтығы ретінде, екінші жағынан EXEC 2 және REXX тілдерінде ұсынды. Алғашқы кең таралған іске асыру 1959–1970 жылдардағы IBM 1620 арқылы қолжетімді болды. 1620 – дискретті транзисторларды қолданған ондық цифрлы машина, бірақ ол цифрлар тізбегінде бүтін сандар арифметикасын орындау үшін аппараттық құралдарға (іздеу кестелерін пайдалана отырып) ие болды, оның ұзындығы екі цифрдан бастап қолданылатын жадтың көлеміне дейін болатын. Қабаттасқан нүктелік арифметика үшін мантисса жүз цифрдан кем болуы керек еді, ал көрсеткіш тек екі цифрмен шектелді. Ең үлкен жад 60 000 цифрды ұсынды, бірақ 1620 үшін Fortran компиляторлары 10 сияқты белгілі бір өлшемдерге тоқтады, әдепкі өлшем қанағаттандырмаса, оны басқару картасында көрсетуге болады.
Бағдарламалық кітапханалар
Көптеген компьютерлік бағдарламалық жасақтамаларда кездейсоқ дәлдіктегі арифметика, қажетті дәлдікте сандарды сақтау және есептеулерді орындау үшін дерек түрлері мен кіші бағдарламаларды ұсынатын сыртқы кітапхананы шақыру арқылы іске асырылады. Әртүрлі кітапханаларда кездейсоқ дәлдіктегі сандарды бейнелеудің әртүрлі әдістері бар, кейбір кітапханалар тек бүтін сандармен жұмыс істейді, ал басқалары жылжымалы нүктелі сандарды әртүрлі негіздерде (ондық немесе екілік дәрежелерде) сақтайды. Бір санды жалғыз мән ретінде бейнелеудің орнына, кейбір кітапханалар санды бөлім/бөлшектен тұратын жұп ретінде сақтайды (рационал сандар), ал кейбіреулері есептеуге болатын сандарды толық бейнелей алады, бірақ тек белгілі бір сақтау лимитіне дейін. Негізінде, Тьюринг машиналарының барлық нақты сандарды бейнелеу мүмкіндігі жоқ, себебі сандар жиынының кардиналдығы сандар жиынының кардиналдығынан асып түседі.