0 से अनंत तक पूर्णांक संख्याओं का प्रतिनिधित्व करने के लिए एक अच्छा स्कीमा, यह मानते हुए कि आपके पास अनंत रैखिक बाइनरी स्टोरेज है?


10

मैं 0 से शुरू होने वाले पूर्णांक संख्याओं का प्रतिनिधित्व करने के लिए एक स्कीमा चाहूंगा, बिना किसी सीमा के (अनंत रैखिक भंडारण तक पहुंच)।

यहां एक स्कीमा है जो 0 से 255 तक संख्याओं का प्रतिनिधित्व कर सकता है:

पूर्णांक को संग्रहीत करने के लिए स्टोरेज (पता 0) के पहले बाइट का उपयोग करें।

अब, मान लें कि मैं 255 से बड़ी संख्या का प्रतिनिधित्व करना चाहता हूं। बेशक, मैं पूर्णांक का प्रतिनिधित्व करने के लिए 1 से अधिक बाइट का उपयोग कर सकता हूं, लेकिन जब तक यह एक निश्चित संख्या है, तब तक एक पूर्णांक इतना बड़ा होगा कि यह प्रतिनिधित्व नहीं कर सकता है मूल स्कीमा।

यहां एक और स्कीमा है जो कार्य करने में सक्षम होना चाहिए, लेकिन यह शायद कुशल से बहुत दूर है।

बस किसी प्रकार के अनूठे "संख्या के अंत" बाइट का उपयोग करें, और संख्या का प्रतिनिधित्व करने के लिए सभी पिछले बाइट्स का उपयोग करें। जाहिर है, इस "संख्या का अंत" बाइट का उपयोग कहीं भी संख्या प्रतिनिधित्व में नहीं किया जा सकता है, लेकिन यह एक आधार -255 (आधार-256 के बजाय) नंबरिंग प्रणाली का उपयोग करके प्राप्त किया जा सकता है।

हालाँकि, यह धीमा और शायद अक्षम है। मैं एक बेहतर इंसान बनाना चाहता हूं जो कम मूल्यों और तराजू के साथ बेहतर प्रदर्शन करता है।

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


1
क्या आप कुछ ऐसा चाहते हैं जो असीम रूप से (आपके उद्घाटन के रूप में), या लाखों वर्षों तक (जैसे आपके समापन में) हो सकता है? दो आवश्यकताएँ पूरी तरह से अलग हैं। 64-बिट मशीन पर Twos पूरक लाखों वर्षों के लिए पैमाने पर होगा
user16764

1
@ user16764, क्या आपका मतलब एकल 64-बिट पूर्णांक चर है? यह निश्चित रूप से काम नहीं करेगा: यदि 6 मिलियन लोग प्रति सेकंड 1 मिलियन यूयूआईडी का उपभोग कर रहे हैं, तो यह मुश्किल से एक महीने से अधिक चलेगा।
दिमित्री शूर्योव

1
और 128-बिट मशीन पर कितना समय लगेगा?
user16764

2
RFC 2550 में विचार , जो मनमाने ढंग से बड़े सकारात्मक पूर्णांकों के लिए एक lexicographic- आदेशित ASCII प्रतिनिधित्व प्रदान करता है, इसके लिए अनुकूल हो सकता है। अंतत: यह एक एकता खंड के लिए टूट जाता है जो बेस -26 सेगमेंट की लंबाई को एन्कोड करता है जो बेस -10 सेगमेंट की लंबाई को एन्कोड करता है - बाद वाले दो आधारों को स्कीम के लिए कुछ भी मौलिक की तुलना में एएससीआईआई प्रतिनिधित्व के साथ अधिक करना है।
रैंडम 832

1
मान लिया जाए कि आप क्रमिक रूप से 128 बिट संख्या उत्पन्न करते हैं: यदि हम प्रत्येक मानव को एक पेटाफ्लॉप-कंप्यूटर देकर सभी कंप्यूटरों की संगणना क्षमता को अपर-बाउंड करते हैं, तो इन नंबरों को चलाने में 9 मिलियन वर्ष लगेंगे। यदि दूसरी ओर प्रत्येक मानव बेतरतीब ढंग से 600 मिलियन 128 बिट संख्या उत्पन्न करेगा, तो 50% संभावना है कि वे 1 डुप्लिकेट उत्पन्न करते हैं। क्या आपके लिए यह काफी अच्छा है? ( en.wikipedia.org/wiki/Universally_unique_identifier ) यदि नहीं, तो 256 बिट्स का उपयोग इन दोनों आंकड़ों को 2 ^ 128 = 3.4 * 10 ^ 38 से गुणा करता है, जो सेकंड में ब्रह्मांड के वर्ग से अधिक है।
एलेक्स दस ब्रिंक

