नंबर को फ़्लोर करने के लिए बिटवाइज़ या 0 का उपयोग करना


192

मेरी एक सहकर्मी एक बिटवाइज़ या:

var a = 13.6 | 0; //a == 13

हम इसके बारे में बात कर रहे थे और कुछ चीजें सोच रहे थे।

  • यह कैसे काम करता है? हमारा सिद्धांत यह था कि इस तरह के एक ऑपरेटर का उपयोग करके किसी पूर्णांक में संख्या डाली जाती है, इस प्रकार अंश को हटा दिया जाता है
  • क्या इसे करने से कोई फायदा है Math.floor? शायद यह थोड़ा तेज है? (पंच का इरादा नहीं)
  • क्या इसके कोई नुकसान हैं? शायद यह कुछ मामलों में काम नहीं करता है? स्पष्टता एक स्पष्ट बात है, क्योंकि हमें इसका पता लगाना था, और ठीक है, मैं इस प्रश्न को लिख रहा हूं।

धन्यवाद।


6
नुकसान: यह केवल 2 ^ 31 which1 तक काम करता है जो लगभग 2 बिलियन (10 ^ 9) है। अधिकतम संख्या मान लगभग 10 ^ 308 btw है।
51इमे विद सिप

12
उदाहरण: 3000000000.1 | 0-1294967296 का मूल्यांकन करता है। इसलिए इस पद्धति को धन गणना के लिए लागू नहीं किया जा सकता है (विशेषकर ऐसे मामलों में जहां आप दशमलव संख्या से बचने के लिए 100 से गुणा करते हैं)।
08इमे विद सिप

13
@ MoneyimeVidas फ़्लोट्स का उपयोग पैसे की गणना में भी नहीं किया जाना चाहिए
जॉर्ज रीथ

20
यह फर्श नहीं है, यह छोटा है (0 की ओर गोल)।
बार्टोलोमिएज ज़ाल्स्की

3
परिणाम 0.1 + 0.2 == 0.3एक जावास्क्रिप्ट कंसोल में टाइप करने का प्रयास करें । यदि आपकी भाषा इसका समर्थन करती है, तो आपको एक दशमलव प्रकार का उपयोग करना चाहिए। यदि नहीं, तो इसके बजाय सेंट स्टोर करें।
एलेक्स टर्पिन

जवाबों:


161

यह कैसे काम करता है? हमारा सिद्धांत यह था कि इस तरह के एक ऑपरेटर का उपयोग करके किसी पूर्णांक में संख्या डाली जाती है, इस प्रकार अंश को हटा दिया जाता है

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

यह Math.floor करने पर कोई लाभ है? शायद यह थोड़ा तेज है? (पंच का इरादा नहीं)

http://jsperf.com/or-vs-floor/2 थोड़ा तेज लगता है

क्या इसके कोई नुकसान हैं? शायद यह कुछ मामलों में काम नहीं करता है? स्पष्टता एक स्पष्ट बात है, क्योंकि हमें इसका पता लगाना था, और ठीक है, मैं इस प्रश्न को लिख रहा हूं।

  • JsLint पास नहीं करेगा।
  • 32-बिट पूर्णांक पर हस्ताक्षर किए
  • अजीब तुलनात्मक व्यवहार:, Math.floor(NaN) === NaNजबकि(NaN | 0) === 0

9
@ फेरोल्ड वास्तव में, क्योंकि यह वास्तव में गोल नहीं है, केवल छोटा है।
एलेक्स टर्पिन

5
एक और संभावित नुकसान है Math.floor(NaN) === NaN, जबकि (NaN | 0) === 0। कुछ अनुप्रयोगों में यह अंतर महत्वपूर्ण हो सकता है।
टेड होप

4
लूप इनवेरिएंट कोड मोशन के कारण आपका jsperf क्रोम पर खाली छोरों के लिए प्रदर्शन की जानकारी दे रहा है। थोड़ा बेहतर परफेक्ट
सैम जाइल्स

4
यह asm.js(जहां मैंने पहली बार इसके बारे में सीखा था) का एक मानक हिस्सा है । यदि यह किसी अन्य कारण से तेज है, तो यह Mathऑब्जेक्ट पर एक फ़ंक्शन को कॉल नहीं कर रहा है , एक फ़ंक्शन जिसे कभी भी बदल दिया जा सकता है Math.floor = function(...)
GMAN

3
(value | 0) === valueयह जांचने के लिए इस्तेमाल किया जा सकता है कि एक मूल्य वास्तव में एक पूर्णांक और केवल एक पूर्णांक है (जैसा कि एल्म स्रोत कोड @ ड्वेन-क्रुक से जुड़ा हुआ है)। और foo = foo | 0किसी भी मान को पूर्णांक में ले जाने के लिए इस्तेमाल किया जा सकता है (जहां 32-बिट संख्याओं को काट दिया जाता है और सभी गैर-संख्याएँ 0 होती हैं)।
डेविड माइकल ग्रेग

36

यह फर्श के विपरीत ट्रंकेशन है । हॉवर्ड का जवाब सही है; लेकिन मैं Math.floorइसमें वही जोड़ूंगा जो नकारात्मक संख्या के संबंध में है। गणितीय रूप से, यह वही है जो एक मंजिल है।

ऊपर वर्णित मामले में, प्रोग्रामर को ट्रंकेशन में अधिक रुचि थी या दशमलव को पूरी तरह से काट दिया। हालाँकि, वाक्यविन्यास उन्होंने इस तथ्य का अस्पष्ट उपयोग किया कि वे फ्लोट को एक इंट में परिवर्तित कर रहे हैं।


