कैसे होता है !! ~ (न कि टिल्ड / बैंग बैंग टिल्ड) एक 'शामिल / शामिल' एरे विधि कॉल के परिणाम को बदल देता है?


95

यदि आप यहाँ jQuery inArrayपृष्ठ पर टिप्पणियाँ पढ़ते हैं , तो एक दिलचस्प घोषणा है:

!!~jQuery.inArray(elm, arr) 

अब, मेरा मानना ​​है कि डबल-विस्मयादिबोधक बिंदु परिणाम को प्रकार में बदल देगा boolean, के मूल्य के साथ true। मुझे समझ में नहीं आ रहा है कि ~इस सब में टिल्ड ( ) ऑपरेटर का क्या उपयोग है ?

var arr = ["one", "two", "three"];
if (jQuery.inArray("one", arr) > -1) { alert("Found"); }

ifबयान का खंडन:

if (!!~jQuery.inArray("one", arr)) { alert("Found"); }

टूट - फूट:

jQuery.inArray("one", arr)     // 0
~jQuery.inArray("one", arr)    // -1 (why?)
!~jQuery.inArray("one", arr)   // false
!!~jQuery.inArray("one", arr)  // true

मैंने यह भी देखा कि अगर मैंने टिल्ड को सामने रखा, तो इसका परिणाम है -2

~!!~jQuery.inArray("one", arr) // -2

मैं यहाँ टिल्ड के उद्देश्य को नहीं समझता। क्या कोई इसे समझा सकता है या मुझे किसी संसाधन की ओर संकेत कर सकता है?


50
जो कोई भी ऐसा कोड लिखता है जिसे कीबोर्ड से दूर जाने की आवश्यकता होती है।
कर्क वॉक

12
@KirkWoll: क्यों? ~jQuery.inArray()वास्तव में बहुत उपयोगी है - संभवतः यहां तक ​​कि एक बहुत अच्छा कारण है कि खोज फ़ंक्शन -1विफलता के लिए वापस लौटते हैं (एकमात्र मूल्य जिसका दो का पूरक गलत है)। एक बार जब आप चाल देख चुके हैं और समझ गए हैं, तो मुझे लगता है कि यह उससे भी अधिक पठनीय है != -1
आमदन

9
@ आमदन - नहीं। बस नहीं। सच में, मैं विश्वास नहीं कर सकता कि आप किसी भी चीज़ के!!~ लिए बचाव कर रहे हैं ।
Kirk Woll

24
समस्या यह है, यह सिर्फ इतना है: एक "चाल"। मेरे if (x != -1)और if (~x)मेरे बीच मुख्य अंतर यह है कि पूर्व वास्तव में व्यक्त करता है कि आप क्या करने का इरादा रखते हैं। उत्तरार्द्ध आपको पूरी तरह से कुछ और करने की इच्छा व्यक्त करता है ("कृपया मेरे 64-बिट नंबर को 32-बिट पूर्णांक में परिवर्तित करें, और जांचें कि क्या बिटवाइस का पूर्णांक सत्य नहीं है"), जहां आप सिर्फ वांछित परिणाम प्राप्त करने के लिए होते हैं। एक मामला।
जिमीटीएच

10
>= 0शायद पर्याप्त रूप से लेट नहीं किया गया था , इसलिए अधिक गुप्त !!~का उपयोग किया गया था।
योशी

जवाबों:


56

टिल्ड ऑपरेटर वास्तव में jQuery का हिस्सा नहीं है - यह जावास्क्रिप्ट में ही बिटवाइज़ नहीं ऑपरेटर है।

देखें टिल्ड का महान रहस्य (~)

आपको अपने प्रयोगों में अजीब संख्या मिल रही है क्योंकि आप एक पूर्णांक पर एक बिटवाइज़ लॉजिकल ऑपरेशन कर रहे हैं (जो, मुझे पता है कि दो के पूरक के रूप में संग्रहीत किया जा सकता है या ऐसा कुछ ...)

