संख्याओं को छोटे भागों के रूप में व्यवहार करना पर्याप्त भंडारण और एल्गोरिदम की बात है। मान लेते हैं कि आपके पास एक कंपाइलर है, जो int
केवल 99 के माध्यम से 0 हो सकता है और आप 999999 तक संख्याओं को संभालना चाहते हैं (हम इसे सरल रखने के लिए केवल सकारात्मक संख्याओं के बारे में चिंता करेंगे)।
आप ऐसा करते हैं कि प्रत्येक संख्या को तीन int
एस देकर और समान नियमों का उपयोग करके (आपके पास) इसके अलावा, घटाव और अन्य बुनियादी कार्यों के लिए प्राथमिक विद्यालय में वापस सीखा है।
एक मनमाने ढंग से सटीक लाइब्रेरी में, हमारी संख्याओं का प्रतिनिधित्व करने के लिए उपयोग किए जाने वाले आधार प्रकारों की संख्या पर कोई निश्चित सीमा नहीं है, बस जो भी मेमोरी पकड़ सकती है।
उदाहरण के लिए 123456 + 78
:
12 34 56
78
-- -- --
12 35 34
कम से कम महत्वपूर्ण छोर से कार्य करना:
- प्रारंभिक कैरी = ०।
- 56 + 78 + 0 कैरी = 134 = 34 1 कैरी के साथ
- 34 + 00 + 1 कैरी = 35 = 35 कैरी 0 के साथ
- 12 + 00 + 0 कैरी = 12 = 12 के साथ 0 कैरी
यह वास्तव में, आपके सीपीयू के अंदर बिट स्तर पर आम तौर पर कैसे काम करता है, इसके अतिरिक्त है।
घटाव समान है (आधार प्रकार के घटाव का उपयोग करना और कैरी के बजाय उधार लेना), गुणा बार-बार परिवर्धन (बहुत धीमी गति से) या क्रॉस-उत्पाद (तेज) के साथ किया जा सकता है और विभाजन पेचीदा होता है, लेकिन संख्याओं के स्थानांतरण और घटाव के द्वारा किया जा सकता है शामिल (लंबे विभाजन को आपने एक बच्चे के रूप में सीखा होगा)।
मैंने वास्तव में पुस्तकालयों को दस की अधिकतम शक्तियों का उपयोग करके इस तरह का सामान करने के लिए लिखा है जो कि एक पूर्णांक में फिट हो सकते हैं जब चुकता (दो से int
एक साथ गुणा करने पर अतिप्रवाह को रोकने के लिए , जैसे कि 16-बिट int
को 99 से 0 तक सीमित किया जा रहा है। 9,801 (<32,768) उत्पन्न करते हैं, जब चुकता होता है, या int
99,80,001 (<2,147,483,648) उत्पन्न करने के लिए 9,999 के माध्यम से 0 का उपयोग करके 32-बिट होता है, जिसने एल्गोरिदम को बहुत कम कर दिया।
बाहर देखने के लिए कुछ ट्रिक्स।
1 / संख्याओं को जोड़ने या गुणा करने पर, आवश्यक अधिकतम स्थान पूर्व-आवंटित करें बाद में कम करें यदि आपको लगता है कि यह बहुत अधिक है। उदाहरण के लिए, दो 100- "अंक" (जहां अंक एक है int
) संख्याओं को जोड़ना आपको 101 अंकों से अधिक कभी नहीं देगा। 12 अंकों की संख्या को 3 अंकों की संख्या से गुणा करें, कभी भी 15 अंकों से अधिक नहीं होगा (अंकों की संख्या जोड़ें)।
2 / अतिरिक्त गति के लिए, नंबरों को सामान्य करें (यदि आवश्यक हो तो स्टोरेज को कम करें) केवल अगर पूरी तरह से आवश्यक हो - मेरे पुस्तकालय में यह एक अलग कॉल था, इसलिए उपयोगकर्ता गति और भंडारण चिंताओं के बीच निर्णय ले सकता है।
3 / एक सकारात्मक और ऋणात्मक संख्या का जोड़ घटाना है, और एक ऋणात्मक संख्या को घटाना समान धनात्मक को जोड़ना है। आप ऐड को एडजस्ट करने और संकेतों को एडजस्ट करने के बाद एक-दूसरे को कॉल करने के लिए काफी कोड बचा सकते हैं।
4 / छोटे संख्याओं से बड़ी संख्या को घटाने से बचें क्योंकि जब तक आप संख्याओं को समाप्त नहीं करते हैं, जैसे:
10
11-
-- -- -- --
99 99 99 99 (and you still have a borrow).
इसके बजाय, 11 से 10 घटाएं, फिर इसे नकारें:
11
10-
--
1 (then negate to get -1).
यहां उन पुस्तकालयों में से एक से टिप्पणी (पाठ में बदल गई) जो मुझे इसके लिए करनी थी। कोड ही, दुर्भाग्य से, कॉपीराइट है, लेकिन आप चार बुनियादी कार्यों को संभालने के लिए पर्याप्त जानकारी लेने में सक्षम हो सकते हैं। निम्नलिखित में मान लें कि -a
और -b
ऋणात्मक संख्याओं का प्रतिनिधित्व करते हैं a
और b
शून्य या सकारात्मक संख्या हैं।
इसके अलावा , यदि संकेत अलग-अलग हैं, तो नकार के घटाव का उपयोग करें:
-a + b becomes b - a
a + -b becomes a - b
के लिए घटाव , लक्षण अलग हैं, निषेध का उपयोग इसके अलावा:
a - -b becomes a + b
-a - b becomes -(a + b)
यह भी सुनिश्चित करने के लिए कि हम बड़ी संख्या से छोटी संख्या घटा रहे हैं:
small - big becomes -(big - small)
गुणन निम्नानुसार प्रविष्टि स्तर के गणित का उपयोग करता है:
475(a) x 32(b) = 475 x (30 + 2)
= 475 x 30 + 475 x 2
= 4750 x 3 + 475 x 2
= 4750 + 4750 + 4750 + 475 + 475
जिस तरह से इसे हासिल किया जाता है, उसमें एक समय (पीछे की तरफ) 32 अंकों में से प्रत्येक को निकालना शामिल होता है, फिर परिणाम में जोड़े जाने वाले मूल्य की गणना करने के लिए ऐड का उपयोग करना (शुरू में शून्य)।
ShiftLeft
और ShiftRight
ऑपरेशन को LongInt
रैप वैल्यू (10 के लिए "वास्तविक" गणित) से जल्दी से गुणा या विभाजित करने के लिए उपयोग किया जाता है । ऊपर के उदाहरण में, हम 475 को शून्य से 2 गुना (32 का अंतिम अंक) जोड़कर 950 प्राप्त करते हैं (परिणाम = 0 + 950 = 950)।
फिर हमने 4750 प्राप्त करने के लिए 475 को छोड़ दिया और 3. पाने के लिए दाईं ओर 32 को स्थानांतरित किया। 14250 को प्राप्त करने के लिए 4750 को शून्य से 3 गुना जोड़ें और फिर 950 के परिणाम में जोड़कर 15200 प्राप्त करें।
लेफ्ट शिफ्ट 4750 47500 पाने के लिए, राइट शिफ्ट 3 पाने के लिए 0. क्योंकि राइट शिफ्ट 32 अब शून्य है, हम समाप्त हो चुके हैं और वास्तव में 475 x 32 15200 के बराबर है।
विभाजन भी मुश्किल है लेकिन प्रारंभिक अंकगणित ("" में चला जाता है "" के लिए "gazinta" विधि) पर आधारित है। निम्नलिखित के लिए लंबे विभाजन पर विचार करें 12345 / 27
:
457
+-------
27 | 12345 27 is larger than 1 or 12 so we first use 123.
108 27 goes into 123 4 times, 4 x 27 = 108, 123 - 108 = 15.
---
154 Bring down 4.
135 27 goes into 154 5 times, 5 x 27 = 135, 154 - 135 = 19.
---
195 Bring down 5.
189 27 goes into 195 7 times, 7 x 27 = 189, 195 - 189 = 6.
---
6 Nothing more to bring down, so stop.
इसलिए 12345 / 27
है 457
शेष के साथ 6
। सत्यापित करें:
457 x 27 + 6
= 12339 + 6
= 12345
इसे 12345 के सेगमेंट को नीचे लाने के लिए एक ड्रॉ-डाउन वेरिएबल (शुरू में शून्य) का उपयोग करके लागू किया जाता है, जब तक कि यह 27 से अधिक या बराबर न हो।
तब हम केवल 27 को घटाते हैं जब तक कि हम 27 से नीचे नहीं निकल जाते - घटाव की संख्या शीर्ष रेखा में जोड़ा गया खंड है।
जब नीचे लाने के लिए अधिक खंड नहीं हैं, तो हमारे पास हमारा परिणाम है।
ध्यान रखें कि ये बहुत बुनियादी एल्गोरिदम हैं। यदि आपके अंक विशेष रूप से बड़े होने जा रहे हैं तो जटिल अंकगणित करने के बेहतर तरीके हैं। आप ग्नू मल्टीपल प्रिसिजन अरिथमेटिक लाइब्रेरी जैसी किसी चीज़ में देख सकते हैं - यह मेरे अपने पुस्तकालयों की तुलना में काफी बेहतर और तेज़ है।
इसमें यह दुर्भाग्यपूर्ण मिसफिट है कि यह केवल बाहर निकल जाएगा यदि यह स्मृति से बाहर निकलता है (मेरी राय में एक सामान्य उद्देश्य पुस्तकालय के लिए एक घातक दोष) लेकिन, अगर आप अतीत को देख सकते हैं, तो यह क्या करता है पर बहुत अच्छा है।
यदि आप इसका उपयोग लाइसेंसिंग कारणों से नहीं कर सकते हैं (या क्योंकि आप अपने आवेदन को बिना किसी स्पष्ट कारण के बाहर निकालना चाहते हैं), तो आप कम से कम एल्गोरिदम को अपने कोड में एकीकृत करने के लिए वहां से प्राप्त कर सकते हैं।
मैंने यह भी पाया है कि एमपीआईआर (जीएमपी का एक कांटा) पर बॉड्स संभावित परिवर्तनों पर चर्चा करने के लिए अधिक उत्तरदायी हैं - वे एक अधिक डेवलपर-अनुकूल गुच्छा लगते हैं।