parseInt (शून्य, 24) === 23 ... रुको, क्या?


226

ठीक है, इसलिए मैं parseInt के साथ खिलवाड़ कर रहा था यह देखने के लिए कि यह कैसे मूल्यों को अभी तक आरंभीकृत नहीं करता है और मैं इस मणि पर ठोकर खाई हूं। नीचे किसी भी मूलांक 24 या इसके बाद के संस्करण होते हैं।

parseInt(null, 24) === 23 // evaluates to true

मैंने इसे IE, क्रोम और फ़ायरफ़ॉक्स में परीक्षण किया और वे सभी सच हैं, इसलिए मैं सोच रहा हूं कि यह विनिर्देश में कहीं होना चाहिए। एक त्वरित Google खोज ने मुझे कोई परिणाम नहीं दिया इसलिए मैं यहां हूं, किसी को समझा सकता हूं।

मुझे याद है कि एक क्रॉकफोर्ड का भाषण सुनने के बाद वह कह रहा था कि typeof null === "object"ऑब्जेक्ट और नल की वजह से उसकी स्मृति में समान प्रकार के पहचानकर्ता या उन रेखाओं के साथ कुछ है, लेकिन मुझे अब वह वीडियो नहीं मिल रहा है।

इसे आज़माएं: http://jsfiddle.net/robert/txjwP/

सुधार संपादित करें : एक उच्च मूलांक अलग परिणाम देता है, 32 रिटर्न 785077
संपादित 2 zzzzBov से:[24...30]:23, 31:714695, 32:785077, 33:859935, 34:939407, 35:1023631, 36:1112745


tl; डॉ

समझाएं कि parseInt(null, 24) === 23एक सही कथन क्यों है।


49
कितना विचित्र। जावास्क्रिप्ट हमेशा आपको अपने पैर की उंगलियों पर रखता है।
— FishBasketGordo

1
डेटा बिंदु: alert(parseInt(null, 34) === 23)उत्पादितfalse
— स्टीफन पी

1
alert(parseInt(null,26)===23);सच भी पैदा करता है?!?!
— पेटर इवानोव

6
[24...30]:23, 31:714695, 32:785077, 33:859935, 34:939407, 35:1023631, 36:1112745,[37...]:NaN
— zzzzBov

1
एक अतिरिक्त नोट के undefinedरूप में, पहले पैरामीटर के रूप में 30
— zzzzBov

जवाबों:


240

यह nullस्ट्रिंग में परिवर्तित हो "null"रहा है और इसे परिवर्तित करने की कोशिश कर रहा है। 23 के माध्यम से मूलांक 0 के लिए, ऐसे कोई अंक नहीं हैं जो इसे रूपांतरित कर सकते हैं, इसलिए यह वापस आ जाता है NaN। 24 में "n", 14 वें अक्षर को अंक प्रणाली में जोड़ा जाता है। 31 पर, "u"21 वें अक्षर को जोड़ा जाता है और पूरे स्ट्रिंग को डिकोड किया जा सकता है। 37 पर अब कोई वैध अंक सेट नहीं है जो उत्पन्न किया जा सकता है और NaN लौटाया जाता है।

js> parseInt(null, 36)
1112745

>>> reduce(lambda x, y: x * 36 + y, [(string.digits + string.lowercase).index(x) for x in 'null'])
1112745

3
@Tomalak: कौन कहता है कि यह उपयोग कर रहा है toString()?
— इग्नासियो वाज़क्वेज़-अब्राम्स

3
@Ignacio। दरअसल, मैं गलत था। मुझे एहसास नहीं था कि 37 एक मूलांक की बात कर रहा था। उसके लिए माफ़ करना।
— माइक सैमुअल

3
@ रॉबर्ट, नहीं, मैं उलझन में था और उसने सोचा कि वह जो दावा कर रहा था, उसके अलावा कुछ और दावा कर रहा था। यह सही उत्तर है। चारों तरफ क्षमायाचना।
— माइक सैमुअल

19
मुझे अभी भी लगता है कि यह उत्तर कुछ संदर्भों के साथ कर सकता है। हालांकि यह पूरी तरह से सही है, यह वास्तव में सिर्फ एक बड़ा जोर है ...
— लाइटनेस दौड़ ऑर्बिट

4
@Tomalak - सभी संदर्भों के लिए मेरे उत्तर की जाँच करें। यह उत्तर सही (और पहला) एक है इसलिए मुझे लगता है कि इसे स्वीकार किया जाना चाहिए। हालाँकि यह समझाने में कभी भी तकलीफ नहीं होती है कि हुड के नीचे क्या होता है?)
— डेविड टिटारेंको

118

मोज़िला हमें बताता है :

