जावास्क्रिप्ट में ~~ ("डबल टिल्ड") क्या करता है?


204

मैं आज एक ऑनलाइन गेम भौतिकी पुस्तकालय की जाँच कर रहा था और ~~ ऑपरेटर के पार आया। मुझे पता है कि एक एकल ~ एक बिटवाइज़ नहीं है, क्या यह ~~ नॉट ऑफ़ ए नॉट, जो एक ही मूल्य वापस दिलाएगा, क्या यह नहीं होगा?


जवाबों:


248

यह दशमलव बिंदु के बाद सब कुछ हटा देता है क्योंकि बिटवाइज़ ऑपरेटर अपने ऑपरेटरों को हस्ताक्षरित रूप से 32-बिट पूर्णांक में परिवर्तित करते हैं। यह काम करता है कि क्या ऑपरेंड (फ्लोटिंग-पॉइंट) नंबर या स्ट्रिंग्स हैं, और परिणाम एक संख्या है।

दूसरे शब्दों में, इसकी पैदावार होती है:

function(x) {
  if(x < 0) return Math.ceil(x);
  else return Math.floor(x);
}

केवल अगर x के बीच है - (2 31 ) और 2 31 - 1. अन्यथा, अतिप्रवाह होगा और संख्या "चारों ओर लपेट" होगी।

किसी फ़ंक्शन के स्ट्रिंग तर्क को एक संख्या में परिवर्तित करने के लिए इसे उपयोगी माना जा सकता है, लेकिन दोनों अतिप्रवाह की संभावना के कारण और यह कि यह गैर-पूर्णांक के साथ उपयोग करने के लिए गलत है, मैं इसे "कोड गोल्फ" ( यानी) को छोड़कर इस तरह से उपयोग नहीं करूंगा अनावश्यक रूप से ट्रिमिंग बाइट पठनीयता और मजबूती के मूल्य पर आपके कार्यक्रम के स्रोत कोड को बंद कर देता है)। मैं उपयोग +xया Number(x)इसके बजाय होगा।


यह कैसे नहीं की नहीं है

उदाहरण के लिए संख्या -43.2 है:

-43.2 10 = 11111111111111111111111111110101 2

हस्ताक्षरित (दो का पूरक) 32-बिट बाइनरी नंबर के रूप में। (जावास्क्रिप्ट दशमलव बिंदु के बाद क्या है की उपेक्षा करता है।) बिट्स देता है:

नहीं -43 10 = 00000000000000000000000000101010 2 = 42 10

फिर से निकलना देता है:

नहीं 42 10 = 11111111111111111111111111010101 2 = -43 10

यह Math.floor(-43.2)उस नकारात्मक संख्या से भिन्न होता है जो शून्य की ओर होती है, इससे दूर नहीं। (फर्श फ़ंक्शन, जो -44 के बराबर होगा, हमेशा अगले निचले पूर्णांक तक गोल होता है, भले ही संख्या सकारात्मक या नकारात्मक हो।)


6
जो कहना है, ~~एक छोटा रास्ता है (और संभवतः एक अच्छा समाधान?) एक छोटा समारोह बनाने के लिए , लेकिन जाहिर है जावास्क्रिप्ट में
रफिन

4
JSLint के उपयोग के बारे में शिकायत करेंगे ~~
रिचर्ड कुक

1
Math.trunc ()
Xitalogy

30

पहले ~ ऑपरेटर ऑपरेटर को पूर्णांक (संभवतः स्ट्रिंग या बूलियन के लिए मान के बाद) के लिए बाध्य करता है, फिर सबसे कम 31 बिट्स को निष्क्रिय करता है। आधिकारिक तौर पर ECMAScript नंबर सभी फ्लोटिंग-पॉइंट हैं, लेकिन स्पाइडरमोंकी इंजन में कुछ संख्याएँ 31-बिट पूर्णांक के रूप में लागू की जाती हैं।

आप इसका उपयोग 1-तत्व सरणी को पूर्णांक में बदलने के लिए कर सकते हैं। फ्लोटिंग-पॉइंट्स को C रूल के अनुसार परिवर्तित किया जाता है, अर्थात। आंशिक भाग का काट-छाँट।

दूसरा ~ ऑपरेटर फिर बिट्स को निष्क्रिय कर देता है, इसलिए आप जानते हैं कि आपके पास एक पूर्णांक होगा। यह किसी स्टेटमेंट स्टेटमेंट में बूलियन के लिए एक मान के रूप में जबरदस्ती नहीं है, क्योंकि एक खाली वस्तु {} सत्य का मूल्यांकन करती है, जबकि ~~ {} गलत का मूल्यांकन करती है।

js>~~"yes"
0
js>~~3
3
js>~~"yes"
0
js>~~false
0
js>~~""
0
js>~~true
1
js>~~"3"
3
js>~~{}
0
js>~~{a:2}
0
js>~~[2]
2
js>~~[2,3]
0
js>~~{toString: function() {return 4}}
4
js>~~NaN
0
js>~~[4.5]
4
js>~~5.6
5
js>~~-5.6
-5