7
यह सही उत्तर है, स्वीकार नहीं किया गया है। इसमें वह Math.floor(8589934591.1)परिणाम जोड़ें जो अपेक्षित परिणाम 8589934591.1 | 0 नहीं देता है
सलमान ए

21

ECMAScript 6 में, के बराबर |0है Math.trunc , एक तरह से मैं कहना चाहिए:

किसी भी अंश अंकों को हटाकर किसी संख्या का अभिन्न हिस्सा लौटाता है। यह सिर्फ डॉट और इसके पीछे के अंकों को काटता है, चाहे वह तर्क सकारात्मक संख्या हो या नकारात्मक संख्या।

Math.trunc(13.37)   // 13
Math.trunc(42.84)   // 42
Math.trunc(0.123)   //  0
Math.trunc(-0.123)  // -0
Math.trunc("-1.123")// -1
Math.trunc(NaN)     // NaN
Math.trunc("foo")   // NaN
Math.trunc()        // NaN

6
इस तथ्य को छोड़कर कि Math.trunc()संख्या 2 या 31 के बराबर या उससे अधिक के साथ काम | 0करती है
Nolyurn

10

आपकी पहली बात सही है। संख्या एक पूर्णांक पर डाली जाती है और इस प्रकार किसी भी दशमलव अंक हटा दिए जाते हैं। कृपया ध्यान दें, Math.floorमाइनस इनफिनिटी की ओर अगले पूर्णांक तक यह राउंड होता है और इस प्रकार ऋणात्मक संख्याओं पर लागू होने पर एक अलग परिणाम देता है।


5

जावास्क्रिप्ट डबल प्रिसिजन 64-बिट फ्लोटिंग नंबरों केNumber रूप में प्रतिनिधित्व करता है ।

Math.floor इसे ध्यान में रखकर काम करता है।

32 बिट हस्ताक्षरित पूर्णांकों में बिटवाइज संचालन कार्य करता है । 32 बिट हस्ताक्षरित पूर्णांक नकारात्मक हस्ताक्षरकर्ता के रूप में पहले बिट का उपयोग करते हैं और अन्य 31 बिट संख्या हैं। इसके कारण, न्यूनतम और अधिकतम संख्या की अनुमति दी गई 32 बिट पर हस्ताक्षर किए गए नंबर क्रमशः -2,147,483,648 और 2147483647 (0x7FFFFFFFF) हैं।

इसलिए जब आप कर रहे हैं | 0, तो आप अनिवार्य रूप से कर रहे हैं & 0xFFFFFFFF। इसका मतलब है, कोई भी संख्या जिसे 0x80000000 (2147483648) के रूप में दर्शाया गया है या उससे अधिक एक नकारात्मक संख्या के रूप में वापस आ जाएगी।

उदाहरण के लिए:

 // Safe
 (2147483647.5918 & 0xFFFFFFFF) ===  2147483647
 (2147483647      & 0xFFFFFFFF) ===  2147483647
 (200.59082098    & 0xFFFFFFFF) ===  200
 (0X7FFFFFFF      & 0xFFFFFFFF) ===  0X7FFFFFFF

 // Unsafe
 (2147483648      & 0xFFFFFFFF) === -2147483648
 (-2147483649     & 0xFFFFFFFF) ===  2147483647
 (0x80000000      & 0xFFFFFFFF) === -2147483648
 (3000000000.5    & 0xFFFFFFFF) === -1294967296

इसके अलावा। बिटवाइज़ ऑपरेशन्स "फ्लोर" नहीं करते हैं। वे छंटनी करते हैं , जो कहने के समान है, वे निकटतम गोल करते हैं 0। एक बार जब आप ऋणात्मक संख्याओं के लिए चारों ओर जाना है, Math.floorदौर नीचे जबकि बिटवाइज़ गोलाई शुरू अप

जैसा कि मैंने पहले कहा, Math.floorसुरक्षित है क्योंकि यह 64 बिट फ्लोटिंग नंबरों के साथ काम करता है। बिटवाइज़ तेज़ है , हाँ, लेकिन 32 बिट पर हस्ताक्षर किए गए दायरे तक सीमित है।

संक्षेप में:

  • यदि आप काम करते हैं तो बिटवाइज वही काम करता है 0 to 2147483647
  • यदि आप काम करते हैं तो बिटवाइज़ 1 नंबर बंद है -2147483647 to 0
  • बिटवाइज संख्या से कम -2147483648और अधिक से अधिक के लिए पूरी तरह से अलग है 2147483647

यदि आप वास्तव में प्रदर्शन को ट्विस्ट करना चाहते हैं और दोनों का उपयोग करना चाहते हैं:

function floor(n) {
    if (n >= 0 && n < 0x80000000) {
      return n & 0xFFFFFFFF;
    }
    if (n > -0x80000000 && n < 0) {
      return (n - 1) & 0xFFFFFFFF;
    }
    return Math.floor(n);
}

बस Math.truncबिटवाइज़ ऑपरेशंस जैसे कामों को जोड़ना है । तो आप यह कर सकते हैं:

function trunc(n) {
    if (n > -0x80000000 && n < 0x80000000) {
      return n & 0xFFFFFFFF;
    }
    return Math.trunc(n);
}

5
  • चश्मा का कहना है कि यह एक पूर्णांक में बदल जाता है:

    आज्ञा देना lnum ToInt32 (lval)।

  • प्रदर्शन: इससे पहले jsperf पर परीक्षण किया गया है ।

नोट: हटाए गए कल्पना के लिए मृत लिंक

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