2011-07-27 16 views
9

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

उदा .:

var a = 17516032;   // has 25 bits 
alert(a << 7)    // outputs -2052915200 
alert(a * 128)    // outputs 2242052096 
alert(2242052096 >> 16) // outputs -31325 
alert(2242052096/65536) // outputs 34211 

जबकि पहले वैकल्पिक हल (बाएं पारी के बजाय गुणा) स्वीकार्य है, दूसरा नहीं है।

ऐसा क्यों होता है? इसके साथ कैसे सहन करें?

+0

मुझे यह नहीं पता कि विभाजन क्यों स्वीकार्य नहीं होगा? – Guffa

+0

@ गुफा मुझे केवल 32 बिट पूर्णांक के लिए कुछ सामान्य दृष्टिकोण की आवश्यकता नहीं है। –

+0

डिवीजन पूर्णांक पर नहीं किया जाता है, यह फ़्लोटिंग पॉइंट नंबर पर किया जाता है, इसलिए मुझे आपकी तर्क समझ में नहीं आती है। इसके अलावा, एक डबल परिशुद्धता फ़्लोटिंग पॉइंट नंबर केवल 53 बिट पूर्णांक का प्रतिनिधित्व कर सकता है, इसलिए यदि आप बीईआर-संपीड़ित संख्याओं को डीकोड करना चाहते हैं तो यह बहुत कुछ नहीं है। – Guffa

उत्तर

7

17516032 बाइनरी में 00000001000010110100011000000000 है। 7 से बाएं स्थानांतरित करने से आपको 10000101101000110000000000000000 मिल जाता है। यह के बराबर two's complement (जो लगभग सभी कंप्यूटर नकारात्मक संख्याओं का प्रतिनिधित्व करते हैं) के बराबर है।

>> एक हस्ताक्षरित सही शिफ्ट है। इसका मतलब है कि बाएं सबसे बिट (जो किसी संख्या का संकेत निर्धारित करता है) को बाईं तरफ स्थानांतरित कर दिया जाएगा।

उदा।

1100 >> 2 == 1111 
0111 >> 2 == 0001 

आप एक अहस्ताक्षरित पारी (जो संकेत बिट पर ध्यान नहीं देता) करना चाहते हैं, >>> का उपयोग जो होगा bitstring के बाएं छोर शून्य से भरना।

+0

यह है, धन्यवाद! कोई विचार क्यों बाएं शिफ्ट इस तरह के अजीब परिणाम पैदा करता है? –

+0

कोई समस्या नहीं है। उसमें शामिल करने के लिए मेरा जवाब संपादित किया। – tskuzzy

3

बिटवाई ऑपरेटर 32 बिट पूर्णांक पर काम करते हैं, जबकि गुणा और विभाजन फ़्लोटिंग पॉइंट नंबर पर काम करता है।

जब आप कोई संख्या बदलते हैं, तो इसे ऑपरेशन से पहले एक फ्लोटिंग पॉइंट नंबर से 32 बिट पूर्णांक में परिवर्तित किया जाता है, और ऑपरेशन के बाद फ़्लोटिंग पॉइंट नंबर पर वापस परिवर्तित किया जाता है। 22420520 9 6 में 32 वां बिट सेट है, इसलिए यह 32 बिट पूर्णांक में परिवर्तित होने पर एक नकारात्मक संख्या है।

>> सही शिफ्ट ऑपरेटर मूल्य के संकेत को नहीं बदलता है, यानी बाईं ओर से स्थानांतरित बिट्स के पास बिट बिट के समान मूल्य होता है। इसके बजाय शून्य बिट्स में स्थानांतरित करने के लिए >>> दायां शिफ्ट ऑपरेटर का उपयोग करें।

संदर्भ: MDN: Bitwise operators

2

(2242052096/65536) == (2242052096 >>> 16)

नोट अलग पाली।

1

जावास्क्रिप्ट सामान्य रूप से संख्याओं को डबल (सटीक) फ्लोटिंग पॉइंट के रूप में दर्शाता है।

लगभग सभी बिटवाई ऑपरेशंस एक हस्ताक्षरित 32-बिट पूर्णांक में कनवर्ट करते हैं, जो भी वे करने जा रहे हैं, फिर परिणाम को वापस परिवर्तित करते समय हस्ताक्षरित 32-बिट पूर्णांक के रूप में देखें।

अपवाद >>> है जो परिणाम को के रूप में संरेखित 32-बिट पूर्णांक को वापस परिवर्तित करते समय मानता है।

तो:

  • सही बदलाव >>> बजाय >> का उपयोग करके बस काम करने के लिए बनाया जा सकता है;
  • a * 128 अपेक्षित उत्तर देता है क्योंकि यह पहली बार किसी हस्ताक्षरित 32-बिट पूर्णांक में परिवर्तित नहीं होता है - यह केवल एक फ़्लोटिंग-पॉइंट गुणा है;
  • a << 7 एक अप्रत्याशित उत्तर देता है क्योंकि यह एक हस्ताक्षरित 32-बिट पूर्णांक में परिवर्तित हो जाता है, और फिर आप 1 को साइन बिट में स्थानांतरित करते हैं, जिसके परिणामस्वरूप ऋणात्मक 32-बिट मान नकारात्मक होता है।

वहाँ एक <<< नहीं है, लेकिन अगर आप एक परिवर्तन के रूप में अपनी बाईं पारी लिखना चाहते हैं, आप

(a << 7) >>> 0 

उम्मीद जवाब (>>> 0 प्रभावी रूप से प्राप्त करने के लिए उपयोग कर सकते हैं डाले हस्ताक्षर किए 32- एक हस्ताक्षरित 32-बिट मान के लिए बिट मान)।

+0

अच्छा। समझाने के लिए धन्यवाद! –

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