2014-09-20 6 views
5

क्या कोई यह बता सकता है कि यह फ़ंक्शन क्या करता है?यह गणित गोल करने का कार्य कैसे काम करता है?

static inline void round_to_zero(volatile float *f) 
{ 
    *f += 1e-18; 
    *f -= 1e-18; 
} 

मेरा मतलब है 1e-18 जोड़ने और इसे फिर से घटाकर, मैं समझता हूं। लेकिन मुझे समझ में नहीं आता कि इसके पास एक फ्लोट पर क्या प्रभाव होगा। कारण यह समझने की कोशिश कर रहा हूं कि मैं कुछ कोड में युगल का उपयोग कर रहा हूं जो इस फ़ंक्शन का उपयोग करता है (जिसे मैंने फ़्लोट से परिवर्तित किया है)। इसकी ऑडियो कोड, और इसके बाद के संस्करण समारोह इस पुस्तकालय से आता है:

https://github.com/swh/lv2/blob/master/include/ladspa-util.h

मैं अगर यह एक डबल पर काम करेंगे के रूप में है, या अतिरिक्त परिशुद्धता एक डबल है के लिए संशोधित करने की आवश्यकता सोच रहा हूँ। मुझे संदेह है कि यह डेटा के आखिरी कुछ बिट्स को बंद कर देता है, अगर वे वहां हैं तो फ्लोट से उन्हें मिटा दें, हालांकि मुझे समझ में नहीं आता कि कैसे। लेकिन मुझे कल्पना है कि अगर ऐसा होता है, तो मुझे एक्सपोनेंट को डबल के अनुरूप बदलने की आवश्यकता होगी।

TIA, पीट

+0

