2010-02-12 12 views
7

मुझे एक पूर्णांक मान स्टोर करना है जो लंबे डेटाटाइप के अधिकतम मूल्य से बड़ा है। मैं इस मान को स्मृति में कैसे संग्रहीत और कुशलतापूर्वक उपयोग करूं?आप स्मृति में मनमाने ढंग से बड़े पूर्णांक मान को कैसे संग्रहीत करते हैं?

यदि संभव हो, तो कृपया इसे उदाहरण के माध्यम से चित्रित करें।

+6

http://gmplib.org/ – ziya

उत्तर

3

मैं तुम्हें कोड नहीं देंगे, लेकिन मैं कुछ सुझाव कर सकते हैं दृष्टिकोण के लिए:

  1. एक चरित्र स्ट्रिंग के रूप में मूल्य भंडारण और गणना
  2. कोशिश तोड़ने प्रदर्शन करने के लिए परिवर्तित करने का प्रयास करें मूल्य के एक हिस्से को
  3. मौजूदा पुस्तकालयों कि के लिए इस की देखभाल कर सकते हैं देखें का प्रतिनिधित्व करने के लिए कई पूर्णांकों में मूल्य को आप

गुड लक

+6

विशेष रूप से अगर यह एक परीक्षा के लिए है, मैं आपको प्राथमिक स्कूल में गणित करने के तरीके के बारे में सोचने की सलाह दूंगा। आप जानते हैं, जोड़ते हैं, 1 लेते हैं, घटाते हैं, 10 लेते हैं, आदि। यदि आप इन परिचालनों को एक चरित्र स्ट्रिंग पर नहीं कर सकते हैं, तो आप प्राथमिक विद्यालय में विफल रहे, और इसके परिणामस्वरूप विश्वविद्यालय में कंप्यूटर विज्ञान में असफल रहा। –

7

संभावित समाधान:
1) कस्टम पूर्णांक प्रकार को परिभाषित करें जो उस मान को पकड़ने के लिए काफी बड़ा है। 128-बिट पूर्णांक 98474737475747374739399 रखने के लिए काफी बड़ा है।
2) किसी भी उपलब्ध bignum लाइब्रेरी का उपयोग करें।

2

यह विश्वविद्यालय में प्रारंभिक कंप्यूटर विज्ञान कक्षाओं में एक आम सवाल है। फोकस के प्राथमिक क्षेत्र ए) समझते हैं कि कैसे (पूर्णांक) संख्या बाइनरी अंकों के रूप में संग्रहीत की जाती है, और बी) डेटा संरचनाओं की मूल बातें, जहां एक प्रोग्रामिंग भाषा वांछित डेटा संरचना स्वयं प्रदान नहीं करती है, तो आप मेटा या संग्रह संरचनाएं, जैसे struct सी, class सी ++ में, या record पास्कल में।

तो कंप्यूटर में एक छोटा पूर्णांक कैसे संग्रहीत किया जाता है? सी में, आपके पास डेटा प्रकार char, short, int, long हैं जिनका उपयोग विभिन्न आकारों के पूर्णांक को स्टोर करने के लिए किया जा सकता है। (मैं इस चर्चा के लिए long long को अनदेखा कर दूंगा।) सामान्यता के लिए कहें कि दिए गए 32-बिट प्लेटफॉर्म पर आकार 8-बिट, 16-बिट, 32-बिट और 64-बिट क्रमशः हैं। उन मानों पर विचार करें जिन्हें प्रदर्शित किया जा सकता है (हस्ताक्षरित मानी जाने वाली सरलता के लिए)।

अब, आप एक बड़ा पूर्णांक कैसे स्टोर कर सकते हैं, जिसे एक हस्ताक्षरित 64-बिट लंबे समय तक संग्रहीत नहीं किया जा सकता है? अपने स्वयं के बड़े पूर्णांक डेटा प्रकार बनाएं, जिसमें कई छोटे (लेकिन मानक) पूर्णांक शामिल हैं जैसे कि वे बड़े मानों का प्रतिनिधित्व करते हैं।

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

18

इस तरह एक struct का उपयोग कर दशमलव अंक के दृश्यों के रूप में एक संख्या के संचय के बारे में सोचो:

struct num { 
    int ndigits; 
    char d[MAXDIGITS]; 
}; 

उदाहरण के लिए, संख्या 123456

struct num n = { 6, { 6, 5, 4, 3, 2, 1 } }; 

के रूप में प्रारंभ किया जा सकता है उलट अंकों आदेश पता चला है आसान गणना के लिए महत्वपूर्ण होना चाहिए। विशेष रूप से, n.d[i] का स्थान मान n.d[i] * 10^i है।