जवाबों:


13

एक दृष्टिकोण जो मैंने उपयोग किया है: प्रमुख 1 बिट्स की संख्या की गणना करें, कहते हैं n। संख्या का आकार 2 ^ n बाइट्स (अग्रणी 1 बिट्स सहित) है। पहले 0 बिट के बाद बिट्स को एक पूर्णांक के रूप में लें, और अधिकतम मान (प्लस एक) को जोड़ें, जिसे 2 ^ (n-1) बाइट्स में इस एन्कोडिंग का उपयोग करके एक संख्या द्वारा दर्शाया जा सकता है।

इस प्रकार,

                  0 = 0b00000000
                   ...
                127 = 0b01111111
                128 = 0b1000000000000000
                   ...
              16511 = 0b1011111111111111
              16512 = 0b11000000000000000000000000000000
                   ...
          536887423 = 0b11011111111111111111111111111111
          536887424 = 0b1110000000000000000000000000000000000000000000000000000000000000
                   ...
1152921505143734399 = 0b1110111111111111111111111111111111111111111111111111111111111111
1152921505143734400 = 0b111100000000000000000000000000000000000000000000 ...

यह योजना किसी भी गैर-नकारात्मक मूल्य को बिल्कुल एक तरह से प्रस्तुत करने की अनुमति देती है।

(समान रूप से, प्रमुख 0 बिट्स की संख्या का उपयोग किया जाता है।)


1
मेरे लिए यह समझ पाना कठिन था कि कौन से उत्तर को स्वीकार किया जाए, क्योंकि मुझे लगता है कि उनमें से कई बहुत जानकारीपूर्ण और अच्छे हैं। लेकिन मुझे लगता है कि यह मेरे द्वारा पूछे गए सवाल के लिए सबसे उपयुक्त है (संभवत: मेरे पास जो अंतर्निहित है, वह व्यक्त करना मुश्किल है)।
दिमित्री शूर्योव

2
मैंने एक और अधिक गहन लेख लिखा जिसमें एक उदाहरण कार्यान्वयन और डिजाइन विचार है।
14

10

आप क्या करने की कोशिश कर रहे हैं, इस पर आधारित बहुत सारी थ्योरी है। सार्वभौमिक कोड के बारे में विकी पृष्ठ पर एक नज़र डालें - पूर्णांक एन्कोडिंग विधियों की कुछ विस्तृत सूची है (जिनमें से कुछ वास्तव में अभ्यास में उपयोग की जा रही हैं)।

डेटा संपीड़न में, पूर्णांक के लिए एक सार्वभौमिक कोड एक उपसर्ग कोड है जो बाइनरी कोडवर्ड पर सकारात्मक पूर्णांक को मैप करता है

या आप कुछ इकाइयों (सबसे अधिक संभावना बाइट्स) में संख्या की लंबाई को स्टोर करने के लिए पहले 8 बाइट्स का उपयोग कर सकते हैं और फिर डेटा बाइट्स डाल सकते हैं। इसे लागू करना बहुत आसान होगा, लेकिन छोटी संख्याओं के लिए यह अक्षम है। और आप मानवता के लिए उपलब्ध सभी डेटा ड्राइवों को भरने के लिए पूर्णांक को कोड करने में सक्षम होंगे :)


इसके लिए धन्यवाद, यह बहुत दिलचस्प है। मैं इसे स्वीकृत उत्तर के रूप में चिह्नित करना चाहता था, लेकिन इसने 2 वां स्थान प्राप्त किया। यह एक सैद्धांतिक दृष्टिकोण से बहुत अच्छा जवाब है, IMO।
दिमित्री शूर्योव

4

कैसे के बारे में 1 की संख्या 1 प्लस की संख्या चलो आकार (आकार) संख्या आकार (संख्या) बिट में आकार (आकार) हो। NumSize एक बाइनरी नंबर है जो आकार बिट्स सहित बाइट्स में संख्या प्रतिनिधित्व का आकार देता है। शेष बिट्स बाइनरी में संख्या (संख्या) हैं। सकारात्मक पूर्णांक योजना के लिए, यहाँ कुछ नमूना उदाहरण संख्याएँ हैं:

