जावा / सी ++ में कोई पावर ऑपरेटर क्यों नहीं है?


23

जबकि ऐसे ऑपरेटर हैं - **पायथन में, मैं सोच रहा था कि जावा और सी ++ में एक भी क्यों नहीं है।

ऑपरेटर ओवरलोडिंग के साथ आप C ++ में परिभाषित की जाने वाली कक्षाओं के लिए एक बनाना आसान है (और मेरा मानना ​​है कि ऐसी चीज जावा में भी संभव है), लेकिन जब आदिम प्रकार जैसे कि इंट, डबल और इतने पर बात करते हैं, तो आपको लाइब्रेरी का उपयोग करना होगा जैसे कार्य Math.power(और आमतौर पर दोनों को दोगुना करना होता है)।

तो - आदिम प्रकारों के लिए ऐसे ऑपरेटर को परिभाषित क्यों नहीं किया जाता है?


8
C ++ में, हम अपने ऑपरेटर नहीं बना सकते। आप केवल मौजूदा ऑपरेटरों को ओवरलोड कर सकते हैं।

1
@ महेश, इसलिए मैं एक शक्ति होने के लिए अपना खुद का नंबर वर्ग और अधिभार ^ ऑपरेटर बना सकता हूं। यह वास्तव में नहीं है।

22
@ रैनझीलर: इससे कोई फर्क नहीं पड़ता क्योंकि ^ऑपरेटर की पूर्ववर्तीता घातांक की पूर्ववर्तीता से मेल नहीं खाती है। अभिव्यक्ति पर विचार करें a + b ^ c। गणित में, घातांक पहले किया जाता है ( b ^ c), फिर परिणामी शक्ति को जोड़ा जाता है a। C ++ में, इसके अलावा पहले प्रदर्शन किया जाता है ( a + bफिर) ^ऑपरेटर के साथ प्रदर्शन किया जाता है c। इसलिए भले ही आपने ^ऑपरेटर को घातांक का अर्थ लगाने के लिए लागू किया हो , पूर्ववर्तीता सभी को आश्चर्यचकित कर देगी।
सिलिको

2
@RamZilber - ^C ++ में XOR है। यह सलाह दी जाती है कि अधिभार ऑपरेटर को कोई अलग नहीं करना चाहिए जो एक आदिम डेटा प्रकार का उपयोग करता है।

4
@ रैनझीलर: क्योंकि यह उन सभी ऑपरेटरों में से किसी का उपयोग करने के लिए सहज ज्ञान युक्त नहीं है, जिनका अर्थ आप प्रतिपादक हैं। मैं गंभीरता से किसी भी सी ++ प्रोग्रामर की क्षमता पर सवाल उठाऊंगा जो ++ऑपरेटर या !ऑपरेटर एट को ओवरलोड करता है । अल। मतलब प्रतिपादक। लेकिन आप वैसे भी नहीं कर सकते, क्योंकि आप जिन ऑपरेटरों के बारे में बात करते हैं, वे केवल एक तर्क को स्वीकार करते हैं; प्रतिपादक को दो तर्कों की आवश्यकता होती है।
सिलिको

जवाबों:


32

सामान्यतया, C में (और विस्तार C ++ द्वारा) आदिम संचालकों को सरल हार्डवेयर द्वारा मोटे तौर पर एकल निर्देश में कार्यान्वित किया जाता है। प्रतिपादक की तरह कुछ को अक्सर सॉफ़्टवेयर समर्थन की आवश्यकता होती है; इसलिए यह डिफ़ॉल्ट रूप से नहीं है।

इसके अलावा, यह भाषा के मानक पुस्तकालय द्वारा प्रदान की जाती है std::pow

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


4
जबकि मैं इस सबसे सहमत हूं, यह तथ्य कि मापांक ऑपरेटर का उपयोग फ्लोटिंग पॉइंट प्रकारों पर नहीं किया जा सकता है, आदिम डेटा प्रकारों के लिए असंगत है, लेकिन वह भी शायद किसी भी हार्डवेयर पर एक भी निर्देश नहीं होगा जिसकी मैं कल्पना करता हूं कि अब कोई भी तरीका प्रचलित है।

