एक भाषा में बहुत बड़ी संख्या को संभालना जो नहीं कर सकते हैं?


15

मैं यह सोचने की कोशिश कर रहा हूं कि यदि भाषा निर्माण एक निश्चित मूल्य से बड़ी संख्या से निपटने में असमर्थ है, तो मैं बहुत बड़ी संख्या में गणना करने के लिए (इनफिनिटम - इन्टर नो फ्लॉट्स) करने के बारे में कैसे जाऊंगा।

मुझे यकीन है कि मैं यह सवाल पूछने वाला पहला और आखिरी नहीं हूं लेकिन मैं जिन खोज शब्दों का उपयोग कर रहा हूं, वे मुझे उन स्थितियों को संभालने के लिए एक एल्गोरिथम नहीं दे रहे हैं। बल्कि अधिकांश सुझाव भाषा परिवर्तन या परिवर्तनशील प्रस्ताव देते हैं, या उन चीजों के बारे में बात करते हैं जो मेरी खोज के लिए अप्रासंगिक हैं। इसलिए मुझे थोड़ी गाइडेंस की जरूरत है।

मैं इस तरह एक एल्गोरिथ्म बाहर स्केच करेंगे:

  1. भाषा के लिए पूर्णांक चर की अधिकतम लंबाई निर्धारित करें।

  2. यदि कोई संख्या चर की अधिकतम लंबाई के आधे से अधिक लंबाई है, तो इसे एक सरणी में विभाजित करें। (थोड़ा खेलने का कमरा दें)

  3. सरणी क्रम [0] = सबसे अधिक संख्या दाईं ओर [n-max] = बाईं ओर सबसे अधिक संख्या

    पूर्व। संख्या: 29392023 ऐरे [0]: 23, ऐरे [1]: 20, ऐरे [2]: 39, ऐरे [3]: 29

चूँकि मैंने चर की आधी लंबाई को मार्क ऑफ़ पॉइंट के रूप में स्थापित किया है, तो मैं आधे रास्ते के निशान वाले दसवें, सौवें, आदि की गणना कर सकता हूँ, ताकि अगर चर की अधिकतम लंबाई 0 से 9999999999 तक 10 अंक हो, तो मुझे पता है कि पांच अंकों तक आधा करके मुझे कुछ खेलने का कमरा दें।

इसलिए अगर मैं जोड़ूं या बढ़ाऊं तो मेरे पास एक चर चेकर फ़ंक्शन हो सकता है जो यह देखता है कि सरणी का छठा अंक (दाएं से) [0] सरणी के पहले अंक (दाएं से) के समान स्थान है [1]।

विभाजन और घटाव के अपने मुद्दे हैं जिनके बारे में मैंने अभी तक नहीं सोचा है।

मैं कार्यक्रम की तुलना में बड़ी संख्या में समर्थन के सर्वोत्तम कार्यान्वयन के बारे में जानना चाहूंगा।


1
पहली बात जो दिमाग में आती है वह है जावा की बिगइन्टेगर
इवान

क्या यह एक ऐसी भाषा है जिसे यहां कोई भी जान सकता है और विशिष्ट सिफारिशें करने में सक्षम हो सकता है, या यह कुछ अस्पष्ट और मालिकाना है?
FrustratedWithFormsDesigner

मुझे नहीं पता कि मैं इसके लिए कौन सी भाषा चाहूंगा। मुझे पता है कि php सबसे ज्यादा है लेकिन मैं इसे उस भाषा में नहीं करना चाहता। लिस्प आकर्षक है क्योंकि मैंने जो पढ़ा है, उसकी लंबाई की कोई सीमा नहीं है। हालाँकि, यह जानने का मेरा व्यक्तिगत दोष यह है कि यह कैसे काम करता है मुझे एक द्वीप पर फंस जाने पर इसे क़ाबासिक में करने की स्वतंत्रता चाहिए। (यह मज़े के लिए भी है, मैं हमेशा बड़ी संख्या की गणना करने के बारे में सोच रहा हूं और कुछ ऑनलाइन कैलकुलेटर कार्य के लिए बहुत बोझिल हैं।)
मल्लो

जवाबों:


25

आप जिस भाषा के साथ काम कर रहे हैं, उसके लिए आप एक मनमाने ढंग से सटीक अंकगणित ("कई सटीक" या "बड़ी संख्या") लाइब्रेरी की तलाश कर रहे हैं। उदाहरण के लिए, यदि आप C के साथ काम कर रहे हैं तो आप GNU Bignum लाइब्रेरी का उपयोग कर सकते हैं -> http://gmplib.org/