Number              sizeSize  numSize    num
63:                 0 (1)     1 (1)      111111
1048575:            10 (2)    11 (3)     1111 11111111 11111111
1125899906842623:   110 (3)   111 (7)    11 11111111 11111111 11111111 11111111 11111111 11111111
5.19.. e+33:        1110 (4)  1111 (15)  11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111

4

कैसे के बारे में: लंबाई के लिए एक बाइट, फिर संख्या के लिए n बाइट्स (कम से कम महत्वपूर्ण बाइट पहले)। जब तक पिछली लंबाई 255 थी तब तक लंबाई + संख्या दोहराएं।

यह मनमाने ढंग से बड़ी संख्या के लिए अनुमति देता है, लेकिन अभी भी संभालना आसान है और बहुत अधिक मेमोरी बर्बाद नहीं करता है।


fNek: कोई ऊपरी सीमा नहीं है। उदाहरण के लिए, यदि आपको संख्या के लिए 513 बाइट्स की आवश्यकता है, तो बाइट अनुक्रम है [255, b0, ..., b255,255, b256, ..., b511,2, b512, b513]
user28777

माफ़ करना। अधिक ध्यान से पढ़ना सीखना चाहिए।
fNek

3

प्रत्येक बाइट में से केवल 7 बिट्स का उपयोग क्यों न करें, और 8 बिट का उपयोग करके यह इंगित करें कि क्या कोई अन्य बाइट है? तो 1-127 एक बाइट में होगा, 128 को 0x80 0x01, आदि द्वारा दर्शाया जाएगा।


1
यह योजना प्रत्येक 8 बिट्स में सिर्फ 128 मानों को एन्कोड करती है, जो वास्तव में प्रश्नकर्ता द्वारा प्रस्तावित दूसरी एन्कोडिंग योजना की तुलना में कम कुशल है, जहां हर 8 बिट्स में 255 मान एनकोडेड हैं। दोनों योजनाएं इस तथ्य से ग्रस्त हैं कि आपको यह जानने के लिए पूरी संख्या में पढ़ने की आवश्यकता है कि आपको इसे संग्रहीत करने के लिए कितना संग्रहण करना है।
बूथ पर मार्क बूथ

3
तो आपको इसकी प्रतिलिपि बनाने के लिए नंबर को दो बार स्कैन करने की आवश्यकता है, तो क्या? यदि मैं एक असीम रूप से बड़ी संख्या के लिए प्रतीक्षा कर सकता हूं, तो मैं इसके लिए दो बार इंतजार कर सकता हूं।
रसेल बोरोगोव

यद्यपि मैंने इसे बहुत सावधानी से निर्दिष्ट नहीं किया था, मैं एक समाधान की तलाश कर रहा हूं जो यथासंभव कुशलता से प्रदर्शन करता है (एक समाधान के बजाय जो आवश्यकताओं से मेल खाता है; मैंने पहले ही अपने प्रश्न में एक संभावित अक्षम उत्तर का वर्णन किया है)।
दिमित्री शूर्योव

3

यूयूआईडी सिस्टम एक परिमित (लेकिन बड़े) ब्रह्मांड में परिमित (लेकिन बड़े) कंप्यूटिंग शक्ति पर आधारित हैं। ब्रह्मांड में कणों की संख्या जैसी बेतुकी बड़ी चीजों की तुलना में यूयूआईडी की संख्या बड़ी है। यूआईआईडी की संख्या, किसी भी निश्चित बिट के साथ, अनंत की तुलना में, हालांकि, छोटी है।

संख्या ध्वज के अपने अंत का प्रतिनिधित्व करने के लिए 0xFFFF का उपयोग करने में समस्या यह है कि यह संख्याओं के बड़े होने पर आपकी संख्या को कम कुशल बनाता है। हालाँकि, ऐसा लगता है कि आपकी UUID योजना इस समस्या को और भी बदतर बना देती है। 256 बाइट्स में से एक को छोड़ देने के बजाय, अब आपके पास पूरा यूयूआईडी स्थान बर्बाद हो गया है। अभिकलन / मान्यता (स्थान के बजाय) की दक्षता आपके सैद्धांतिक कंप्यूटर पर बहुत कुछ निर्भर करती है (जो, मुझे लगता है कि आपके पास है अगर आप अनंत के बारे में बात कर रहे हैं)। एक टेप और एक परिमित राज्य नियंत्रक के साथ टीएम के लिए, किसी भी यूयूआईडी योजना को कुशलतापूर्वक स्केल करना असंभव है (मूल रूप से, पंपिंग लेम्मा आपको एक निश्चित-बिट-एंड-एंड मार्कर से कुशलता से आगे बढ़ने से रोकता है)। यदि आप एक परिमित राज्य नियंत्रक नहीं मानते हैं, तो यह लागू नहीं हो सकता है, लेकिन आपको यह सोचना होगा कि बिट्स डिकोडिंग / मान्यता प्रक्रिया में कहां जाते हैं।