@ सायन: कम से कम x86 पर, मापांक एक एकल निर्देश है। ( DIVदोनों विभाजन और मापांक करता है) आप मुझे निरंतरता के बिंदु पर मिल गए हैं।
बिली ओनेल

@ बिली ओनली: एक निर्देश में फ्लोटिंग पॉइंट मॉडुलस? मैं अपने स्वयं के बारे में जानने के लिए असेंबली में देर तक नहीं घूमता। यदि ऐसा है, तो मापांक ऑपरेटर को फ्लोटिंग पॉइंट प्रकारों पर लागू किया जाना चाहिए।

3
@ डोनल फेलो: फोरट्रान के पास प्रतिपादक ऑपरेटर बहुत पहले से था, जो कि कुछ भी हो सकता था।
सुपरकैट

1
@ डोनल फेलो: एक बिजली ऑपरेटर पूर्णांक के साथ उतने उपयोगी नहीं होते हैं, लेकिन छोटी शक्तियों (विशेष रूप से स्क्वरिंग) के लिए निश्चित रूप से इसके उपयोग हो सकते हैं। व्यक्तिगत रूप से मुझे पत्रों के बाहर ऑपरेटरों को बनाने का दृष्टिकोण पसंद है (जैसा कि पास्कल के साथ divया फोरट्रान के साथ होता है .EQ.); भाषा के व्हाट्सएप नियमों के आधार पर, बिना आवश्यकता के ऑपरेटरों की मनमानी संख्या रखना संभव हो सकता है, क्योंकि वे आरक्षित शब्द हैं।
सुपरकैट

41

यह सवाल C ++: Stroustrup, "Design and Evolution of C ++" के लिए जवाबदेह है, इस पर चर्चा 11.6.1, पीपी। 247-250 में की गई है।

एक नए ऑपरेटर को जोड़ने के लिए सामान्य आपत्तियां थीं। यह पहले से ही ओवरक्लेम्प्ड पूर्वता तालिका में जोड़ देगा। कार्य समूह के सदस्यों ने सोचा कि यह एक समारोह होने पर केवल मामूली सुविधा देगा, और वे कभी-कभी अपने स्वयं के कार्यों को प्रतिस्थापित करने में सक्षम होना चाहते थे।

एक ऑपरेटर के लिए कोई अच्छा उम्मीदवार नहीं था। ^विशेष-या, और है ^^के बीच के रिश्ते के कारण आमंत्रित भ्रम &और |और &&और ||!अनुपयोगी था क्योंकि !=एक मौजूदा मूल्य के घातांक के लिए लिखने की स्वाभाविक प्रवृत्ति होगी , और यह पहले से ही लिया गया था। सबसे अच्छा उपलब्ध हो सकता है *^, जो वास्तव में कोई भी वास्तव में पसंद नहीं करता है।

Stroustrup माना **फिर से, लेकिन यह पहले से ही सी में एक अर्थ है: a**pहै aगुणा लौटा pकरने के लिए अंक, और char ** c;वाणी cको सूचक के सूचक के रूप char**एक टोकन के अर्थ के रूप में "पॉइंटर को पॉइंटर की घोषणा" के रूप में पेश करते हुए, "अगली चीज क्या इंगित करती है" (यदि यह पॉइंटर है) या "एक्सप्रेशिएशन" (यदि एक नंबर द्वारा पीछा किया गया है) पूर्ववर्ती समस्याओं का कारण बनता है। a/b**pजैसे a/(b**p)कि पी एक नंबर था, वैसे ही पार्स करना होगा , लेकिन (a/b) * *pअगर पी एक पॉइंटर था, तो इसे पार्सर में हल करना होगा।

दूसरे शब्दों में, यह संभव होगा, लेकिन इससे पूर्वता तालिका और पार्सर जटिल हो जाएगा, और दोनों पहले से ही बहुत जटिल हैं।