यदि आप यह समझना चाहते हैं कि यह कैसे काम करता है तो आप अपनी खुद की बड़ी संख्या वाली लाइब्रेरी भी लिख सकते हैं और इसका उपयोग कर सकते हैं। इसे संभालने का सबसे सरल तरीका सरणियों के साथ है, जहां प्रत्येक तत्व उस संख्या का एक अंक है जिसके साथ आप काम कर रहे हैं। उसके बाद आपको जोड़ने, घटाने, गुणा करने, विभाजित करने, घातांक आदि सभी कार्यों को लागू करने की आवश्यकता है।


5
बेशक "अंक" सापेक्ष है, कई बिग्नम लाइब्रेरी बेस 256 (अहस्ताक्षरित बाइट []) में 2 ^ 64 (अहस्ताक्षरित लंबी []) में अंकों का उपयोग करते हैं
शाफ़्ट सनकी

1
केवल यह सुनिश्चित करने से कि मैं समझ गया था, 'अंक' आधार का एक अंक हो सकता है 256 अंक? मुझे लगता है कि मुझसे गलती हो सकती है, आधार 256 पर गणित करना आधार 88 की तुलना में आसान है, लेकिन अभी भी काफी काम है ... (कम से कम जब मैंने पिछली रात को पेपर हाहा की एक शीट पर किया था)
मल्लो

1
"बेस 256 की तुलना में गणित करना बेस 88 से अधिक आसान है"। असत्य। वे समान रूप से आसान हैं।
एस.लॉट

2
@ एस.लॉट: उम ... जब आपके पास बिटवाइज ऑपरेशन उपलब्ध हैं, तो आधार 256 पर गणित करना निश्चित रूप से आधार 88 की तुलना में आसान है।
जेसन एस

1
अपने स्वयं के ऐड / घटाना / गुणा का निर्माण काफी सीधा है। विभाजन कठिन है, हालांकि, जब तक कि आप इसे बाइनरी में लागू नहीं कर रहे हैं, जहां यह सशर्त घटाव और बिट-शिफ्टिंग में एक अभ्यास बन जाता है।
जेसन एस

13

यह एक अच्छी तरह से ज्ञात समस्या है: मनमाना परिशुद्धता अंकगणित

जब आप जिस भाषा का उपयोग कर रहे हैं वह इस समस्या को हल नहीं करती है, तो पहले एक तीसरे पक्ष के पुस्तकालय को खोजने का प्रयास करें। यदि आप इसे नहीं पाते हैं या आप उत्सुक हैं, तो इसे लागू करने का प्रयास करें; विकिपीडिया लेख में शास्त्रीय कार्यान्वयन का एक अच्छा संदर्भ है।


6

बड़ी संख्या के साथ काम करते समय, शायद सबसे मौलिक डिजाइन निर्णयों में से एक यह है कि मैं बड़ी संख्या का प्रतिनिधित्व कैसे करूं?

क्या यह एक स्ट्रिंग, एक सरणी, एक सूची, या कस्टम (होमग्रोन) भंडारण वर्ग होगा।

उसके बाद निर्णय लिया जाता है, वास्तविक गणित संचालन को छोटे भागों में तोड़ा जा सकता है और फिर मूल या पूर्णांक जैसे मूल भाषा प्रकारों के साथ निष्पादित किया जाता है।

मैंने C # .Net में एक बहुत अल्पविकसित उदाहरण शामिल किया है जो परिणामस्वरूप बड़ी संख्या को एक स्ट्रिंग के रूप में संग्रहीत करता है। आने वाली "संख्या" भी तार हैं, इसलिए बहुत "बड़ी" संख्याओं में भेजने में सक्षम होना चाहिए। ध्यान रखें कि उदाहरण केवल सरल रखने के लिए संपूर्ण संख्याओं के लिए है।

यहां तक ​​कि तार के साथ वर्णों की संख्या या "संख्या" में एक सीमा होती है, जैसा कि यहां बताया गया है:

.NET स्ट्रिंग की अधिकतम संभव लंबाई क्या है?

लेकिन आप कुछ वास्तविक संख्याओं को जोड़ सकते हैं।

वैसे भी, यहाँ एक स्ट्रिंग भंडारण कार्यान्वयन है।

