NaN मुक्केबाजी का उद्देश्य क्या है?


44

21 वीं सदी सी पढ़ना मैं खंड 6 में "NaNs के साथ अंकन असाधारण संख्या" पर पहुंचा , जहां यह कुछ मनमाने ढंग से बिट पैटर्न को संग्रहीत करने के लिए मंटिसा में बिट्स के उपयोग की व्याख्या करता है, उन्हें मार्कर या बिंदुओं के रूप में उपयोग करने के लिए (पुस्तक में उल्लेख किया गया है) कि WebKit इस तकनीक का उपयोग करता है)।

मुझे वास्तव में यकीन नहीं है कि मैं इस तकनीक की उपयोगिता को समझ पाया हूं, कि मैं एक हैक के रूप में देखता हूं (यह एक एनएएन में मंटिसा के मूल्य पर ध्यान नहीं देने वाले हार्डवेयर पर निर्भर करता है) लेकिन एक जावा पृष्ठभूमि से आने के लिए मुझे उपयोग नहीं किया जाता है C का खुरदरापन।

यहां कोड का स्निपेट है जो एक NaN में एक मार्कर सेट और पढ़ता है

#include <stdio.h>
#include <math.h> //isnan

double ref;

double set_na(){
    if (!ref) {
        ref=0/0.;
        char *cr = (char *)(&ref);
        cr[2]='a';
    }
    return ref;
}

int is_na(double in){
    if (!ref) return 0;  //set_na was never called==>no NAs yet.

    char *cc = (char *)(&in);
    char *cr = (char *)(&ref);
    for (int i=0; i< sizeof(double); i++)
        if (cc[i] != cr[i]) return 0;
    return 1;
}

int main(){
    double x = set_na();
    double y = x;
    printf("Is x=set_na() NA? %i\n", is_na(x));
    printf("Is x=set_na() NAN? %i\n", isnan(x));
    printf("Is y=x NA? %i\n", is_na(y));
    printf("Is 0/0 NA? %i\n", is_na(0/0.));
    printf("Is 8 NA? %i\n", is_na(8));
}

यह प्रिंट करता है:

Is x=set_na() NA? 1
Is x=set_na() NAN? 1
Is y=x NA? 1
Is 0/0 NA? 0
Is 8 NA? 0

और JSValue.h वेबकिट पर एन्कोडिंग की व्याख्या करता है, लेकिन इसका उपयोग क्यों नहीं किया जाता है।

इस तकनीक का उद्देश्य क्या है? क्या अंतरिक्ष / प्रदर्शन के लाभ इसकी हैकिश प्रकृति को संतुलित करने के लिए पर्याप्त हैं?


क्या आप एक सरल उदाहरण प्रदान कर सकते हैं?
B21овиЈ

स्पष्ट होना ओपी पूछ रहा है कि सिग्नलिंग NaN का उपयोग कहां किया जा सकता है
शाफ़्ट फ्रीक

1
@ratchetfreak, आपको क्या लगता है?
विंस्टन एवर्ट

@ratchetfreak: सवाल NaN को संकेत देने के बारे में नहीं है, जैसा कि webkit JSValue.h बताते हैं, लेकिन मुझे कुछ नया खोज करने देने के लिए धन्यवाद!
औरजक्र

1
@ हडसन आइसन () मुख्य में दूसरे प्रिंटफ में इस्तेमाल किया गया सी। Is_an () का उद्देश्य यह परीक्षण करना है कि इनपुट में डबल का बिट पैटर्न वैश्विक वैरिएबल के अंदर सहेजे गए के बराबर है या नहीं।
औरजक्र

जवाबों:


63

जब आप एक गतिशील रूप से टाइप की गई भाषा को लागू कर रहे हैं, तो आपके पास एक एकल प्रकार है जो आपके किसी भी ऑब्जेक्ट को पकड़ सकता है। इसके लिए मैं तीन अलग-अलग दृष्टिकोणों से अवगत हूँ:

सबसे पहले, आप पॉइंटर्स के आसपास से गुजर सकते हैं। यह वही है जो सीपीथॉन कार्यान्वयन करता है। प्रत्येक वस्तु एक PyObjectसूचक है। ये संकेत चारों ओर से गुज़रते हैं और संचालन का पता लगाने के लिए PyObject संरचना में विवरण देखकर किया जाता है।

नुकसान यह है कि छोटे मूल्य जैसे संख्याएं बॉक्सिंग मूल्यों के रूप में संग्रहीत होती हैं, इसलिए आपके छोटे 5 कहीं स्मृति के ब्लॉक के रूप में संग्रहीत होते हैं। तो यह हमें संघ के दृष्टिकोण की ओर ले जाता है, जिसका उपयोग लुआ द्वारा किया जाता है। इसके बजाय PyObject*, प्रत्येक मान एक संरचना है जो प्रकार को निर्दिष्ट करने के लिए एक क्षेत्र है, और फिर सभी विभिन्न समर्थित प्रकारों का एक संघ है। इस तरह हम किसी भी स्मृति को छोटे मूल्यों के लिए आवंटित करने से बचते हैं, बजाय उन्हें सीधे संघ में संग्रहीत किए।