1
यहाँ शांति के सभी उदाहरणों के लिए धन्यवाद, यह वास्तव में मदद करता है!
शेन टोमलिन्सन

6
यह भी~~undefined // 0
प्राची

1
भी~~null // 0
chovy

तकनीकी रूप से आपके पास गलत आदेश है। दूसरा ~वही करता है जो आपने पहले किया था ~और इसके विपरीत। ~ऑपरेटर एक एकल ऑपरेटरों और दाएं से बाएं से interpereted है ~~Xकी तरह है ~(~X)की तरह नहीं (~~)Xहै (जो एक सिंटैक्स त्रुटि हो जाएगा)
yunzen

20

ECMAScript 6 में, समतुल्य ~~है 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

पॉलीफ़िल:

function trunc(x) {
    return x < 0 ? Math.ceil(x) : Math.floor(x);
}

6
कुछ आश्चर्य की बात है कि, ~~ Math.trunc, jsperf.com/math-trunc-vs-double-bitwise-not-operator से अधिक तेज़ है । हालांकि, सब कुछ गति के बारे में नहीं है; पठनीयता भी।
गजस

3
~~ और Math.trunc के बीच एक महत्वपूर्ण अंतर है: यदि आप एक स्ट्रिंग पास करते हैं, या NaN या जो भी चीज एक संख्या नहीं है, तो Math.trunc NaN वापस कर देगा, और ~~ उन मामलों में, हमेशा एक नंबर लौटाएगा, यह 0. लौटेंगे
बुज़िनास

Jsperf.com/math-trunc-vs-double-bitwise-not-operator के अनुसार, Math.trunc Chrome 59+ में ~~ से थोड़ा तेज है ।
जैक स्टीम

12

~ऐसा करने के लिए लगता है -(N+1)। इसलिए ~2 == -(2 + 1) == -3यदि आप इसे फिर से -3 पर करते हैं तो यह इसे वापस कर देता है: ~-3 == -(-3 + 1) == 2यह शायद एक स्ट्रिंग को एक दौर में लगभग एक संख्या में बदल देता है।

इस धागे को देखें: http://www.sitepoint.com/forums/showthread.php?t=663275

इसके अलावा, अधिक विस्तृत जानकारी यहाँ उपलब्ध है: http://dreaminginjavascript.wordpress.com/2008/07/04/28/


लिंक Drackir के लिए धन्यवाद!
शेन टोमेलिनसन


3

बस एक चेतावनी है। यहाँ अन्य उत्तर मुझे कुछ परेशानी में डाल गए।

फ़्लोटिंग पॉइंट संख्या के दशमलव बिंदु के बाद कुछ भी निकालने का इरादा है, लेकिन इसमें कुछ कोने वाले मामले हैं जो इसे एक बग खतरा बनाते हैं। मैं ~~ से बचने की सलाह दूंगा।

सबसे पहले, ~~ बहुत बड़ी संख्या पर काम नहीं करता है।

~~1000000000000 == -727279968

एक विकल्प के रूप में, उपयोग Math.trunc()(जैसा कि गजस ने उल्लेख किया है, Math.trunc()एक अस्थायी बिंदु संख्या के पूर्णांक भाग को वापस करता है लेकिन केवल ECMAScript 6 अनुरूप जावास्क्रिप्ट में उपलब्ध है)। आप हमेशा ऐसा करके Math.trunc()गैर- ECMAScript-6 वातावरण के लिए अपना खुद का बना सकते हैं :

if(!Math.trunc){
    Math.trunc = function(value){
        return Math.sign(value) * Math.floor(Math.abs(value));
    }
}

मैंने संदर्भ के लिए इस पर एक ब्लॉग पोस्ट लिखा: http://bitlords.blogspot.com/2016/08/the-double-tilde-x-technique-in.html


1

यह इस बात का एक उदाहरण है कि कैसे इस ऑपरेटर को कुशलता से उपयोग किया जा सकता है, जहां इसका उपयोग करने के लिए समझ में आता है:

leftOffset = -(~~$('html').css('padding-left').replace('px', '') + ~~$('body').css('margin-left').replace('px', '')),

स्रोत:

अंकों के साथ बातचीत करते हुए अनुभाग देखें


1

संख्याओं को परिवर्तित करना

console.log(~~-1);    // -1
console.log(~~0);     // 0
console.log(~~1);     // 1
console.log(~~"-1");  // -1
console.log(~~"0");   // 0
console.log(~~"1");   // 1
console.log(~~true);  // 1
console.log(~~false); // 0

~ -1 0 है

if (~someStr.indexOf("a")) {
  // Found it
} else  {
  // Not Found
}

स्रोत


1

टिल्डे (~) का एक अल्गोरिह्म है - (N + 1)

परीक्षा के लिए:

~0 = -(0+1) = -1
~5 = -(5+1) = -6
~-7 = -(-7+1) = 6

डबल टिल्ड है - (- (N + 1) +1)

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

~~5 = -(-(5+1)+1) = 5
~~-3 = -(-(-3+1)+1) = -3

ट्रिपल टिल्ड है - (- (- ((N + 1) +1) +1)

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

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