फ़ंक्शन parseInt अपने पहले तर्क को स्ट्रिंग में परिवर्तित करता है, इसे पार्स करता है, और एक पूर्णांक या NaN लौटाता है। यदि NaN नहीं है, तो लौटाया गया मान निर्दिष्ट मूलांक (आधार) में संख्या के रूप में लिए गए पहले तर्क का दशमलव पूर्णांक निरूपण होगा। उदाहरण के लिए, 10 का मूलांक एक दशमलव संख्या, 8 अष्टक, 16 हेक्साडेसिमल और इतने पर से बदलने के लिए इंगित करता है। 10 से ऊपर के मूलांक के लिए, वर्णमाला के अक्षर 9. से अधिक अंक दर्शाते हैं। उदाहरण के लिए, हेक्साडेसिमल संख्या (आधार 16), एफ के माध्यम से ए का उपयोग किया जाता है।

में कल्पना , 15.1.2.2/1 हमें बताता है कि स्ट्रिंग के लिए रूपांतरण का उपयोग किया जाता है में निर्मित ToStringहै, जो (के रूप में प्रति 9.8) की पैदावार "null"(साथ भ्रमित होने की नहीं toStringहै, जो लाभ होगा "[object Window]"!)।

तो, आइए विचार करें parseInt("null", 24)।

बेशक, यह संपूर्णता में आधार -24 संख्यात्मक स्ट्रिंग नहीं है, लेकिन "n" है: यह दशमलव 23 है ।

दशमलव 23 को बाहर निकालने के बाद अब पार्सिंग रुक जाती है, क्योंकि आधार -24 प्रणाली में "u" नहीं पाया जाता है:

यदि S में कोई ऐसा वर्ण है, जो मूलांक-R अंक नहीं है, तो Z को पहले ऐसे वर्ण से पहले सभी वर्णों से मिलकर S का विकल्प दें; अन्यथा, Z को S. हो [15.1.2.2/11]

(और यही कारण है कि parseInt(null, 23)(और निचला मूलक) आपको NaN23 के बजाय देता है : "n"आधार -23 प्रणाली में नहीं है।)


2
यह पार्सेइंट का बहुत ही दुखद व्यवहार है (मैं सोच रहा था कि इन मामलों में इसे अपवाद क्यों नहीं बनाया गया)। जब मैं कर सकता हूं तो इसके बजाय मैं NUMBER () का उपयोग करना पसंद करूंगा।
— बृजेश चौहान

79

इग्नासियो वाज़केज़-अब्राम्स सही है, लेकिन यह देखने देता है कि यह कैसे काम करता है ...

से 15.1.2.2 parseInt (string , radix):

जब parseInt फ़ंक्शन को बुलाया जाता है, तो निम्नलिखित कदम उठाए जाते हैं:

  • इनपुटस्ट्रीमिंग को ToString (स्ट्रिंग) होने दें।
  • बता दें कि S पहले इनपुटस्ट्रीमिंग का एक नया बनाया गया विकल्प है जिसमें पहले वर्ण से बना हुआ है जो कि स्ट्राइटहेसस्पेस और उस चरित्र का अनुसरण करने वाले सभी वर्ण नहीं है। (दूसरे शब्दों में, प्रमुख सफेद स्थान को हटा दें।)
  • संकेत 1 होने दो।
  • यदि S खाली नहीं है और S का पहला वर्ण माइनस साइन है -, साइन −1 होने दें।
  • यदि S खाली नहीं है और S का पहला वर्ण एक प्लस चिन्ह + या एक ऋण चिन्ह है -, तो S से पहले वर्ण को हटा दें।
  • आज्ञा देना = ToInt32 (मूलांक)।
  • स्ट्रिपरेपिक्स को सच होने दें।
  • यदि R, 0 है, तो a। यदि आर <2 या आर> 36 है, तो NaN लौटें। ख। यदि R। 16 है, तो पट्टीप्रिफ़िक्स को गलत होने दें।
  • एल्स, आर = 0 ए। आर = 10 दें।
  • यदि स्ट्रिपरेपिक्स सच है, तो ए। यदि S की लंबाई कम से कम 2 है और S के पहले दो अक्षर या तो "0x" या "0X" हैं, तो S से पहले दो अक्षर हटा दें और R = 16 होने दें।
  • यदि S में कोई ऐसा वर्ण है, जो मूलांक-R अंक नहीं है, तो Z को पहले ऐसे वर्ण से पहले सभी वर्णों से मिलकर S का विकल्प दें; अन्यथा, Z को S होने दें।
  • यदि Z खाली है, तो NaN लौटें।
  • बता दें कि मैथेमैटिकल गणितीय पूर्णांक मान है जो कि मूलांक-आर संकेतन में Z द्वारा दर्शाया गया है, जो AZ और az के लिए अंकों का उपयोग करता है, जिसमें मान 10 से 35 के माध्यम से होते हैं। (हालाँकि, यदि R 10 है और Z में 20 से अधिक महत्वपूर्ण अंक हैं, तो हर महत्वपूर्ण अंक 20 वीं के बाद अंकों को 0 अंक द्वारा लागू किया जा सकता है, कार्यान्वयन के विकल्प पर; और यदि R 2, 4, 8, 10, 16 या 32 नहीं है, तो mathInt गणितीय पूर्णांक के लिए कार्यान्वयन-निर्भर सन्निकटन हो सकता है मान जो कि मूलांक-आर संकेतन में Z द्वारा दर्शाया गया है।)
  • गणित के लिए संख्या मान होने दें।
  • वापसी साइन × नंबर।