यदि आप केवल 256 बाइट्स में से 1 से बेहतर दक्षता चाहते हैं, तो आप अपनी यूयूआईडी योजना के लिए जो भी उपयोग करने जा रहे हैं, उसकी 1-बिट लंबाई का उपयोग कर सकते हैं। यह अक्षमता में 2 ^ बिट-लंबाई में से 1 है।

ध्यान दें कि अन्य एन्कोडिंग योजनाएं हैं, हालांकि। सीमांकक के साथ बाइट एन्कोडिंग सिर्फ लागू करने के लिए सबसे आसान होता है।


2

मेरा सुझाव है कि बाइट्स की एक सरणी (या ints या longs) और एक लंबाई फ़ील्ड है जो कहती है कि संख्या कितनी लंबी है।

यह लगभग जावा के बिगइंटर द्वारा उपयोग किए जाने वाला दृष्टिकोण है । इससे संभव होने वाला पता स्थान बड़े पैमाने पर है - आसानी से ब्रह्मांड में प्रत्येक व्यक्ति परमाणु को एक अलग यूयूआईडी देने के लिए पर्याप्त है :-)

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


जब फ़ील्ड की संख्या अनंत हो सकती है, तो आप सरणी की लंबाई को एनकोड नहीं कर सकते।
स्लावेक

मैं सहमत हूं कि किसी दिए गए समस्या के लिए एक मौजूदा समाधान (विशेष रूप से एक जो पेशेवर जांच के माध्यम से) का उपयोग करके, जब संभव हो, पसंद किया जाता है। धन्यवाद।
दिमित्री शूर्योव

@Slawek: सच है, लेकिन उपयोग के मामले के लिए ओपी वर्णन कर रहा है (यानी UUIDs), एक BigInteger प्रभावी रूप से अनंत है। आप किसी भी कंप्यूटर में अनंत सूचनाओं को अनंत आकार की मेमोरी के साथ संलग्न नहीं कर सकते हैं, इसलिए BigInteger उतना ही अच्छा है जितना कि आप प्राप्त करने की संभावना रखते हैं।
मायके

2

सबसे पहले, उन सभी के लिए धन्यवाद जिन्होंने मेरे अपेक्षाकृत अस्पष्ट और सार प्रश्न के महान जवाब दिए।

मैं एक संभावित उत्तर देने में योगदान करना चाहता हूं जो मैंने अन्य उत्तरों के बारे में सोचने के बाद सोचा है। यह पूछे गए सवाल का सीधा जवाब नहीं है, लेकिन यह प्रासंगिक है।

जैसा कि कुछ लोगों ने बताया, 64/128/256 बिट आकार के पूर्णांक का उपयोग करना आपको पहले से ही UUIDs के लिए एक बहुत बड़ी जगह देता है। जाहिर है कि यह अनंत नहीं है, लेकिन ...

शायद यह एक अच्छा विचार हो सकता है कि केवल एक निश्चित आकार के इंट का उपयोग करें (जैसे, 64-बिट शुरू करने के लिए) जब तक 64-बिट पर्याप्त नहीं है (या इसके करीब)। फिर, यह मानते हुए कि आपके पास यूयूआईडी के सभी पिछले उदाहरणों तक ऐसी पहुंच है, बस उन सभी को 128-बिट इनट्स में अपग्रेड करें और इसे अपने पूर्णांक के निश्चित आकार में लें।

यदि सिस्टम इस तरह के ठहराव / सेवा में रुकावट की अनुमति देता है, और क्योंकि इस तरह के "पुनर्निर्माण" के संचालन काफी बार होने चाहिए, तो शायद लाभ (एक बहुत ही सरल, तेज, सिस्टम को लागू करने के लिए आसान) नुकसान से आगे निकल जाएगा (सभी पहले से आवंटित पूर्णांकों को फिर से बनाने के लिए) एक नए पूर्णांक बिट आकार के लिए)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.