NaNयुगल के रूप में दृष्टिकोण दुकानों सब कुछ है, और के अप्रयुक्त भाग पुनः उपयोग कर लेता NaNअतिरिक्त भंडारण के लिए। संघ पद्धति पर लाभ यह है कि हम प्रकार क्षेत्र को बचाते हैं। यदि यह एक वैध डबल है, तो यह एक डबल है अन्यथा मंटिसा वास्तविक वस्तु का एक संकेतक है।

याद रखें, यह हर जावास्क्रिप्ट वस्तु है। हर चर, हर वस्तु में एक मूल्य, हर अभिव्यक्ति। अगर हम उन सभी को 96 बिट्स से 64 बिट्स तक कम कर सकते हैं जो कि बहुत प्रभावशाली है।

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


2
दरअसल सीपीथॉन छोटी संख्या को कैश करता है। देखें hg.python.org/cpython/file/e6cc582cafce/Objects/longobject.c
फिलिप बादल

1
@cpcloud, सच है, लेकिन यह विस्तार प्रासंगिक नहीं लगता।
विंस्टन इर्वर्ट

1
आप सही हैं। मैंने जो लिखा था उसे पढ़ने के बाद मैंने वही सोचा।
फिलिप बादल

2
सभी मूल्यों को "मुक्केबाजी" से बचाने के लिए एक आदिम प्रकार के बिट्स का उपयोग करना एक समय-सम्मानित तकनीक है। स्मॉलटाकल ने 1970 के दशक में इसका इस्तेमाल किया, 16-बिट पूर्णांक से एक बिट को ऑब्जेक्ट पॉइंटर या 15-बिट संकेत करने के लिए चोरी किया SmallInteger
जोनाथन यूनिस

2
@JonathanEunice, वास्तव में? यह मुझे आश्चर्यचकित करता है क्योंकि 16 बिट्स में वास्तव में लंबी रेंज नहीं है जो मैं थोड़ा सा देने को तैयार हूं।
विंस्टन इवर्ट

7

"असाधारण मूल्यों" के लिए NaN का उपयोग करना एक अतिरिक्त बूलियन चर की आवश्यकता से बचने के लिए एक प्रसिद्ध और कभी-कभी सहायक तकनीक है this_value_is_invalid। बुद्धिमानी से उपयोग किया जाता है, यह किसी भी प्रदर्शन व्यापार-नापसंद के बिना अपने कोड को अधिक संक्षिप्त, क्लीनर, सरल, बेहतर पठनीय बनाने में मदद कर सकता है।

इस तकनीक के कुछ नुकसान हैं, बेशक (यहाँ देखें http://ppkwok.blogspot.co.uk/2012/11/java-cafe-1-never-write-nan-nan_24.html ), लेकिन जावा जैसी भाषाओं में ( या बहुत समान C #) मानक लाइब्रेरी फ़ंक्शंस हैं, Float.isNaNजो NaNs को सरल बनाने के लिए काम करते हैं। बेशक, जावा में आप वैकल्पिक रूप से Floatऔर Doubleवर्ग और सी # में उपयोग कर सकते हैं अशक्त मूल्य प्रकार float?और double?, आपको nullअमान्य फ़्लोटिंग पॉइंट नंबरों के लिए NaN के बजाय उपयोग करने की संभावना है , लेकिन उन तकनीकों का प्रदर्शन और स्मृति पर महत्वपूर्ण नकारात्मक प्रभाव पड़ सकता है आपके कार्यक्रम का उपयोग।

C में NaN का उपयोग 100% पोर्टेबल नहीं है, यह सच है, लेकिन आप इसे हर जगह उपयोग कर सकते हैं जहाँ IEEE 754 फ़्लोटिंग पॉइंट मानक उपलब्ध है। AFAIK आज लगभग हर मुख्यधारा के हार्डवेयर है (या कम से कम अधिकांश कंपाइलर का रनटाइम वातावरण इसका समर्थन करता है)। उदाहरण के लिए, इस SO पोस्ट में C में NaN के उपयोग के बारे में अधिक विवरण जानने के लिए कुछ जानकारी है।


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

मैंने प्रश्न को लिंक करने के लिए संपादित किया है जहां वेबकिट NaN- बॉक्सिंग का उपयोग करता है। ऐसा लगता है कि वेबकिट का NaN का व्यापक उपयोग है, सिग्नल 'NaN' के अलावा अन्य
andijcr

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