ऐसा लगता है कि यह बहुत ही अनुकूलित कोड है जो कोड को संभालने वाले अनुमानित प्रकार के डेटा (http://en.wikipedia.org/wiki/Denormal_number) के साथ denormal संख्याओं के आईईईई 754 हैंडलिंग पर निर्भर करता है। इसके अलावा मैं इसका एहसास नहीं कर सकता। – caskey

+0

@caskey 'float' denormal संख्याएं उससे छोटी हैं। – ouah

उत्तर

1

निम्नलिखित कोड को दर्शाता है कि समारोह क्या करता है।

int main(void) 
{ 
    float a; 

    a = -1.0; 
    a /= 1e100; 
    printf("%f\n", a); 

    round_to_zero(&a); 
    printf("%f\n", a); 
} 

बात आप जानना चाहते हैं कि आईईईई-754 चल बिन्दु संख्या 0 के लिए दो संभावित मान है। positive 0 और negative 0 है। round_to_zero कार्य करने के लिए सकारात्मक 0.

नकारात्मक 0 धर्मान्तरित मूल्य 1e-18 लगभग डबल परिशुद्धता संख्या 1.0 के लिए 1 lsb है। तो मुझे नहीं लगता कि double (निश्चित रूप से तर्क प्रकार बदलने के अलावा) के साथ उस फ़ंक्शन का उपयोग करने के लिए कोई भी संशोधन आवश्यक है।

+0

धन्यवाद - क्या आप यह समझा सकते हैं कि यह कैसे करता है? 1e-18 जोड़ने और इसका घटाना क्यों इस प्रभाव में है, मैं सोच रहा हूं कि संख्याओं की पूरी श्रृंखला पर इसका क्या प्रभाव हो सकता है। यदि मान 1e-18 एक डबल के लिए 1 एलएसबी है, तो यह एक फ्लोट के लिए बहुत कम होना चाहिए, जिसे कोड के लिए डिज़ाइन किया गया था, इसलिए मुझे आश्चर्य है कि फ़ंक्शन पर डबल की तुलना में फ्लोट पर अलग प्रभाव पड़ता है? चूंकि मैं इसे वास्तव में समझ नहीं पा रहा हूं (हालांकि मैं साइन को हटाने की आवश्यकता को समझता हूं), मुझे सूक्ष्म मतभेदों पर संदेह है जो युगल का उपयोग करके कोड बना सकता है अलग-अलग (ज्ञात नहीं)। – Pete

+0

@Pete - विचार यह है कि यदि आप नकारात्मक 0 से शुरू करते हैं, तो 1e-18 जोड़ना आपको एक छोटा सकारात्मक नंबर देता है, और 1e-18 घटाना आपको सकारात्मक 0 देता है। यदि आप किसी अन्य नंबर से शुरू करते हैं, जोड़ते और घटाते हैं 1e-18 का नंबर पर कोई शुद्ध प्रभाव नहीं है। ऐसा लगता है कि वैसे भी सिद्धांत है। – user3386109

1

सोचा कि मुझे निम्नलिखित विवरण जोड़ने के लिए इस पर वापस आना चाहिए।

जबकि ऋणात्मक शून्य से सकारात्मक में परिवर्तित करने का जिक्र सही है और मेरे लिए उपयोगी था, उससे इसके लिए और अधिक है।

1e-18 जोड़ना और फिर इसे एक फ्लोट से घटाकर वास्तव में फ्लोट से बहुत कम संख्याओं को मिटा दें। इसका उपयोग ऑडियो अनुप्रयोगों में किया जाता है क्योंकि फ़िल्टर छोटे फ्लोट्स को उन कार्यों के माध्यम से पुन: गणना कर सकते हैं जो लगातार फ्लोट को विभाजित करते हैं, जिसके परिणामस्वरूप कभी भी छोटी संख्या होती है। एक बार जब संख्या denormalised (Caskey के रूप में वर्णित) हो जाता है, तो कई cpus (x86 शामिल) में उस संख्या के लिए प्रसंस्करण गति 100x धीमी हो जाती है।

उस डेटा प्रकार के लिए असामान्य आकार संख्या से अधिक बड़ी संख्या जोड़कर, आप प्रकार में संग्रहीत छोटे मान को मिटा दें। एक ही बड़े मूल्य के परिणाम को शून्य रखने वाले प्रकार में घटाना, जो संसाधित होने पर प्रसंस्करण गति को प्रभावित नहीं करता है। छोटे मूल्य को मिटाए जाने का कारण यह है कि प्रकार में सिग्निफिशैंड सटीक बहुत छोटा मूल्य रखने के लिए पर्याप्त नहीं है, और आपके द्वारा अभी जोड़ा गया बड़ा मूल्य है।

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

1.0f के एक मूल्य के साथ एक ऑडियो नमूने के साथ प्रारंभ।

इसे एक समारोह के माध्यम से 40 बार विभाजित करें जो 10 से विभाजित होता है, जिसके परिणामस्वरूप 1e-40 का मान होता है।

v = 0.0100000 ई -38 (फ्लोट प्रकार में लगभग 8 दशमलव सटीक हैं, और 38 तक का एक्सपोनेंट है, इसलिए स्मृति में दिखता है जैसा कि मैंने इसे यहां लिखा है)।

यह अब एक फ्लोट प्रकार के लिए एक असामान्य मूल्य है, और एक सीपीयू इसे धीरे-धीरे संसाधित करने का कारण बनता है। धीमी गति से कैसे छुटकारा पाएं? इसे शून्य बनाओ। तो:

1e-18 जोड़ें; नतीजा: 1.00000000 ई -18 (ध्यान दें कि मूल 1e-40 8 अंकों के महत्व में प्रतिनिधित्व करने के लिए बहुत छोटा है और यदि यह पहले से ही बहुत बड़ा 1e-18 मान रखता है)।

तब घटाना 1e-18 मूल्य: ०.०००००००० ई-0

इसलिए हम शून्य उत्पादन, मूल denormal मूल्य को मिटाने, और हमारे cpu हमें धन्यवाद।

संबंधित मुद्दे