अब, कुछ सवाल:

  • आप कैसे जोड़ना होगा एक num करने के लिए एक?
  • num पर आप मनमाने ढंग से एकल अंक कैसे जोड़ेंगे?
  • आप दो num एस को एक साथ कैसे जोड़ेंगे?
  • आप num को दो से कैसे गुणा करेंगे?
  • आप एक अंक से num कैसे गुणा करेंगे?
  • आप num को 10 से गुणा कैसे करेंगे?
  • आप दो num एक साथ कैसे गुणा करेंगे? हंट: कुछ पेंसिल और पेपर गुणा करें और देखें कि वे कैसे काम करते हैं।

आप सवालों का इस क्रम के माध्यम से काम हैं, तो आप प्रत्येक चरण के लिए एक समारोह में लिखने के लिए, और बाद में सवालों के जवाब देने उन कार्यों का फिर से उपयोग, और एक बहुत ही सरल और unoptimized लंबे अंत (सक्षम होना चाहिए ठीक है, MAXDIGIT अंकों तक) सकारात्मक संख्याओं के अतिरिक्त और गुणा के लिए पूर्णांक पैकेज।

अन्य प्रश्न:

  • आप num कैसे सामान्यीकरण करते ऋणात्मक संख्याओं के साथ ही सकारात्मक प्रतिनिधित्व करने के लिए?
  • आप एक num को दूसरे से कैसे विभाजित करते हैं (रहने वाले को अनदेखा करते हैं)? यह गुणा से अधिक कठिन है, लेकिन फिर, कुछ पेंसिल और पेपर लंबे डिवीजन करके शुरू करें और आप जो करते हैं उसके बारे में सावधानी से सोचें।
+0

एक अच्छा विवरण। और उसके बाद: उस सरणी पर बेस -10 के बजाय बेस -256 का उपयोग करें। :) – Kos

+1

आधार का उपयोग कर @Kos 2^32 (या 2^64 यदि 64-बिट सिस्टम पर) काफी बेहतर –

+0

@ LưuVĩnhPhúc आधार 2^32 (या आधार 2^64) के साथ काम कर रहा है, सी में अजीब हो सकता है, क्योंकि दो "अंक" जोड़ने के बाद सेट ले जाने के लिए सेट करने का कोई प्रभावी तरीका नहीं है। कच्चे असेंबलर में, यह जांच आपके सी प्रोग्राम में ऑनलाइन, या ऑनलाइन असेंबलर के साथ आसान होगी। हालांकि, मुझे संदेह है कि यह थोड़ा सा है जहां ओपी कम से कम इस समय पर आरामदायक होगा। –

0

यदि यह केवल प्रदर्शन के लिए है, मेरा सुझाव है कि एक <stdio.h> सी मानक पुस्तकालय या हो सकता है कुछ संशोधन करना <string.h> से (कुख्यात printf के लिए)।

+0

क्षमा करें, लेकिन जब तक आप इसे ठीक नहीं करते हैं, यह सबसे भ्रमित उत्तर के लिए एक उम्मीदवार है। –

+0

यह इंगित करने के लिए धन्यवाद, मुझे हमेशा फिर से पढ़ना चाहिए। हालांकि सवाल भी भ्रमित है। –

0
struct digitcontainer 
    { 
     struct digitcontainer* left; 
     struct digitcontainer* right; 
     unsigned char digit; 
    } 

    struct longinteger 
    { 
     char sign; 
     struct digitcontainer* firstdigit; 
    } 

    // positive number with 1000 digits 
    void test() 
    { 
     struct longinteger myNumber; 

     myNumber.sign = '+'; 
     myNumber.firstdigit = (struct digitcontainer*)malloc(sizeof(digitcontainer)); 
     myNumber.firstdigit->left = NULL; 
     myNumber.firstdigit->right = NULL; 
     myNumber.firstdigit->digit = 1; 

     struct digitcontainer* left = myNumber.firstdigit; 

     for(int i=1; i<1000; i++) 
     { 
     left->right = (struct digitcontainer*)malloc(sizeof(digitcontainer)); 
     left->right->left = left; 
     left->right->digit = (unsigned char)i; 
     left = left->right; 
     } 

     left->right = NULL; 

     // call free for each digitcontainer you are finished using the number 
    } 
0

LibTomMath सी में एक अच्छा मनमाना परिशुद्धता पूर्णांक कार्यान्वयन प्रदान करता है, मैं लगभग कोई संशोधन के साथ एक iPhone परियोजना में छोड़ने में सक्षम था।

3

रॉबर्ट लाफोर - सी ++ में वस्तु उन्मुख प्रोग्रामिंग, 4 संस्करण:

// verylong.cpp 
// implements very long integer type 
#include "verylong.h"   //header file for verylong 
//-------------------------------------------------------------- 
void verylong::putvl() const   //display verylong 
    { 
    char temp[SZ]; 
    strcpy(temp,vlstr);     //make copy 
    cout << strrev(temp);    //reverse the copy 
    }         //and display it 
//-------------------------------------------------------------- 
void verylong::getvl()     //get verylong from user 
    { 
    cin >> vlstr;      //get string from user 
    vlen = strlen(vlstr);    //find its length 
    strrev(vlstr);      //reverse it 
    } 