/// <summary>
/// Adds two "integers".  The integers can be of any size string.
/// </summary>
/// <param name="BigInt1">The first integer</param>
/// <param name="BigInt2">The second integer</param>
/// <returns>A string that is the addition of the two integers passed.</returns>
/// <exception cref="Exception">Can throw an exception when parsing the individual parts     of the number.  Callers should handle. </exception>
public string AddBigInts(string BigInt1, string BigInt2)
{
    string result = string.Empty;

    //Make the strings the same length, pre-pad the shorter one with zeros
    int length = (BigInt1.Length > BigInt2.Length ? BigInt1.Length : BigInt2.Length);
    BigInt1 = BigInt1.PadLeft(length, '0');
    BigInt2 = BigInt2.PadLeft(length, '0');

    int remainder = 0;

    //Now add them up going from right to left
    for (int i = (BigInt1.Length - 1); i >= 0; i--)
    {
        //If we don't encounter a number, this will throw an exception as indicated.
        int int1 = int.Parse(BigInt1[i].ToString());
        int int2 = int.Parse(BigInt2[i].ToString());

        //Add
        int add = int1 + int2 + remainder;

        //Check to see if we need a remainder;
        if (add >= 10)
        {
            remainder = 1;
            add = add % 10;
        }
        else
        {
            remainder = 0;
        }

        //Add this to our "number"
        result = add.ToString() + result;
    }

    //Handle when we have a remainder left over at the end
    if (remainder == 1)
    {
        result = remainder + result;
    }

    return result;
}

मुझे आशा है कि आप अपने स्वयं के कार्यान्वयन पर कुछ विचार देते हैं। कृपया ध्यान दें, कि नमूना कोड शायद अनुकूलित या ऐसा कुछ भी नहीं है। यह कुछ विचारों को देने के लिए है कि यह कैसे किया जा सकता है।


ठंडा!! धन्यवाद यह स्पष्ट चीजों को बनाए रखने में मदद करता है मैं अतिरिक्त से अधिक जटिल होता।
मल्लो

-2

यह मेरे लिए तेजी से काम करता है:

static string Add(string a, string b)
        {
            string c = null;

            if (Compare(a, b) < 0)
            {
                c = a;
                a = b;
                b = c;
            }

            StringBuilder sb = new StringBuilder();

            b = b.PadLeft(a.Length, '0');

            int r = 0;

            for (int i = a.Length - 1; i >= 0; i--)
            {
                int part = a[i] + b[i] + r - 96;

                if (part <= 9)
                {
                    sb.Insert(0, part);

                    r = 0;
                }
                else
                {
                    sb.Insert(0, part - 10);

                    r = 1;
                }
            }

            if (r == 1)
            {
                sb.Insert(0, "1");
            }

            return sb.ToString();
        }

2
यह साइट वैचारिक प्रश्नों के बारे में है और उत्तर चीजों की व्याख्या करने के लिए अपेक्षित हैं। स्पष्टीकरण के बजाय कोड डंप फेंकना आईडीई से व्हाइटबोर्ड पर कोड कॉपी करने जैसा है: यह परिचित लग सकता है और यहां तक ​​कि कभी-कभी समझ में आता है, लेकिन यह अजीब लगता है ... बस अजीब है। व्हाइटबोर्ड में संकलक नहीं है
gnat

यह साइट EXCHANGE है, इसलिए हम एक दूसरे की मदद करने की कोशिश करते हैं जितना हमारे पास है। शायद मुझे StackOverflow में ऐसी टिप्पणियाँ करनी चाहिए, लेकिन मैंने अपने दृष्टिकोण के साथ मदद करने की कोशिश की। यदि किसी को अभी भी स्पष्टीकरण की आवश्यकता है, तो वह इसके लिए पूछेगा। मैं अंत से शुरू करके, अंक द्वारा एक मानक गणितीय अतिरिक्त अंक प्राप्त करता हूं।
एंड्रानिक

ज्ञाता से सहमत। कम से कम डंपिंग कोड से पहले एल्गोरिथ्म की व्याख्या करें।
फ्रैंक हिलमैन

बिना किसी स्पष्टीकरण के केवल डंपिंग कोड कॉपी-पास्ट-एंड-गो को प्रोत्साहित करने जैसा है। मैं नहीं देखता कि कैसे SoftwareEngineering में उपयोगी हो सकता है। शायद StackOverflow में है, लेकिन दोनों साइटों वास्तव में पूरी तरह से अलग उद्देश्य हैं।
Laiv
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.