मुझे जावा के बारे में कहानी नहीं पता; मैं कर सकता था सब अटकलें हैं। सी के लिए, जहां यह शुरू हुआ, सभी सी ऑपरेटरों को असेंबली कोड में आसानी से अनुवादित किया जाता है, आंशिक रूप से संकलक को सरल बनाने के लिए और आंशिक रूप से सरल ऑपरेटरों में समय लेने वाली कार्यक्षमता को छिपाने से बचने के लिए (तथ्य यह है कि operator+()और अन्य लोग बड़ी जटिलता और प्रदर्शन हिट छिपा सकते हैं) C ++ के बारे में शुरुआती शिकायतों में से)।


2
अच्छा जवाब। मुझे लगता है कि जावा ने इस संबंध में सी को सरल बनाने की कोशिश की, इसलिए कोई भी नया ऑपरेटर नहीं जोड़ना चाहता था। यह अफ़सोस की बात है कि किसी ने मुझसे नहीं पूछा, मुझे निश्चित रूप से पसंद आया होगा *^। : D
maaartinus

1
C को पाठ स्वरूपण करने के लिए बनाया गया था। फोर्ट्रान को गणित करने के लिए बनाया गया था और 20 साल पहले जटिल, शक्ति और मैट्रिक्स गणित था।
मार्टिन बेकेट

@ मर्टिन बेकेट: क्या आप इस बात का सबूत पा सकते हैं कि सी पाठ प्रारूपण के लिए बनाया गया था? यह मेरे लिए एक बहुत ही भद्दी भाषा है, और मैंने सी की उत्पत्ति के बारे में जो पढ़ा है, वह कहता है कि इसे मुख्य रूप से रीक्स के लिए सिस्टम प्रोग्रामिंग के लिए डिज़ाइन किया गया था।
डेविड थॉर्नले ने

@DavidThornley - यह यूनिक्स में लिखने के लिए डिज़ाइन किया गया था, लेकिन सभी शुरुआती यूनिक्स का उपयोग पाठ स्वरूपण के लिए किया गया लगता है, और इसके लिए यह एक व्यापक स्ट्रिंग और i / o लाइब्रेरी है।
मार्टिन बेकेट

6
+1: मौजूदा अर्थ a**pहत्यारा है। (हैक्स उस समस्या के आसपास काम करने के लिए… Brr!)
डोनल फेलो

13

मुझे संदेह है क्योंकि आपके द्वारा प्रस्तुत प्रत्येक ऑपरेटर भाषा की जटिलता को बढ़ाता है। इसलिए प्रवेश के लिए अवरोध बहुत अधिक है। मैं अपने आप को बहुत, बहुत मुश्किल से घातांक का उपयोग कर पाता हूं - और ऐसा करने के लिए एक विधि कॉल का उपयोग करने से अधिक खुश हूं।



3
मैं उपयोग करता हूँ x**2और x**3शायद ही कभी। और एक मैजिक पॉव कार्यान्वयन जिसे कंपाइलर जानता है और सरल मामलों के लिए अनुकूलन करता है वह अच्छा होगा।
कोडइन्कॉउंस

2
@CodeInChaos: हालांकि x * xऔर x * x * xवर्ग और घन के लिए खराब विकल्प नहीं हैं।
डेविड थॉर्नले

5
@David आप बस नहीं लिख सकते हैं x*xअगर x एक अभिव्यक्ति है। सबसे अच्छा मामले में कोड अस्पष्ट हो जाता है, और सबसे धीमी या गलत भी। तो आपको अपने स्वयं के स्क्वायर और क्यूब कार्यों को परिभाषित करने की आवश्यकता होगी। और फिर भी पावर ऑपरेटर के रूप में ** का उपयोग करने की तुलना में कोड बदसूरत होगा।
कोडइन्चौस

1
@ डेविड मुझे कोष्ठक डालने की आवश्यकता है, लेकिन अभिव्यक्ति को कई बार दोहराने की आवश्यकता नहीं है और स्रोत-कोड को ब्लॉट करता है। जिससे पठनीयता बहुत कम हो जाती है। और सामान्य उपसंचाई उन्मूलन केवल तभी संभव है जब संकलक अभिव्यक्ति को साइड इफेक्ट से मुक्त होने की गारंटी दे सकता है। और कम से कम .net घबराना उस संबंध में बहुत स्मार्ट नहीं है।
कोडइन्चौस