//-------------------------------------------------------------- 
verylong verylong::operator + (const verylong v) //add verylongs 
    { 
    char temp[SZ]; 
    int j; 
         //find longest number 
    int maxlen = (vlen > v.vlen) ? vlen : v.vlen; 
    int carry = 0;      //set to 1 if sum >= 10 
    for(j = 0; j<maxlen; j++)   //for each position 
     { 
     int d1 = (j > vlen-1) ? 0 : vlstr[j]-'0'; //get digit 
     int d2 = (j > v.vlen-1) ? 0 : v.vlstr[j]-'0'; //get digit 
     int digitsum = d1 + d2 + carry;    //add digits 
     if(digitsum >= 10)    //if there's a carry, 
     { digitsum -= 10; carry=1; } //decrease sum by 10, 
     else        //set carry to 1 
     carry = 0;     //otherwise carry is 0 
     temp[j] = digitsum+'0';   //insert char in string 
     } 
    if(carry==1)      //if carry at end, 
     temp[j++] = '1';     //last digit is 1 
    temp[j] = '\0';      //terminate string 
    return verylong(temp);    //return temp verylong 
    } 
//-------------------------------------------------------------- 
verylong verylong::operator * (const verylong v) //multiply 
    {            //verylongs 
    verylong pprod;      //product of one digit 
    verylong tempsum;     //running total 
    for(int j=0; j<v.vlen; j++)   //for each digit in arg 
     { 
     int digit = v.vlstr[j]-'0';  //get the digit 
     pprod = multdigit(digit);  //multiply this by digit 
     for(int k=0; k<j; k++)   //multiply result by 
     pprod = mult10(pprod);  // power of 10 
     tempsum = tempsum + pprod;  //add product to total 
     } 
    return tempsum;      //return total of prods 
    } 
//-------------------------------------------------------------- 
verylong verylong::mult10(const verylong v) const //multiply 
    {            //arg by 10 
    char temp[SZ]; 
    for(int j=v.vlen-1; j>=0; j--)  //move digits one 
     temp[j+1] = v.vlstr[j];   // position higher 
    temp[0] = '0';      //put zero on low end 
    temp[v.vlen+1] = '\0';    //terminate string 
    return verylong(temp);    //return result 
    } 
//-------------------------------------------------------------- 
verylong verylong::multdigit(const int d2) const 
    {         //multiply this verylong 
    char temp[SZ];      //by digit in argument 
    int j, carry = 0; 
    for(j = 0; j<vlen; j++)    //for each position 
     {        // in this verylong 
     int d1 = vlstr[j]-'0';   //get digit from this 
     int digitprod = d1 * d2;   //multiply by that digit 
     digitprod += carry;    //add old carry 
     if(digitprod >= 10)   //if there's a new carry, 
     { 
     carry = digitprod/10;   //carry is high digit 
     digitprod -= carry*10;  //result is low digit 
     } 
     else 
     carry = 0;     //otherwise carry is 0 
     temp[j] = digitprod+'0';   //insert char in string 
     } 
    if(carry != 0)      //if carry at end, 
     temp[j++] = carry+'0';   //it's last digit 
    temp[j] = '\0';      //terminate string 
    return verylong(temp);    //return verylong 
    } 

Verylong वर्ग हैडर

// verylong.h 
// class specifier for very long integer type 
#include <iostream> 
#include <string.h>   //for strlen(), etc. 
#include <stdlib.h>   //for ltoa() 
using namespace std; 

const int SZ = 1000; 
     //maximum digits in verylongs 

class verylong 
    { 
    private: 
     char vlstr[SZ];  //verylong number, as a string 
     int vlen;    //length of verylong string 
     verylong multdigit(const int) const; //prototypes for 
     verylong mult10(const verylong) const; //private functions 
    public: 
     verylong() : vlen(0)    //no-arg constructor 
     { vlstr[0]='\0'; } 
     verylong(const char s[SZ])  //one-arg constructor 
     { strcpy(vlstr, s); vlen=strlen(s); } //for string 
     verylong(const unsigned long n) //one-arg constructor 
     {          //for long int 
     ltoa(n, vlstr, 10);   //convert to string 
     strrev(vlstr);    //reverse it 
     vlen=strlen(vlstr);   //find length 
     } 
     void putvl() const;    //display verylong 
     void getvl();     //get verylong from user 
     verylong operator + (const verylong); //add verylongs 
     verylong operator * (const verylong); //multiply verylongs 
    }; 
+0

इस तरह के दशमलव अंक संग्रहीत करने के लिए पर्याप्त हो सकता है लेकिन वास्तविक गणना में यह अक्षम होगा। बिगिंट पुस्तकालयों का उपयोग [बेस 2^64 में अंक (या 32-बिट कंप्यूटर में आधार 2^32)] (http://stackoverflow.com/q/11548070/995714) इसके बजाय –

संबंधित मुद्दे

 संबंधित मुद्दे