रूबी 2.4 मर्ज किया गया Fixnum
&Bignum
एक ही कक्षा में (Integer
) इसलिए मुझे लगता है कि यह रूबी में विभिन्न संख्या प्रकारों की समीक्षा करने का एक अच्छा समय है!
इसी के बारे में हम इस पोस्ट में बात करने जा रहे हैं 🙂
संख्या प्रकारों का अवलोकन
आइए रूबी में सभी संख्या से संबंधित वर्गों के वर्ग पदानुक्रम पर एक नज़र डालते हैं:
Numeric Integer Fixnum Bignum Float Complex Rational BigDecimal (Standard Library)
जैसा कि आप देख सकते हैं, Numeric
वर्ग सभी संख्या वर्गों के लिए जनक है। याद रखें कि आप ancestors
. का उपयोग कर सकते हैं किसी भी वर्ग के लिए मूल वर्ग खोजने की विधि।
उदाहरण :
Fixnum.ancestors - Fixnum.included_modules [Fixnum, Integer, Numeric, Object, BasicObject]
आइए अब इन कक्षाओं को तालिका के रूप में देखें:
Class | विवरण | उदाहरण |
---|---|---|
पूर्णांक | Fixnum का मूल वर्ग &Bignum | 1 |
Fixnum | संपूर्ण संख्याएं जो OS पूर्णांक प्रकार (32 या 64 बिट) में फिट होती हैं | 1 |
बिग्नम | बड़ी संख्या के लिए उपयोग किया जाता है | 111111111111 |
फ्लोट | अशुद्ध दशमलव संख्याएं | 5.0 |
जटिल | काल्पनिक संख्याओं वाली गणित सामग्री के लिए प्रयुक्त | (1+0i) |
तर्कसंगत | अंशों को दर्शाने के लिए उपयोग किया जाता है | (2/3) |
BigDecimal | बिल्कुल सटीक दशमलव संख्याएं | 3.0 |
फ्लोट इम्प्रिसिजन
Float
रूबी में कक्षा को आधिकारिक रूबी दस्तावेज़ीकरण में "अशुद्ध" के रूप में वर्णित किया गया है।
ऐसा क्यों है?
मैं आपको एक उदाहरण दिखाता हूं :
0.2 + 0.1 == 0.3 # false
यह झूठ क्यों है?
आइए 0.2 + 0.1
. का परिणाम देखें :
0.30000000000000004
बिल्कुल! यही हमारा मतलब अपरिशुद्धता से है।
ऐसा इसलिए होता है क्योंकि जिस तरह से एक फ्लोट संग्रहीत किया जाता है। यदि आपको दशमलव संख्याओं की आवश्यकता है जो हमेशा सटीक हों तो आप BigDecimal
. का उपयोग कर सकते हैं कक्षा।
फ्लोट बनाम बिगडेसिमल
BigDecimal एक ऐसा वर्ग है जो आपको मनमानी-सटीक दशमलव संख्या देता है।
उदाहरण :
require 'bigdecimal' BigDecimal("0.2") + BigDecimal("0.1") == 0.3 # true
हम हमेशा BigDecimal
. का उपयोग क्यों नहीं करते? फिर? क्योंकि यह बहुत धीमा है!
यहां एक बेंचमार्क है :
Calculating ------------------------------------- bigdecimal 21.559k i/100ms float 79.336k i/100ms ------------------------------------------------- bigdecimal 311.721k (± 7.4%) i/s - 1.552M float 3.817M (±11.7%) i/s - 18.803M Comparison: float: 3817207.2 i/s bigdecimal: 311721.2 i/s - 12.25x slower
BigDecimal
Float
. से 12 गुना धीमा है , और इसीलिए यह डिफ़ॉल्ट नहीं है 🙂
Fixnum बनाम Bignum
इस खंड में, मैं Fixnum
. के बीच के अंतरों का पता लगाना चाहता हूं और Bignum
रूबी 2.4 से पहले।
आइए कुछ कोड से शुरू करते हैं :
1.class # Fixnum 100000000000.class # Bignum
रूबी हमारे लिए सही वर्ग बनाता है, और यह स्वचालित रूप से एक Fixnum
. को बढ़ावा देगा एक Bignum
. के लिए जब आवश्यक हो।
नोट :Bignum
. प्राप्त करने के लिए आपको एक बड़ी संख्या की आवश्यकता हो सकती है ऑब्जेक्ट अगर आपके पास 64-बिट रूबी दुभाषिया है।
हमें विभिन्न वर्गों की आवश्यकता क्यों है? इसका उत्तर यह है कि बड़ी संख्याओं के साथ काम करने के लिए आपको एक अलग कार्यान्वयन की आवश्यकता होती है, और बड़ी संख्याओं के साथ काम करना धीमा होता है, इसलिए हम Float
जैसी ही स्थिति के साथ समाप्त होते हैं। बनाम BigDecimal
।
Fixnums के विशेष गुण
Fixnum
कक्षा में कुछ विशेष गुण भी होते हैं। उदाहरण के लिए, ऑब्जेक्ट आईडी की गणना एक सूत्र का उपयोग करके की जाती है।
1.object_id # 3 20.object_id # 41
सूत्र है:(number * 2) + 1
।
लेकिन इसमें और भी बहुत कुछ है, जब आप Fixnum
. का उपयोग करते हैं कोई वस्तु बिल्कुल नहीं बनाई जा रही है। Fixnum
. में स्टोर करने के लिए कोई डेटा नहीं है , क्योंकि मान ऑब्जेक्ट आईडी से ही प्राप्त होता है।
यह सिर्फ एक कार्यान्वयन विवरण है, लेकिन मुझे लगता है कि यह जानना दिलचस्प है
MRI (Matz's Ruby Interpreter) वैल्यू और ऑब्जेक्ट आईडी के बीच कनवर्ट करने के लिए इन दो मैक्रोज़ का उपयोग करता है:
INT2FIX(i) ((VALUE)(((SIGNED_VALUE)(i))<<1 | FIXNUM_FLAG)) FIX2LONG(x) ((long)RSHIFT((SIGNED_VALUE)(x),1))
यहां जो होता है उसे "बिट शिफ्टिंग" कहा जाता है, जो सभी बिट्स को बाईं या दाईं ओर ले जाता है।
एक स्थिति को बाईं ओर स्थानांतरित करना 2 से गुणा करने के बराबर है और इसीलिए सूत्र है (number * 2) + 1
. +1 FIXNUM_FLAG
. से आता है ।
इसके विपरीत, Bignum
सामान्य वर्ग की तरह अधिक काम करता है और सामान्य वस्तु आईडी का उपयोग करता है:
111111111111111.object_id # 23885808
इसका मतलब यह है कि Fixnum
वस्तुएं दुभाषिया स्तर पर कैसे काम करती हैं, इस संदर्भ में प्रतीकों के करीब हैं, जबकि Bignum
ऑब्जेक्ट स्ट्रिंग्स के करीब होते हैं।
2.4 में पूर्णांक
चूंकि रूबी 2.4 फिक्सनम और बिग्नम बहिष्कृत हैं, लेकिन पर्दे के पीछे वे अभी भी उसी तरह काम करते हैं।
रूबी स्वचालित रूप से एक प्रकार से दूसरे प्रकार में स्विच हो जाती है।
कक्षा बदले बिना ।
इसका मतलब है कि छोटा Integer
नंबर अभी भी उसी तरह से काम करते हैं जैसे Fixnum
।
सारांश
इस पोस्ट में, आपने रूबी में मौजूद विभिन्न संख्या-संबंधित वर्गों के बारे में सीखा।
आपने सीखा कि फ़्लोट सटीक नहीं होते हैं और आप BigDecimal
. का उपयोग कर सकते हैं यदि सटीकता प्रदर्शन से कहीं अधिक महत्वपूर्ण है। आपने यह भी सीखा कि Fixnum
ऑब्जेक्ट दुभाषिया स्तर पर विशेष हैं, लेकिन Bignum
s केवल नियमित वस्तुएं हैं।
अगर आपको यह पोस्ट दिलचस्प लगी हो तो नीचे दिए गए फॉर्म में मेरे न्यूज़लेटर के लिए साइन-अप करना न भूलें 🙂