नोट parseInt केवल एक पूर्णांक मान के रूप में स्ट्रिंग के एक प्रमुख हिस्से की व्याख्या कर सकता है; यह किसी भी वर्ण को अनदेखा करता है जिसे किसी पूर्णांक के अंकन के भाग के रूप में व्याख्यायित नहीं किया जा सकता है, और ऐसा कोई संकेत नहीं दिया गया है कि ऐसे किसी वर्ण की उपेक्षा की गई थी।

यहाँ दो महत्वपूर्ण भाग हैं। मैंने दोनों को बोल्ड किया। इसलिए सबसे पहले, हमें यह पता लगाना होगा कि toStringप्रतिनिधित्व क्या nullहै। हमें Table 13 — ToString Conversionsउस जानकारी के लिए खंड 9.8.0 को देखना होगा :

यहां छवि विवरण दर्ज करें

महान, इसलिए अब हम जानते हैं कि toString(null)आंतरिक रूप से करने से एक 'null'स्ट्रिंग पैदा होती है । महान, लेकिन यह वास्तव में कैसे अंक (वर्ण) को संभालता है जो प्रदान किए गए मूलांक के भीतर मान्य नहीं हैं?

हम ऊपर 15.1.2.2देखते हैं और हम निम्नलिखित टिप्पणी देखते हैं:

यदि S में कोई ऐसा वर्ण है, जो मूलांक-R अंक नहीं है, तो Z को पहले ऐसे वर्ण से पहले सभी वर्णों से मिलकर S का विकल्प दें; अन्यथा, Z को S होने दें।

इसका मतलब है कि हम सभी अंकों को निर्दिष्ट मूलांक तक संभालते हैं और बाकी सब चीजों को नजरअंदाज करते हैं।

मूल रूप से, ऐसा parseInt(null, 23)ही काम करना है parseInt('null', 23)। uका कारण बनता है दो l's ध्यान नहीं दिया जा करने के लिए (भले ही वे मूलांक 23 का हिस्सा हैं)। इसलिए, हम केवल केवल पार्स कर सकते हैं n, पूरे बयान को पर्यायवाची बना सकते हैं parseInt('n', 23)। :)

किसी भी तरह से, महान सवाल!


33
parseInt( null, 24 ) === 23

के बराबर है

parseInt( String(null), 24 ) === 23

जो के बराबर है

parseInt( "null", 24 ) === 23

आधार 24 के अंक 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, ..., n हैं।

भाषा युक्ति कहती है

  1. यदि S में कोई ऐसा वर्ण है, जो मूलांक-R अंक नहीं है, तो Z को पहले ऐसे वर्ण से पहले सभी वर्णों से मिलकर S का विकल्प दें; अन्यथा, Z को S होने दें।

वह हिस्सा है जो सुनिश्चित करता है कि सी-शैली पूर्णांक शाब्दिक 15Lरूप से पार्स की तरह ठीक है, इसलिए उपरोक्त इसके बराबर है

parseInt( "n", 24 ) === 23

"n" ऊपर दी गई अंकों की सूची का 23-rd अक्षर है।

QED


16

मुझे लगता nullहै कि एक स्ट्रिंग में परिवर्तित हो जाता है "null"। तो nवास्तव 23में 'बेस 24' ('बेस 25' में वही), u'बेस 24' में अमान्य है , इसलिए बाकी स्ट्रिंग nullको नजरअंदाज कर दिया जाएगा। कारण है कि यह आउटपुट यही की 23जब तक u'base31' में मान्य हो जाएगा।


7

parseInt अल्फ़ान्यूमेरिक प्रतिनिधित्व का उपयोग करता है, तो आधार -24 में "n" मान्य है, लेकिन "u" अमान्य वर्ण है, तो parseInt केवल "n" मान को पार्स करता है ...।

parseInt("n",24) -> 23

एक उदाहरण के रूप में, इसके साथ प्रयास करें:

alert(parseInt("3x", 24))

परिणाम "3" होगा।

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