मैं फ़ंक्शन ऑप्टिमाइज़ेशन रूटीन (नेल्डर-मीड एल्गोरिदम का एक संस्करण) पर काम कर रहा हूं जो बहुत विशिष्ट स्थितियों में अभिसरण करने में विफल रहता है।इस सिंगल-परिशुद्धता ऑपरेशन का परिणाम कैसे गोल किया गया है? [या यह बिट 1 और 0 क्यों नहीं है?]
मैं पता चला है कि एक float
चर, चलो यह a
कॉल, a
और अन्य चर का b
कि एक सा ही से यह से अलग है के बीच मतलब सौंपा जा रहा है।
दरअसल, प्रत्येक चरों के मान इस प्रकार हैं:
float a = 25.9735966f; // 41CFC9ED
float b = 25.9735947f; // 41CFC9EC
और अब मैं a
को a
और b
के बीच मतलब आवंटित करने के लिए कोशिश कर रहा हूँ:
a = 0.5 * (a+b);
जब मैं लिखने एक परीक्षण कार्यक्रम में यह कोड, मुझे परिणाम मिलना है, अर्थात् 25.9735947
। लेकिन मेरे मूल पुस्तकालय कोड के डीबगर में मैं देखता हूं कि 25.9735966
अवशेषों का मान है। मुझे यकीन है कि मेरे पास दोनों कार्यक्रमों पर एक ही कंपाइलर झंडे हैं। क्या कोई कारण है कि यह सिंगल-परिशुद्धता गणना अलग-अलग परिणाम क्यों देगी?
अद्यतन
रूप @PascalCuoq का अनुरोध किया, यहाँ मैं क्या सोचता प्रश्न में लाइन के लिए विधानसभा है। रेखा कुछ अन्य चीजें कर रही है हालांकि मुझे यकीन नहीं है कि गुणा कहाँ होता है।
.loc 1 53 0 discriminator 2
movl -60(%rbp), %eax
cltq
salq $3, %rax
addq -88(%rbp), %rax
movq (%rax), %rax
movl -44(%rbp), %edx
movslq %edx, %rdx
salq $2, %rdx
leaq (%rax,%rdx), %rcx
movl -44(%rbp), %eax
cltq
salq $2, %rax
addq -72(%rbp), %rax
movl -60(%rbp), %edx
movslq %edx, %rdx
salq $3, %rdx
addq -88(%rbp), %rdx
movq (%rdx), %rdx
movl -44(%rbp), %esi
movslq %esi, %rsi
salq $2, %rsi
addq %rsi, %rdx
movss (%rdx), %xmm1
movl -52(%rbp), %edx
movslq %edx, %rdx
salq $3, %rdx
addq -88(%rbp), %rdx
movq (%rdx), %rdx
movl -44(%rbp), %esi
movslq %esi, %rsi
salq $2, %rsi
addq %rsi, %rdx
movss (%rdx), %xmm0
addss %xmm1, %xmm0
movss .LC6(%rip), %xmm1
mulss %xmm1, %xmm0
movss %xmm0, (%rax)
movl (%rax), %eax
movl %eax, (%rcx)
स्पष्टीकरण
मेरे कोड न्यूमेरिकल व्यंजनों से Nelder-मीड कोड का एक
ripoff
संस्करण है। p[i][j] == 25.9735966f
और p[ilo][j] == 25.9735947f
p[i][j]=psum[j]=0.5*(p[i][j]+p[ilo][j]);
इस पंक्ति में,: हमलावर लाइन इस एक है। p[i][j]
में परिणामस्वरूप मान 25.9735966f
है।
मेरे पास अभी तक कोई स्पष्टीकरण नहीं है, लेकिन 25।9735 9 47 निकटतम ** यहां तक कि ** परिणाम के लिए सही गोल है, क्योंकि मुझे लगता है कि आपको मुझे बताने की आवश्यकता नहीं है। –
मूल लाइब्रेरी कोड से 'ए = 0.5 * (ए + बी);' के लिए असेंबली देखने का कोई मौका? उसमें कोई अन्य लाइब्रेरी लिंक नहीं हो सकती है जो राउंडिंग मोड को "मददगार" सेट कर सकती है? –
जब आप "डीबगर में" कहते हैं, तो क्या आपका मतलब है कि जब आप डीबगर का उपयोग करके मानों का निरीक्षण करते हैं, या क्या आपका मतलब है कि इस लाइब्रेरी के डीबगर संस्करण का उपयोग करते समय, अन्यथा सामान्य रूप से चलने पर, अलग-अलग परिणाम उत्पन्न होते हैं? –