मैं दृढ़ता और सुसंगतता के लिए निरंतर अभिव्यक्तियों के गणित कार्यों का उपयोग करता हूं (log(x)/0.3...
के बजाय log(x)/log(2)
)। चूंकि ये फ़ंक्शंस वास्तव में भाषा का हिस्सा नहीं हैं, न ही उन्हें math.h
(केवल घोषित) में परिभाषित किया गया है, क्या स्थिरांक संकलित समय पर सटीक हो जाएंगे, या क्या उन्हें रनटाइम पर कथित रूप से गणना की जाएगी?निरंतर अभिव्यक्तियों के गणित कार्यों को संकलित समय पर पूर्व-गणना की जाती है?
उत्तर
कुछ कंपाइलर्स संकलन समय पर उनका मूल्यांकन करेंगे, लेकिन इस व्यवहार की गारंटी नहीं है (और ऐसा करने से समस्याएं भी हो सकती हैं)। आपको अपने कंपाइलर को जांचना होगा और देखें कि यह क्या करता है।
ध्यान दें कि कई प्रणालियों पर log(2)
<math.h>
में मैक्रो M_LN2
से उपलब्ध है।
यदि संकलक जानता है कि लॉग का कोई दुष्प्रभाव नहीं है और हमेशा एक ही मान देता है (उदाहरण के लिए, एक 'शुद्ध' फ़ंक्शन है), तो यह संकलन समय पर उनका मूल्यांकन कर सकता है। चूंकि उपयोगकर्ता के पास गणित लाइब्रेरी से फ़ंक्शंस को बदलने का विकल्प होता है और लॉग को उस फ़ंक्शन के साथ प्रतिस्थापित करना चुन सकता है जो प्रत्येक बार लॉग (2) के लिए समान मान वापस नहीं करता है या उसके दुष्प्रभाव होते हैं, तो संकलक मूल्यांकन नहीं कर सकता यह संकलन समय पर। –
परिणाम सही होने पर मैं इस व्यवहार को सख्त मोड में दो अलग-अलग कंपाइलर्स (जीसीसी, आईसीसी) पर प्राप्त करने में सक्षम हूं (उदाहरण के लिए 'पाउ (2.0, 2.0) ') और इसलिए कॉल (सिद्धांत में) साइड-इफेक्ट मुक्त है इस धारणा के तहत कि उपयोगकर्ता ने अपना खुद का दिनचर्या नहीं बदला है। जबकि मैं आपके विश्लेषण से सहमत हूं कि संकलक शायद ऐसा नहीं कर रहे हैं, वे वैसे भी ऐसा करने के लिए पूरी तरह तैयार हैं = /। यह मुझे आश्चर्य नहीं करेगा अगर कुछ कंपाइलर झंडे प्रभावित होने पर भी ऐसा करते हैं, क्योंकि कंपाइलर लेखकों के पास आमतौर पर फ़्लोटिंग पॉइंट स्टेटस का एक बहुत ही मंद दृश्य होता है। –
इसकी अनुमति है क्योंकि किसी भी मानक फ़ंक्शंस को प्रतिस्थापित करने का प्रयास करने वाले प्रोग्राम अब सी प्रोग्राम का पालन नहीं कर रहे हैं। – caf
वे आम तौर पर रनटाइम पर गणना करेंगे (उन्हें इनलाइन करने के तरीके के लिए अन्य उत्तरों देखें), हालांकि मैं तब तक "कचरा" शब्द का उपयोग नहीं करता जब तक कि उनमें से बहुत से नहीं थे और/या कोड को बहुत से निष्पादित किया गया था कई बार
बल्कि सिर्फ निरंतर मूल्य में डाल से, एक #define
या const
चर कि व्यक्त करता है क्या है कि बजाय मूल्य का अर्थ है (PI
, LOG_2
, आदि) और उपयोग पैदा करते हैं।
उदाहरण के लिए:
#define LOG_2 0.30102999566
यह किसी भी गणना नहीं करता है और आप क्या कभी सटीक आप की इच्छा या अपने पर्यावरण (32 बिट वी 64 बिट) दिए गए प्रबंधित कर सकते हैं करने के लिए मान निर्दिष्ट कर सकते हैं।
सावधान! यदि आप LOG_2 (लॉग (2)) '' निर्धारित करते हैं, तो ''LOG_2' का उपयोग करते समय' लॉग() 'कॉल करता है। एक 'कॉन्स' ग्लोबल वैरिएबल एक * बहुत * बेहतर विचार है। –
@ माइक - मैं आपको यह सुझाव नहीं दे रहा था कि आप ऐसा करते हैं लेकिन # LOG_2 0.30102999' (या आप कितने डीपी चाहते हैं) – ChrisF
आप गलत तरीके से दावा कर रहे हैं कि कम से कम जीसीसी के साथ उन्हें संकलन समय पर गणना की जाती है । – fortran
यह रनटाइम पर होता है क्योंकि फ़ंक्शन के लिए कोड केवल लिंकिंग चरण के दौरान उपलब्ध होता है (जो संकलन चरण के बाद होता है)।
चरण को अनुकूलित करने के लिए, वैश्विक वैरिएबल का उपयोग करें जिसका उपयोग आप इसे करने से पहले शुरू करते हैं।
सिवाय इसके कि यदि यह एक मानक मानक हेडर में घोषित मानक फ़ंक्शन है, तो कार्यान्वयन इसके बारे में जानता है। –
आप गलत हैं: यह जानता है कि फ़ंक्शन * मौजूद है * लेकिन इसका मतलब यह नहीं है कि मानक शीर्षलेख फ़ाइलों में घोषित कार्यों को कोई विशेष उपचार मिलता है। कंपाइलर के दृष्टिकोण से, वे किसी अन्य शीर्ष फ़ाइल से किसी भी अन्य फ़ंक्शन की तरह हैं। साथ ही, संकलक लिंक नहीं कर सकता है इसलिए किसी भी फ़ंक्शन को लोड करने और निष्पादित करने का कोई तरीका नहीं है, मानक या नहीं। –
यह निर्भर करता है। यदि संकलक गणित को ठीक से कर सकता है क्योंकि यह रनटाइम पर किया जाएगा, और यदि लिंक समय अनुकूलन किया जाता है, और यदि पुस्तकालय किसी प्रकार के मध्यवर्ती रूप में रखा जाता है, तो हाँ यह किया जा सकता है।
अधिकांश कंपाइलर ऐसा नहीं करते हैं।
लाइब्रेरी फ़ंक्शंस के मामले में, कुछ कंपाइलर इन कार्यों को इंट्रिनिक्स के रूप में कार्यान्वित कर सकते हैं, जिसका अर्थ है कि संकलक कॉल को प्रतिस्थापित करने के लिए कॉल को प्रतिस्थापित करने के कार्यों के बारे में पर्याप्त जानता है। चाहे वह ऐसा करेगा, संकलक पर निर्भर करता है। व्यावहारिक रूप से, मैं अक्सर ध्यान देता हूं कि कुछ कंपाइलर संकलन समय पर फ़्लोटिंग-पॉइंट एक्सप्रेशन की पूर्व-गणना करने के लिए अनिच्छुक हैं, भले ही उनमें कोई फ़ंक्शन कॉल शामिल न हो।
सामान्य स्थिति में, आम तौर पर संकलन समय पर गणना नहीं की जाएगी और गणना नहीं की जा सकती है, यह मानते हुए कि संकलक बस इन कार्यों के बारे में पर्याप्त नहीं जानता है ताकि संकलन समय पर उनकी गणना कर सकें। हो सकता है कि उनके पास कुछ प्रमुख रन-टाइम दुष्प्रभाव हों?
कुछ कंपाइलरों में गैर-मानक कंपाइलर-निर्भर एक्सटेंशन हो सकते हैं जो उपयोगकर्ता को कंपाइलर के कार्यों के बारे में अतिरिक्त जानकारी प्रदान करने की अनुमति देते हैं, ताकि संकलक फ़ंक्शन कॉल को बेहतर तरीके से अनुकूलित कर सके और यह भी पता लगाए कि किसी दिए गए कॉल को प्रतिस्थापित किया जा सकता है या नहीं एक संकलन समय पूर्व गणना के साथ। उदाहरण के लिए, जीसीसी कंपाइलर attributes (जीसीसी-विशिष्ट एक्सटेंशन) const
और pure
जैसे फ़ंक्शन का समर्थन करता है।यदि तर्क संकलन समय पर ज्ञात हैं, तो const
विशेषता के साथ कार्य करने के लिए कॉल को सैद्धांतिक रूप से संकलित-समय पूर्व-गणना के साथ प्रतिस्थापित किया जा सकता है। हालांकि मैं यह नहीं कह सकता कि जीसीसी वास्तव में ऐसा कर सकता है या नहीं।
सी ++ में (भले ही आपका प्रश्न टैग किया गया हो) भाषा एक योजनाबद्ध नई सुविधा constexpr
घोषणा विनिर्देशक है जो एक समान उद्देश्य प्रदान करता है और आपके द्वारा वर्णित प्रभाव का अनुमान लगाया जाता है।
यह कंपाइलर और अनुकूलन झंडे पर निर्भर करता है।
$ cat constant_call_opt.c
#include <math.h>
float foo() {
return log(2);
}
$ gcc -c constant_call_opt.c -S
$ cat constant_call_opt.s
.file "constant_call_opt.c"
.text
.globl foo
.type foo, @function
foo:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl $0x3f317218, %eax
movl %eax, -4(%ebp)
flds -4(%ebp)
leave
ret
.size foo, .-foo
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
नहीं: @AndrewyT बताते हैं, जीसीसी निर्दिष्ट करने के लिए जो कार्य करता है लगातार और विशेषताओं के माध्यम से शुद्ध कर रहे हैं, और इस मामले जवाब सकारात्मक है, यह परिणाम इनलाइन जाएगा, जैसा कि आप आसानी से देख सकते क्षमता है फ़ंक्शन कॉल, बस एक स्थिर लोड करता है (0x3f317218 == 0.69314718246459961 == log(2)
)
एल्थॉट मेरे पास अब कोशिश करने के लिए कोई अन्य कंपाइलर नहीं है, मुझे लगता है कि आप सभी प्रमुख सी कंपाइलरों में वही व्यवहार की उम्मीद कर सकते हैं, क्योंकि यह एक छोटा सा अनुकूलन है ।
यदि आप अपने सिर में 0x3f317218 जैसे 32-बिट आईईईई फ़्लोटिंग पॉइंट एन्कोडिंग को तत्काल डीकोड नहीं कर सकते हैं, तो 'लॉग (1.0)' को संकलित करने का प्रयास करें, जिसके परिणामस्वरूप 'movl $ 0x0,% eax' में अच्छा आसान स्थिर' $ 0x0' होता है। लाइन। –
- 1. गणितीय कार्यों की गणना करने का समय चल रहा है
- 2. जीएनयू जीसीसी गणित कार्यों की शुद्धता आवश्यकता?
- 3. निरंतर अभिव्यक्तियों में numeric_limits :: max() का उपयोग
- 4. गणित कार्यों को हल करें पीएल/एसक्यूएल
- 5. एक पाठ रूप में गणित अभिव्यक्तियों को संरक्षित करना
- 6. फ़ोरैच इंटरफ़ेस प्रकारों पर समय-समय पर जांच को संकलित क्यों करता है?
- 7. शून्य निरंतर संकलित समय त्रुटि द्वारा जावा जावा को विभाजित क्यों नहीं किया जाता है?
- 8. डेल्फी में समय गणित
- 9. गणित - बिटशफ्ट राइट (या बाएं) को कैसे संकलित करें?
- 10. समय कार्यों
- 11. नियमित अभिव्यक्तियों की सीमाएं?
- 12. बाइंडिंग की समय जांच संकलित करें?
- 13. हास्केल: क्या मुझे नियमित अभिव्यक्तियों को संकलित करना चाहिए?
- 14. जहां स्थिर आवंटित करते समय स्मृति आवंटित की जाती है?
- 15. अभिव्यक्तियों की गणना मॉड्यूलो एन
- 16. गणित में किंवदंतियों की साजिश
- 17. संकलन समय निरंतर
- 18. डेल्फी 6 - कई बार संकलित करते समय बग गायब हो जाती है
- 19. जीसीसी: गणित पुस्तकालय को जोड़ने के लिए -एलएम ध्वज की आवश्यकता क्यों है?
- 20. ओएस स्तर पर नींद कैसे लागू की जाती है?
- 21. संकलित समय पेड़ संरचना
- 22. एक सरणी तर्क एक फ़ंक्शन को निरंतर सूचक नहीं है?
- 23. गणित
- 24. सीयूडीए मेमोरी कैसे प्रबंधित की जाती है?
- 25. घाटे की गणना कैसे की जाती है?
- 26. अभिव्यक्तियों को केवल पाइपलाइन
- 27. रैखिक समय और निरंतर स्थान
- 28. सी ++ संकलन-समय निरंतर पहचान
- 29. प्रारूप गणित आउटपुट परिणाम की एक सूची
- 30. क्या कोई हुक है जब अज्ञात कक्षाएं निरंतर असाइन की जाती हैं?
मुझे उम्मीद है कि वे सटीक हो जाएंगे, लेकिन अगर आपने कहा कि आप किस कंपाइलर का उपयोग कर रहे थे तो इससे मदद मिलेगी ताकि लोग वास्तव में जांच सकें। – Hazior
लॉग (एक्स), ज़ाहिर है, संकलन समय पर निरंतर अभिव्यक्ति नहीं है, जब तक कि x को पहले स्थिर नहीं किया गया हो और मान दिया जाए। शायद कोड लिखना बहुत मुश्किल नहीं है, जो किसी भी कंपाइलर का मूल्यांकन नहीं करेगा, भले ही मानव के लिए ऐसा करना आसान हो। –
जब से मैं इसमें भाग गया, यह लंबे समय से रहा है, लेकिन ऐसे कार्यान्वयन हुए हैं जो फ्लोटिंग-पॉइंट गणनाओं के कुछ विवरण रनटाइम पर निर्दिष्ट किए जाने की अनुमति देते हैं। उस स्थिति में, इसके आधार पर कुछ भी संकलन समय पर गणना नहीं की जा सकती है। –