11

जावा भाषा और कोर लाइब्रेरी डिजाइनरों ने गणित के अधिकांश कार्यों को गणित वर्ग के लिए फिर से शुरू करने का फैसला किया । मठ देखें । ()

क्यूं कर? बिट-फॉर-बिट परिशुद्धता पर प्रदर्शन को प्राथमिकता देने का लचीलापन। यह कहने के लिए भाषा के बाकी हिस्सों के खिलाफ जाना होगा कि अंतर्निहित गणित ऑपरेटरों का व्यवहार एक मंच से दूसरे चरण में भिन्न हो सकता है, जबकि गणित वर्ग विशेष रूप से बताता है कि व्यवहार संभावित रूप से प्रदर्शन के लिए सटीक बलिदान करता है, इसलिए खरीदार सावधान रहें:

क्लास स्ट्रिक्टमैथ के कुछ संख्यात्मक तरीकों के विपरीत , क्लास मैथ के समकक्ष कार्यों के सभी कार्यान्वयन बिट-फॉर-बिट समान परिणाम वापस करने के लिए परिभाषित नहीं किए गए हैं। यह छूट बेहतर प्रदर्शन करने वाले क्रियान्वयन की अनुमति देती है, जहां सख्त प्रतिलिपि प्रस्तुत करने की आवश्यकता नहीं है।


6

घातांक शुरुआत से ही फोरट्रान का हिस्सा था क्योंकि इसका उद्देश्य वैज्ञानिक प्रोग्रामिंग में वर्गाकार था। इंजीनियर और भौतिक विज्ञानी अक्सर सिमुलेशन में इसका उपयोग करते हैं, क्योंकि भौतिकी में बिजली कानून संबंध सामान्य हैं।

अजगर की वैज्ञानिक कंप्यूटिंग में भी मजबूत उपस्थिति है, उदाहरण के लिए (NumPy और SciPy)। यह, इसके प्रतिपादक ऑपरेटर के साथ, यह सुझाव देता है कि इसका उद्देश्य वैज्ञानिक प्रोग्रामिंग में भी था।

सिस्टम प्रोग्रामिंग में C, Java और C # की जड़ें हैं। शायद यह एक प्रभाव है जो समर्थित ऑपरेटरों के समूह के बाहर प्रतिपादक रखता है।

बस एक सिद्धांत।


4

C केवल ALU के साथ होने वाले सामान्य अंकगणितीय परिचालनों के लिए परिभाषित परिचालक। इसका मुख्य उद्देश्य विधानसभा कोड के लिए एक मानव पठनीय इंटरफ़ेस बनाना था।

C ++ ने कोई भी ऑपरेटर व्यवहार नहीं बदला क्योंकि, वह चाहता था कि C में लिखा गया सभी कोड आधार आज्ञाकारी हो।

जावा ने ऐसा ही किया क्योंकि यह मौजूदा C ++ प्रोग्रामर को डराना नहीं चाहता था।


जब सी बनाया गया था, तो गुणा और भाग में हार्डवेयर की कमी नहीं थी और इसे सॉफ्टवेयर में लागू किया जाना था। फिर भी C में गुणा और भाग संचालक हैं।
सिराइड

@ साइराइड: मेरी जानकारी के लिए, PDP-7 यूनिक्स को चलाने वाला पहला कंप्यूटर था, जिसमें EAE के माध्यम से हार्डवेयर गुणन और विभाजन था। कृपया देखें: bitavers.org/pdf/dec/pdp7/F-75_PDP-7userHbk_Jun65.pdf
तुगरुल एतेस

1

ठीक है क्योंकि हर ऑपरेटर जो एक शक्ति के लिए समझ में आता है वह पहले से ही उपयोग में है। ^ XOR है और ** एक पॉइंटर को पॉइंटर को परिभाषित करता है। इसलिए इसके बजाय उनके पास केवल एक फ़ंक्शन है जो समान कार्य करता है। (पाव की तरह ())


