Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

रूबी नंबर मास्टर करें: इंटीजर, फ्लोट और BigDecimal समझाया गया

रूबी 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]

अब इन क्लासेस को टेबल के रूप में देखते हैं:

क्लास विवरण उदाहरण
Integer Fixnum और Bignum की पेरेंट क्लास 1
Fixnum वे पूर्णांक जो OS इंटीजर टाइप में फिट होते हैं (32 या 64 बिट्स) 1
Bignum बड़ी संख्याओं के लिए उपयोग किया जाता है 111111111111
Float असटीक दशमलव संख्याएं 5.0
Complex काल्पनिक संख्याओं वाले गणित के लिए उपयोग किया जाता है (1+0i)
Rational भिन्नों को दर्शाने के लिए उपयोग किया जाता है (2/3)
BigDecimal सटीक दशमलव संख्याएं 3.0

फ्लोट की असटीकता

आधिकारिक रूबी डॉक्यूमेंटेशन में Float क्लास को "असटीक" बताया गया है।

ऐसा क्यों है?

मैं आपको एक उदाहरण दिखाता हूं:

0.2 + 0.1 == 0.3 # false

यह false क्यों है?

आइए 0.2 + 0.1 के परिणाम को देखते हैं:

0.30000000000000004

बिल्कुल! यही वह असटीकता है जिसका हम मतलब रखते हैं।

ऐसा इसलिए होता है क्योंकि फ्लोट को स्टोर करने का तरीका ऐसा है। यदि आपको ऐसी दशमलव संख्याएं चाहिए जो हमेशा सटीक हों, तो आप BigDecimal क्लास का उपयोग कर सकते हैं।

Float बनाम BigDecimal

BigDecimal एक ऐसी क्लास है जो आपको मनमानी-परिशुद्धता (arbitrary-precision) वाली दशमलव संख्याएं देती है।

उदाहरण:

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

इस सेक्शन में, मैं रूबी 2.4 से पहले Fixnum और Bignum के बीच के अंतरों का पता लगाना चाहता हूं।

आइए कुछ कोड से शुरू करते हैं:

1.class # Fixnum 100000000000.class # Bignum

रूबी हमारे लिए सही क्लास बनाता है, और जब आवश्यक हो तो यह स्वचालित रूप से एक Fixnum को Bignum में प्रोमोट कर देता है।

नोट: यदि आपके पास 64-बिट रूबी इंटरप्रेटर है, तो Bignum ऑब्जेक्ट प्राप्त करने के लिए आपको एक बड़ी संख्या की आवश्यकता हो सकती है।

हमें अलग-अलग क्लासेस की आवश्यकता क्यों है? इसका उत्तर यह है कि बड़ी संख्याओं के साथ काम करने के लिए आपको एक अलग इम्प्लीमेंटेशन की आवश्यकता होती है, और बड़ी संख्याओं के साथ काम करना धीमा होता है, इसलिए हम Float बनाम BigDecimal जैसी ही स्थिति में पहुंच जाते हैं।

Fixnum के विशेष गुण

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 में Fixnum और Bignum डिप्रेकेटेड हैं, लेकिन पर्दे के पीछे वे अभी भी उसी तरह काम करते हैं।

रूबी एक टाइप से दूसरे टाइप पर स्वचालित रूप से स्विच करता है।

क्लास बदले बिना।

इसका मतलब है कि छोटी Integer संख्याएं अभी भी उसी तरह काम करती हैं जैसे Fixnum।

सारांश

इस पोस्ट में, आपने रूबी में मौजूद विभिन्न नंबर-संबंधी क्लासेस के बारे में सीखा।

आपने सीखा कि फ्लोट्स असटीक होते हैं और यदि सटीकता प्रदर्शन से कहीं अधिक महत्वपूर्ण है तो आप BigDecimal का उपयोग कर सकते हैं। आपने यह भी सीखा कि इंटरप्रेटर लेवल पर Fixnum ऑब्जेक्ट्स विशेष होते हैं, लेकिन Bignum सामान्य ऑब्जेक्ट्स होते हैं।

यदि आपको यह पोस्ट दिलचस्प लगी तो नीचे दिए गए फॉर्म में मेरे न्यूज़लेटर के लिए साइन-अप करना न भूलें 🙂

  1. रूबी में AASM के साथ स्टेट मशीन्स में महारत हासिल करें: एक व्यावहारिक गाइड रूबी में AASM के साथ स्टेट मशीन्स में महारत हासिल करें: एक व्यावहारिक गाइड

    आज आप स्टेट मशीन्स के बारे में सीखेंगे, वे कैसे काम करते हैं और AASM जेम के साथ अपने रूबी प्रोजेक्ट्स में उनका उपयोग कैसे करें। अब: एक ट्रैफिक लाइट की कल्पना करें... यह लाल, हरा या पीला हो सकता है। जब यह रंग बदलता है, तो अगला रंग वर्तमान पर आधारित होता है। मान लें कि यह वह प्रकार है जो नेत्रहीन लोग

  1. रूबी 2.6 में MJIT को समझना: जस्ट-इन-टाइम कंपाइलर प्रदर्शन को कैसे बढ़ाता है रूबी 2.6 में MJIT को समझना: जस्ट-इन-टाइम कंपाइलर प्रदर्शन को कैसे बढ़ाता है

    रूबी का प्रदर्शन संस्करण दर संस्करण बहुत सुधर रहा है… और रूबी विकास टीम रूबी को और भी तेज़ बनाने के लिए हर संभव प्रयास कर रही है! इन प्रयासों में से एक 3×3 प्रोजेक्ट है। लक्ष्य? रूबी 3.0, रूबी 2.0 से 3 गुना तेज़ होगा। इस प्रोजेक्ट का हिस्सा नया MJIT कंपाइलर है, जो इस लेख का विषय है। MJIT समझाया गया

  1. रूबी एरे में महारत: व्यावहारिक उदाहरण और आवश्यक मेथड्स रूबी एरे में महारत: व्यावहारिक उदाहरण और आवश्यक मेथड्स

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