दो के पूरक बताते हैं कि बाइनरी में एक संख्या का प्रतिनिधित्व कैसे करें। मुझे लगता है कि मैं सही था।


3
फिक्स्ड! (इसे एक और कड़ी में बदल दिया, जो कि विचित्र रूप से पर्याप्त था, मेरे मूल उत्तर के बाद लिखा गया था ...)
pglhall

121

एक विशिष्ट कारण है जिसे आप कभी-कभी अपने ~सामने लागू होते देखेंगे $.inArray

मूल रूप से,

~$.inArray("foo", bar)

एक छोटा तरीका है

$.inArray("foo", bar) !== -1

$.inArrayसरणी में आइटम का इंडेक्स लौटाता है यदि पहला तर्क मिल जाता है, और यह -1 मिलता है अगर यह नहीं मिला। इसका मतलब है कि यदि आप "सरणी में यह मान है?" के बूलियन की तलाश कर रहे हैं, तो आप एक बूलियन तुलना नहीं कर सकते हैं, क्योंकि -1 एक सत्य मूल्य है, और जब $ .inArray 0 (एक झूठा मूल्य) लौटाता है। ), इसका मतलब है कि यह वास्तव में सरणी के पहले तत्व में पाया गया है।

~बिटवाइज़ ऑपरेटर को लागू करने का कारण बनता -1है 0, और 0 को `-1 बनने का कारण बनता है। इस प्रकार, एरे में मान नहीं मिल रहा है और बिटवाइज़ को लागू करने से फ़ेल्सी मान (0) में परिणाम नहीं होता है, और अन्य सभी मान गैर-0 नंबर वापस आ जाएंगे, और एक सत्य परिणाम का प्रतिनिधित्व करेंगे।

if (~$.inArray("foo", ["foo",2,3])) {
    // Will run
}

और यह इरादा के अनुसार काम करेगा।


2
ब्राउज़रों में यह कितनी अच्छी तरह समर्थित है (अब 2014 में?) या यह पूरी तरह से समर्थित था?
धमाका गोलियां

मुझे आश्चर्य होगा कि अगर इन जैसे बुनियादी ऑपरेशन सही नहीं होंगे।
pcarvalho

104

!!~exprfalseजब अन्यथा करने के लिए मूल्यांकन करता exprहै । यह वही है , जो केवल टूट गया है *-1true
expr != -1


यह काम करता है क्योंकि जावास्क्रिप्ट बिटवाइज़ ऑपरेशंस ऑपरेंड को 32-बिट हस्ताक्षरित पूर्णांक दो के पूरक प्रारूप में परिवर्तित करते हैं। इस प्रकार !!~-1मूल्यांकन किया जाता है:

   -1 = 1111 1111 1111 1111 1111 1111 1111 1111b // two's complement representation of -1
  ~-1 = 0000 0000 0000 0000 0000 0000 0000 0000b // ~ is bitwise not (invert all bits)
   !0 = true                                     // ! is logical not (true for falsy)
!true = false                                    // duh

के अलावा एक मूल्य -1शून्य से कम से कम एक बिट सेट होगा; यह एक सत्य मूल्य पैदा करेगा; !ऑपरेटर को दो बार एक सत्य मूल्य पर लागू करना बूलियन सच है।

जब उपयोग किया जाता है .indexOf()और हम केवल यह जांचना चाहते हैं कि परिणाम है -1या नहीं:

!!~"abc".indexOf("d") // indexOf() returns -1, the expression evaluates to false
!!~"abc".indexOf("a") // indexOf() returns  0, the expression evaluates to true
!!~"abc".indexOf("b") // indexOf() returns  1, the expression evaluates to true

* !!~8589934591असत्य का मूल्यांकन करता हैनफरतके लिए परीक्षण करने के लिए मज़बूती से इस्तेमाल नहीं किया जा सकता है -1


1
एक स्थिर लाइब्रेरी में, मैं उपयोग करने के साथ कोई समस्या नहीं देखता हूं ~foo.indexOf(bar), यह पात्रों या प्रदर्शन पर महत्वपूर्ण बचत नहीं है, लेकिन यह उसी तरह से अपेक्षाकृत सामान्य शॉर्टहैंड foo = foo || {}है।
zzzzBov

6
यह कोई मुद्दा नहीं है ... कम से कम तब तक नहीं जब तक किसी और को आपके कोड के साथ जारी रखने के लिए नहीं कहा जाता है।
सलमान एक


1
@ahsteele, मैं उस नियम से अच्छी तरह वाकिफ हूँ, हालाँकि बिटकॉइन ऑपरेटर हर प्रोग्रामिंग भाषा का एक हिस्सा है, जिसके बारे में मैं सोच सकता हूँ। मैं एक तरह से प्रोग्राम करने की कोशिश करता हूं जो किसी ऐसे व्यक्ति के लिए पठनीय हो जो कोड पढ़ सकता है । मैं किसी भाषा की सुविधाओं का उपयोग केवल इसलिए नहीं करता क्योंकि कोई और इसे नहीं समझता है, अन्यथा मैं भी उपयोग नहीं कर पाऊंगा!!
zzzzBov

कड़ाई से बोलना, >= 0जैसा व्यवहार है वैसा नहीं है !!~!== -1निकट है।
पीटर ओल्सन

33

~foo.indexOf(bar)एक सामान्य आशुलिपि का प्रतिनिधित्व करने के लिए है foo.contains(bar)क्योंकि containsफ़ंक्शन मौजूद नहीं है।

आमतौर पर बूलियन के लिए डाली जावास्क्रिप्ट "मिथ्या" मूल्यों की अवधारणा के कारण अनावश्यक है। इस मामले में इसका उपयोग फ़ंक्शन के आउटपुट को बलपूर्वक trueया करने के लिए किया जाता है false


6
+1 यह उत्तर "क्यों" को स्वीकार किए गए उत्तर से बेहतर बताता है।
nalply

18

jQuery.inArray()-1"नहीं मिला" के लिए रिटर्न , जिसका पूरक ( ~) है 0। इस प्रकार, "नहीं मिला" के लिए ~jQuery.inArray()एक मिथ्या मान ( 0) और एक सत्य मान ("पूर्णांक" के लिए एक नकारात्मक पूर्णांक) लौटाता है । !!फिर असली बुलियन में falsy / truthy को औपचारिक होगा false/ true। तो, "पाया" और "नहीं मिला" के लिए !!~jQuery.inArray()दे देंगे ।truefalse



10

~ऑपरेटर बिटवाइज़ पूरक ऑपरेटर है। से पूर्णांक परिणाम inArray()-1 है, जब तत्व नहीं मिला है, या कुछ गैर-नकारात्मक पूर्णांक है। -1 का बिटवाइज पूरक (बाइनरी में सभी 1 बिट्स के रूप में दर्शाया गया है) शून्य है। किसी भी गैर-नकारात्मक पूर्णांक का बिटवाइज-पूरक हमेशा गैर-शून्य होता है।

इस प्रकार, तब !!~iहोगा trueजब पूर्णांक "i" एक गैर-नकारात्मक पूर्णांक है, और falseजब "i" ठीक -1 है।

ध्यान दें कि ~हमेशा अपने ऑपरेटर को पूर्णांक के लिए मजबूर करता है; यही है, यह पूर्णांक के लिए गैर-पूर्णांक फ़्लोटिंग मान को बाध्य करता है, साथ ही गैर-संख्यात्मक मान भी।


10

टिल्ड बिटवाइस नहीं है - यह मूल्य के प्रत्येक बिट को निष्क्रिय करता है। अंगूठे के एक सामान्य नियम के रूप में, यदि आप ~एक नंबर पर उपयोग करते हैं, तो इसका संकेत उल्टा होगा, फिर 1 को घटाया जाएगा।

इस प्रकार, जब आप करते हैं ~0, तो आपको -1 (0 उलटा -0 होता है, घटाव 1 -1 है)।

यह अनिवार्य रूप से एक मूल्य है कि हमेशा बूलियन हो रही है का एक विस्तृत, सुपर-माइक्रो-अनुकूलित तरीका है।


8

आप सही कह रहे हैं: falseजब indexOfकॉल -1 वापस आएगा तो यह कोड वापस आ जाएगा ; अन्यथा true

जैसा कि आप कहते हैं, जैसे कुछ का उपयोग करना अधिक समझदार होगा

return this.modifiedPaths.indexOf(path) !== -1;

1
लेकिन यह ग्राहक को भेजने के लिए 3 और बाइट्स है! संपादित करें: (जिस तरह से मजाक करते हुए, मेरी टिप्पणी पोस्ट की और महसूस किया कि यह स्पष्ट नहीं था (जो उदास और मूर्खतापूर्ण है))
वेस्ले मर्च

@Wesley: यह सच है, लेकिन इसे केवल एक बार प्रत्येक ग्राहक को भेजना होगा, यह मानते हुए कि ग्राहक कैश करेगा .js। यह कहने के बाद कि वे इसके >=0बजाय उपयोग कर सकते हैं !==-1- भेजने के लिए कोई अतिरिक्त बाइट नहीं है और अभी भी बिट-ट्विडलिंग संस्करण की तुलना में अधिक पठनीय है।
ल्यूक

2
कौन है यहां ट्रोलिंग? ;) मुझे लगता है कि मैंने इसे स्वीकार कर लिया है कि पढ़ने योग्य कोड लिखना क्रिप्टिक प्री-ऑप्टिमाइज़्ड कोड से बेहतर है जो इस तरह के प्रश्न उत्पन्न करता है। बाद में संक्षिप्त करें और अब पढ़ने योग्य, समझने योग्य कोड लिखें।
वेस्ले मर्च

2
व्यक्तिगत रूप से मैं कहूंगा कि > -1यह और भी पठनीय है, लेकिन यह शायद बहुत व्यक्तिपरक है।
योशी

6

~ऑपरेटर बिटवाइज़ नहीं ऑपरेटर है। इसका मतलब यह है कि यह द्विआधारी रूप में एक संख्या लेता है और सभी शून्य को लोगों में और लोगों को शून्य में बदल देता है।

उदाहरण के लिए, बाइनरी में संख्या 0 है 0000000, जबकि -1 है 11111111। इसी तरह, 1 00000001बाइनरी में है, जबकि -2 है 11111110


3

मेरा अनुमान है कि यह वहाँ है क्योंकि यह कुछ अक्षर कम है (जो कि पुस्तकालय लेखक हमेशा के बाद हैं)। यह उन परिचालनों का भी उपयोग करता है जो केवल देशी कोड में संकलित होने पर कुछ मशीन चक्र लेते हैं (जैसा कि संख्या की तुलना में विरोध किया जाता है।)

मैं एक और जवाब से सहमत हूं कि यह एक ओवरकिल है, लेकिन शायद एक तंग लूप में समझ हो सकती है (प्रदर्शन लाभ अनुमान की आवश्यकता है, हालांकि, अन्यथा समय से पहले अनुकूलन हो सकता है।)


2

मुझे लगता है, क्योंकि यह एक बिटवाइज़ ऑपरेशन है, यह जांचने का सबसे तेज़ (कम्प्यूटेशनल रूप से सस्ता) तरीका है कि संशोधित गठरी में पथ दिखाई देता है या नहीं।


1

जैसा (~(-1)) === 0, इसलिए:

!!(~(-1)) === Boolean(~(-1)) === Boolean(0) === false

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

मुझे लगता है कि यह जवाब समझ में आता है। यदि आपके पास एक गणितीय मस्तिष्क है, तो आप स्पष्ट रूप से देख सकते हैं कि प्रत्येक चरण में कौन से हिस्से बदल रहे हैं। क्या यह इस सवाल का सबसे अच्छा जवाब है? नहीं, लेकिन यह उपयोगी है, मुझे ऐसा लगता है! +1
टेलर लोपेज 15
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.