क्या जेएस इंजनों को एक NaN के बिट्स को बदलने की अनुमति है?


12

जावास्क्रिप्ट में, NaN मूल्य को आंतरिक रूप से 64-बिट युगल की एक विस्तृत श्रृंखला द्वारा दर्शाया जा सकता है। विशेष रूप से, निम्न बिटवाइज़ प्रतिनिधित्व के साथ कोई भी डबल:

x111 1111 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx

एक NaN के रूप में व्याख्या की है। मेरा प्रश्न है: मान लीजिए कि मैंने ArrayBuffers का उपयोग करते हुए JS संख्या में दो 32-बिट uints डाली, इसे पास किया, फिर इसे वापस दो 32-बिट uints में ढाला। क्या बरामद बिट्स मूल के समान होंगे, या जेएस इंजनों को एक NaN के बिट्स को बदलने की अनुमति होगी? दूसरे शब्दों में, क्या जेएस नंबरों का इस्तेमाल 64-बिट्स को नुकसानदेह तरीके से स्टोर करने के लिए किया जा सकता है?


2
दिलचस्प विचार
एवर्ट

1
एक परीक्षण मैंने किया। कम से कम Node.js की तरह लगता है बिट्स में परिवर्तन होता है, जिससे जानकारी का नुकसान होता है।
21

1
एक तरफ: ऐसा हर बिट पैटर्न एक NaN का प्रतिनिधित्व नहीं करता है। यदि पहले के बाद सभी एक्स बट्स शून्य हैं, तो यह एक अनन्तता का प्रतिनिधित्व करता है।
एरिक पोस्टपिसिल

जवाबों:


6

ECMA-262 9 वें संस्करण, जून 2018, (मानक जिसे जावास्क्रिप्ट के अनुरूप बनाने का इरादा है) 6.1.6 में "संख्या प्रकार" कहते हैं:

... 9007199254740990 (यानी, 2 53 -2) आईईईई मानक के "नॉट-ए-नंबर" मूल्यों को एक विशेष NaN मान के रूप में ECMAScript में दर्शाया गया है। कुछ कार्यान्वयन में, बाहरी कोड एक अंतर का पता लगाने में सक्षम हो सकता है। विभिन्न गैर-संख्या मानों के बीच, लेकिन ऐसा व्यवहार कार्यान्वयन-निर्भर है; ECMAScript कोड में, सभी NaN मान एक दूसरे से अप्रभेद्य हैं।

24.1.17 "NumberToRawBytes (प्रकार, मान, isLittleEndian)" कहते हैं:

... यदि मान NaN है, तो कच्चे माल को किसी भी कार्यान्वयन के लिए सेट किया जा सकता है जो IEEE 754-2008 बाइनरी 64 प्रारूप में नंबर-इनकोडिंग के लिए चुना गया हो। एक कार्यान्वयन को हमेशा प्रत्येक कार्यान्वयन के लिए एक ही एन्कोडिंग का चयन करना चाहिए जो कि अलग-अलग NaN मान के लिए हो।…

मुझे इस प्रश्न पर रोशनी डालने वाले NaN का कोई अन्य मार्ग नहीं दिखाई देता है। एक तरफ, 24.1.17 हमें प्रभावी रूप से बताता है कि NaN को कच्चे बाइट में परिवर्तित करते समय एक NaN के बिट्स को संरक्षित किया जाना चाहिए। हालाँकि, हमें यह बताने के लिए और कुछ नहीं है कि बिट्स को अन्य परिचालनों में संरक्षित किया जाना चाहिए। कोई यह अनुमान लगा सकता है कि यह इरादा है, क्योंकि 24.1.17 में यह आवश्यकता किसी भी उद्देश्य से काम करेगी यदि बिट्स को किसी अन्य ऑपरेशन द्वारा मनमाने ढंग से बदला जा सकता है। लेकिन मैं जावास्क्रिप्ट कार्यान्वयन पर भरोसा नहीं करेगा कि इस इरादे से इसे लागू किया है।


1

मैंने एक बार जावा के लिए एक प्रश्न पूछा था, NaN मूल्यों के हार्डवेयर-निर्भरता के बारे में, और यह देखा गया कि कुछ CPU चुपचाप एक "शांत NaN" (शांत NaN बिट की स्थापना) को "NaN मान" में परिवर्तित कर देंगे जब एक NaN मान लोड होता है एक प्रोसेसर रजिस्टर में। तो कम से कम एक बिट, शांत NaN बिट, आप मनमाना डेटा संग्रहीत करने के लिए उपयोग नहीं कर सकते।

अन्य बिट्स का उपयोग करना, जब तक कि शांत NaN बिट सेट न हो जाए, तब तक शायद सुरक्षित है। लेकिन अभी भी यहां पर कार्यान्वयन-निर्भरता के लिए जगह है, और इसलिए कोई गारंटी नहीं है।

इस तरह की समस्या यह है कि सामान्य भाषा संचालन कुछ भी करने से बचता है जो एक NaN के आंतरिक मूल्य पर निर्भर करता है, और सभी NaN को "सिर्फ NaN" के रूप में व्यवहार करना पसंद करते हैं।


0

मूल IEEE-754 मानक ने जानबूझकर कार्यान्वयन के लिए NaN के बिट्स को छोड़ दिया। इसने संकेत प्रदान किए, जैसे कि

आप मूल स्मृति पता रख सकते हैं जहां NaN बनाया गया था।

इस बीच, अंकगणित में एक NaN के साथ क्या करना है, इसके बारे में विशिष्ट नियम हैं, और नीचे में बिट्स के साथ कुछ भी नहीं करना है। मुझे नहीं लगता कि यह भी कहा जाता है कि दो NaN जोड़ते समय क्या करना है - बिट्स को उनमें से एक से रखें बनाम बिट्स का एक और सेट बनाएं। बस यह है कि परिणाम अभी भी एक NaN होना चाहिए।

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