@ आरटीएस - क्या एक लैंग्वेज डेवलपर वास्तव में प्रभावकारिता से अधिक समझदारी की तलाश में है?

एक प्रोग्रामिंग भाषा का एक अच्छा डेवलपर दोनों को देखता है। मैं जावा के बारे में कुछ नहीं कह सकता। लेकिन c ++ में compile time पर pow () फंक्शन की गणना की जाती है। और नियमित ऑपरेटरों की तरह ही कुशल है।

@ आरटीएस: pow()फ़ंक्शन रनटाइम पर अपनी गणना करता है, जब तक कि आपको एक कंपाइलर नहीं मिला है pow(), जो इसके लिए निरंतर तह कर सकता है , जिसे मुझे संदेह है। (कुछ संकलक आपको गणना करने के लिए प्रोसेसर इंट्रिंसिक्स का उपयोग करने का विकल्प देते हैं, हालांकि।)
सिलिको में

@ सिलिको में मेरा मतलब यह नहीं था कि यह अंतिम मूल्य की गणना करता है, मेरा मतलब था कि कंपाइलर्स फ़ंक्शन कॉल को दूर कर देंगे, इसलिए आपके पास कच्चा समीकरण होगा।

2
@ जोसेफ: यकीन है कि यह एक अच्छा कारण है। एक एकल *एक शाब्दिक टोकन है, चाहे वह अप्रत्यक्ष या गुणन के लिए उपयोग किया जाए। एक **अर्थ घातांक या तो एक या दो शाब्दिक टोकन होगा, और आप वास्तव में नहीं चाहते कि आपके लेक्सर को टोकन तालिका को हिट करने के लिए होना चाहिए।
डेविड थॉर्नले

0

तथ्य यह है कि अंकगणित ऑपरेटर केवल कार्यों के शॉर्टकट हैं। (लगभग) आप उनके साथ जो कुछ भी करते हैं वह एक फ़ंक्शन के साथ किया जा सकता है। उदाहरण:

c = a + b;
// equals
c.set(a.add(b));
// or as free functions
set(c, add(a,b));

यह सिर्फ अधिक क्रिया है, इसलिए मैं 'शक्ति' प्रदर्शन करने के लिए कार्यों का उपयोग करने में कुछ भी गलत नहीं देखता हूं।


-1

जोड़ / घटाव / नकार और गुणा / भाग बुनियादी गणितीय संचालक हैं। यदि आप बिजली को एक ऑपरेटर बनाने के लिए थे, तो आप कहाँ रुकेंगे? स्क्वायर रूट ऑपरेटर? एन-रूट ऑपरेटर? लघुगणक संचालक?

मैं उनके रचनाकारों के लिए बात नहीं कर सकता, लेकिन मैं कह सकता हूं कि मुझे लगता है कि यह अविवेकी होगा और इस तरह के ऑपरेटरों को भाषा में नहीं होना चाहिए। कीबोर्ड पर शेष नॉन अल्फा-न्यूमेरिक / व्हाइट-स्पेस कैरेक्टर्स की संख्या सीमित है। जैसा कि है, यह अजीब है कि C ++ में एक मापांक ऑपरेटर है।


+1 - मैं यह नहीं देखता कि modएक ऑपरेटर के रूप में होना अजीब क्यों है। यह आमतौर पर एक निर्देश है। यह पूर्णांक पर एक प्राइमरी ऑपरेशन है। यह कंप्यूटर विज्ञान में हर जगह सबसे अधिक उपयोग किया जाता है। (बिना बंधे बफ़र्स जैसी चीजों को लागू करने से modबदबू आएगी)
बिली ओनली

@ बिली ओनली: पूर्णांक प्रकारों और फ्लोटिंग पॉइंट प्रकारों के साथ उपयोग करने में असंगतता के कारण अजीब। हालांकि पूरी तरह से उपयोगी है और मैं इसे हटाने का सपना नहीं देखूंगा। बस विचित्रता सब है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.