पूर्णांक आधारित पावर फंक्शन pow (int, int) को लागू करने का सबसे प्रभावी तरीका


249

C में किसी अन्य पूर्णांक की शक्ति को पूर्णांक बढ़ाने के लिए सबसे कुशल तरीका क्या है?

// 2^3
pow(2,3) == 8

// 5^5
pow(5,5) == 3125

3
जब आप "दक्षता" कहते हैं, तो आपको किस के संबंध में कुशल निर्दिष्ट करने की आवश्यकता है। स्पीड? स्मृति उपयोग? कोड का आकार? रख-रखाव की?
एंडी लेस्टर

क्या C में पॉव () फंक्शन नहीं है?
जलफ

16
हां, लेकिन यह तैरने या डबल्स पर काम करता है, न कि चींटियों पर
नाथन फेलमैन

1
यदि आप वास्तविक intएस से चिपके हुए हैं (और कुछ विशाल-इंट क्लास नहीं), तो आईपीओ के लिए बहुत सारी कॉल ओवरफ्लो होंगी। यह मुझे आश्चर्यचकित करता है कि क्या किसी टेबल की पूर्व-गणना करने और एक साधारण टेबल लुकअप के लिए सभी गैर-अतिप्रवाह संयोजनों को कम करने का एक चतुर तरीका है। यह अधिकांश सामान्य उत्तरों की तुलना में अधिक मेमोरी लेगा, लेकिन शायद गति के मामले में अधिक कुशल होगा।
एड्रियन मैकार्थी

pow()एक सुरक्षित कार्य नहीं
EsmaeelE

जवाबों:


391

स्क्वेरिंग द्वारा प्रतिपादक।

int ipow(int base, int exp)
{
    int result = 1;
    for (;;)
    {
        if (exp & 1)
            result *= base;
        exp >>= 1;
        if (!exp)
            break;
        base *= base;
    }

    return result;
}

यह असममित क्रिप्टोग्राफी में बड़ी संख्या के लिए मॉड्यूलर घातांक करने के लिए मानक विधि है।


38
आपको संभवतः एक चेक जोड़ना चाहिए कि "ऍक्स्प" नकारात्मक नहीं है। वर्तमान में, यह फ़ंक्शन या तो गलत उत्तर देगा या हमेशा के लिए लूप देगा। (इस पर निर्भर करता है कि >> = किसी हस्ताक्षरित इंट पर जीरो-पेडिंग या साइन-एक्सटेंशन होता है - सी कंपाइलरों को या तो व्यवहार करने की अनुमति है)।
user9876

23
मैंने इसके बारे में अधिक अनुकूलित संस्करण लिखा है, यहां स्वतंत्र रूप से डाउनलोड किया जा सकता है: gist.github.com/3551590 मेरी मशीन पर यह लगभग 2.5x तेज था।
orlp

10
@ अखिलजैन: यह पूरी तरह से अच्छा है; जावा में, क्रमशः while (exp)और if (exp & 1)साथ while (exp != 0)और साथ ही इसे वैध बनाने के लिए if ((exp & 1) != 0)
इल्मरी करोनें

3
आपका कार्य संभवतः होना चाहिए unsigned exp, अन्यथा नकारात्मक रूप expसे ठीक से संभालना चाहिए ।
क्रेग मैकक्वीन

5
@ZinanXing गुणा गुणा n परिणाम अधिक गुणा और धीमा है। यह विधि उन्हें प्रभावी ढंग से पुन: उपयोग करके गुणन को बचाता है। उदाहरण के लिए, n ^ 8 का n*n*n*n*n*n*n*nउपयोग करने की भोली पद्धति 7 गुणाओं की गणना करती है। इसके बजाय यह एल्गोरिथ्म गणना करता है m=n*n, फिर o=m*m, p=o*oजहां p= n ^ 8, सिर्फ तीन गुणा के साथ। बड़े प्रदर्शनकारियों के साथ प्रदर्शन में अंतर महत्वपूर्ण है।
bames53

69

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

उदाहरण के लिए, यदि आप x ^ 15 की गणना करना चाहते हैं, तो स्क्वेरिंग द्वारा घातांक का तरीका आपको देगा:

x^15 = (x^7)*(x^7)*x 
x^7 = (x^3)*(x^3)*x 
x^3 = x*x*x

यह कुल 6 गुणा है।

यह पता चला है कि अतिरिक्त-श्रृंखला घातांक के माध्यम से "सिर्फ" 5 गुणा का उपयोग करके किया जा सकता है ।

n*n = n^2
n^2*n = n^3
n^3*n^3 = n^6
n^6*n^6 = n^12
n^12*n^3 = n^15

गुणन के इस इष्टतम अनुक्रम को खोजने के लिए कोई कुशल एल्गोरिदम नहीं हैं। से विकिपीडिया :

सबसे छोटी जोड़ श्रृंखला खोजने की समस्या को गतिशील प्रोग्रामिंग द्वारा हल नहीं किया जा सकता है, क्योंकि यह इष्टतम उपप्रकार की धारणा को संतुष्ट नहीं करता है। यही है, यह शक्ति को छोटी शक्तियों में विघटित करने के लिए पर्याप्त नहीं है, जिनमें से प्रत्येक को न्यूनतम रूप से गणना की जाती है, क्योंकि छोटी शक्तियों के लिए अतिरिक्त श्रृंखलाएं संबंधित हो सकती हैं (गणना साझा करने के लिए)। उदाहरण के लिए, ऊपर a, के लिए सबसे छोटी जोड़ श्रृंखला में, a के लिए उपप्रकार को (a) के रूप में गणना की जानी चाहिए क्योंकि a³ को फिर से उपयोग किया जाता है (जैसा कि, विरोध करें, a⁶ = a² (a²) ², जिसे तीन गुणकों की भी आवश्यकता होती है) )।


4
@JeremySalwen: जैसा कि इस उत्तर में कहा गया है, द्विआधारी घातांक सामान्य रूप से सबसे इष्टतम विधि नहीं है। वर्तमान में गुणकों का न्यूनतम अनुक्रम खोजने के लिए कोई कुशल एल्गोरिदम ज्ञात नहीं हैं।
एरिक पोस्टपिसिल

2
@ EricPostpischil, जो आपके आवेदन पर निर्भर करता है। आमतौर पर हमें सभी नंबरों के लिए काम करने के लिए एक सामान्य एल्गोरिथ्म की आवश्यकता नहीं होती है । कंप्यूटर प्रोग्रामिंग, वॉल्यूम की कला देखें। 2: सेमिन्युमेरिकल एल्गोरिदम
पेसियर

3
अलेक्जेंडर स्टेपानोव और डैनियल रोज द्वारा जेनेरिक प्रोग्रामिंग के लिए गणित से इस सटीक समस्या का एक अच्छा प्रदर्शनी है । यह पुस्तक हर सॉफ्टवेयर प्रैक्टिशनर, IMHO के शेल्फ पर होनी चाहिए।
टोबे स्पाइट

2
En.wikipedia.org/wiki/… भी देखें ।
lhf

यह पूर्णांकों के लिए अनुकूलित किया जा सकता है क्योंकि 255 पूर्णांक शक्तियों के तहत अच्छी तरह से हैं जो 32 बिट पूर्णांक के लिए अतिप्रवाह का कारण नहीं होगा। आप प्रत्येक इंट के लिए इष्टतम गुणन संरचना को कैश कर सकते हैं। मुझे लगता है कि कोड + डेटा अभी भी सभी शक्तियों को कैशिंग से छोटा होगा ...
योशिय्याह योडर

22

अगर आपको किसी शक्ति को 2 बढ़ाने की आवश्यकता है। ऐसा करने का सबसे तेज़ तरीका शक्ति द्वारा बिट शिफ्ट करना है।

2 ** 3 == 1 << 3 == 8
2 ** 30 == 1 << 30 == 1073741824 (A Gigabyte)

क्या ऐसा करने का एक सुंदर तरीका है ताकि 2 ** 0 == 1 हो?
21:39 पर रोब स्मॉलशायर

16
2 ** 0 == 1 << 0 == 1
जेक

14

यहाँ जावा में विधि है

private int ipow(int base, int exp)
{
    int result = 1;
    while (exp != 0)
    {
        if ((exp & 1) == 1)
            result *= base;
        exp >>= 1;
        base *= base;
    }

    return result;
}

बड़े संख्याओं के लिए काम नहीं करता है उदाहरण के लिए pow (71045970,41535484)
अनुश्री अचर्जी

16
@AnushreeAcharjee बिल्कुल नहीं। ऐसी संख्या की गणना करने के लिए मनमाने ढंग से सटीक अंकगणित की आवश्यकता होगी।
डेविड एटलर

बड़ी संख्या के लिए BigInteger # modPow या Biginteger # pow का उपयोग करें, तर्कों के आकार के आधार पर उपयुक्त एल्गोरिदम पहले से ही लागू हैं
Raman Yelianevich

यह एक जावा सवाल नहीं है!
काकाहुइते फ्रिटो

7
int pow( int base, int exponent)

{   // Does not work for negative exponents. (But that would be leaving the range of int) 
    if (exponent == 0) return 1;  // base case;
    int temp = pow(base, exponent/2);
    if (exponent % 2 == 0)
        return temp * temp; 
    else
        return (base * temp * temp);
}

मेरा वोट नहीं है, लेकिन pow(1, -1)एक नकारात्मक घातांक के बावजूद int की सीमा नहीं छोड़ता है। अब जब कोई दुर्घटना से काम करता है, जैसा कि करता है pow(-1, -1)
MSalters

एकमात्र नकारात्मक प्रतिपादक जो आपको इंट की सीमा को नहीं छोड़ सकता है -1 है। और यह केवल तभी काम करता है जब आधार 1 या -1 हो। इसलिए एक्स <0 के साथ केवल दो जोड़े (बेस, एक्सप) हैं जो गैर पूर्णांक शक्तियों के लिए नेतृत्व नहीं करेंगे। हालांकि मैं एक मेटमैटिकियन हूं और मुझे क्वांटिफायर पसंद हैं, मुझे लगता है कि इस मामले में, व्यवहार में, यह कहना ठीक है कि एक नकारात्मक घातांक आपको पूर्णांक छोड़ देता है ...
बार्टगोल

6

यदि आप किसी चीज़ की शक्ति के लिए पूर्णांक का मान प्राप्त करना चाहते हैं, तो शिफ्ट विकल्प का उपयोग करना हमेशा बेहतर होता है:

pow(2,5) द्वारा प्रतिस्थापित किया जा सकता है 1<<5

यह बहुत अधिक कुशल है।


6

power()समारोह केवल इंटेगर के लिए काम करने के लिए

int power(int base, unsigned int exp){

    if (exp == 0)
        return 1;
    int temp = power(base, exp/2);
    if (exp%2 == 0)
        return temp*temp;
    else
        return base*temp*temp;

}

जटिलता = ओ (लॉग (एक्सप))

power()नकारात्मक ऍक्स्प और फ्लोट बेस के लिए काम करने के लिए फ़ंक्शन ।

float power(float base, int exp) {

    if( exp == 0)
       return 1;
    float temp = power(base, exp/2);       
    if (exp%2 == 0)
        return temp*temp;
    else {
        if(exp > 0)
            return base*temp*temp;
        else
            return (temp*temp)/base; //negative exponent computation 
    }

} 

जटिलता = ओ (लॉग (एक्सप))


यह अभिजीत गायकवाड़ और चुक्स के उत्तरों से कैसे अलग है ? कृपया floatप्रस्तुत दूसरे कोड ब्लॉक का उपयोग करें (विचार करें कि कैसे power(2.0, -3)गणना की जाती है)।
ग्रेबर्ड

@greybeard मैंने कुछ टिप्पणी का उल्लेख किया है। हो सकता है कि यह आपकी
राय

1
GNU साइंटिफिक लाइब्रेरी में पहले से ही आपका दूसरा कार्य है: gnu.org/software/gsl/manual/html_node/Small-integer-powers.html
Cacahuete Frito

@roottraveller क्या आप negative exp and float baseसमाधान बता सकते हैं? हम अस्थायी का उपयोग क्यों करते हैं, 2 से अलग एक्सपी और चेक एक्सप (सम / विषम)? धन्यवाद!
लेव

6

एक अत्यंत विशिष्ट मामला है, जब आपको 2 ^ (- y से x) कहने की आवश्यकता होती है, जहां x, निश्चित रूप से नकारात्मक है और एक int पर स्थानांतरण करने के लिए y बहुत बड़ा है। आप फ्लोट के साथ पेंच करके स्थिर समय में 2 ^ x कर सकते हैं।

struct IeeeFloat
{

    unsigned int base : 23;
    unsigned int exponent : 8;
    unsigned int signBit : 1;
};


union IeeeFloatUnion
{
    IeeeFloat brokenOut;
    float f;
};

inline float twoToThe(char exponent)
{
    // notice how the range checking is already done on the exponent var 
    static IeeeFloatUnion u;
    u.f = 2.0;
    // Change the exponent part of the float
    u.brokenOut.exponent += (exponent - 1);
    return (u.f);
}

आधार प्रकार के रूप में डबल का उपयोग करके आप 2 की अधिक शक्तियां प्राप्त कर सकते हैं। (इस पोस्ट को दूर करने में मदद करने के लिए टिप्पणीकारों को बहुत धन्यवाद)।

यह भी संभावना है कि IEEE फ़्लोट के बारे में अधिक जानने के लिए , घातांक के अन्य विशेष मामले खुद को प्रस्तुत कर सकते हैं।


निफ्टी सॉल्यूशन, लेकिन अनसिगेंड ??
पैक्सडीब्लो

IEEE फ्लोट बेस x 2 ^ एक्सप है, घातांक मान को बदलने से दो की शक्ति से गुणा के अलावा और कुछ नहीं होगा, और संभावना अधिक है कि यह फ्लोट को अलग करेगा ... आपका समाधान गलत है IMHO
Drealmer

आप सभी सही हैं, मैंने गलत समझा कि मेरा समाधान मूल रूप से लिखा गया था, ओह, बहुत पहले, स्पष्ट रूप से 2 की शक्तियों के लिए। मैंने समस्या के विशेष मामले के समाधान के लिए अपने उत्तर को फिर से लिखा है।
डग टी।

सबसे पहले, कोड को उद्धृत किया गया है, और संकलन करने के लिए इसे संपादित करने की आवश्यकता है। दूसरे कोड को gcc का उपयोग करके एक core2d पर तोड़ा जाता है। इस डंप को देखें शायद मैंने कुछ गलत किया है। मैं फिर भी इस वसीयत काम नहीं लगता है, के बाद से आईईईई नाव प्रतिपादक आधार है 10
freespace

3
बेस 10? उह नहीं, यह बेस 2 है, जब तक कि आपका मतलब बाइनरी 10 में न हो :)
Drealmer

4

स्क्वेरिंग द्वारा घातांक की दक्षता पर टिप्पणियों के लिए बस के रूप में।

उस दृष्टिकोण का लाभ यह है कि यह लॉग (n) समय में चलता है। उदाहरण के लिए, यदि आप x ^ 1048575 (2 ^ 20 - 1) जैसे कुछ विशाल की गणना करने जा रहे हैं, तो आपको केवल 20 बार लूप में जाना होगा, न कि 1 लाख + भोले दृष्टिकोण का उपयोग करके।

इसके अलावा, कोड जटिलता के संदर्भ में, यह गुणकों के सबसे इष्टतम अनुक्रम को खोजने की कोशिश करने की तुलना में सरल है, एक ला प्रमोद का सुझाव।

संपादित करें:

मुझे लगता है कि मुझे अतिप्रवाह की संभावना के लिए किसी को टैग करने से पहले स्पष्ट करना चाहिए। यह दृष्टिकोण मानता है कि आपके पास किसी प्रकार का विशाल पुस्तकालय है।


2

पार्टी के लिए देर से:

नीचे एक समाधान है कि यह भी y < 0सबसे अच्छा के साथ सौदा कर सकते हैं।

  1. यह intmax_tअधिकतम सीमा के लिए परिणाम का उपयोग करता है । ऐसे उत्तरों के लिए कोई प्रावधान नहीं है जो अंदर फिट नहीं होते हैं intmax_t
  2. powjii(0, 0) --> 1जो इस मामले के लिए एक सामान्य परिणाम है
  3. pow(0,negative), एक अपरिभाषित परिणाम, रिटर्न INTMAX_MAX

    intmax_t powjii(int x, int y) {
      if (y < 0) {
        switch (x) {
          case 0:
            return INTMAX_MAX;
          case 1:
            return 1;
          case -1:
            return y % 2 ? -1 : 1;
        }
        return 0;
      }
      intmax_t z = 1;
      intmax_t base = x;
      for (;;) {
        if (y % 2) {
          z *= base;
        }
        y /= 2;
        if (y == 0) {
          break; 
        }
        base *= base;
      }
      return z;
    }

यह कोड अन्य लूप वाले समाधानों में for(;;)अंतिम base *= baseआम से बचने के लिए हमेशा के लिए लूप का उपयोग करता है । यह गुणन 1 है) की आवश्यकता नहीं है और 2) int*intअतिप्रवाह हो सकता है जो कि यूबी है।


powjii(INT_MAX, 63)में यूबी का कारण बनता है base *= base। यह जाँचने पर विचार करें कि आप गुणा कर सकते हैं, या बिना बताए स्थानांतरित कर सकते हैं और इसे चारों ओर से लपेट सकते हैं।
18 फरवरी को काकाएहेटे फ्रिटो

expहस्ताक्षर किए जाने का कोई कारण नहीं है । यह विषम स्थिति के कारण कोड को जटिल करता है जहां (-1) ** (-N)मान्य है, और कोई भी नकारात्मक मान के लिए abs(base) > 1होगा , इसलिए बेहतर होगा कि इसे अनसाइन किया जाए और उस कोड को सहेजा जाए। 0exp
काकाहुइते फ्रिटो

1
@CacahueteFrito यह सच है कि yहस्ताक्षरित वास्तव में आवश्यक नहीं है और आपके द्वारा टिप्पणी की गई जटिलताओं को सामने लाता है, फिर भी ओपी का अनुरोध विशिष्ट था pow(int, int)। इस प्रकार वे अच्छी टिप्पणियाँ ओपी के प्रश्न से संबंधित हैं। जैसा कि ओपी ने निर्दिष्ट नहीं किया है कि अतिप्रवाह पर क्या करना है, एक अच्छी तरह से परिभाषित गलत जवाब केवल यूबी की तुलना में मामूली बेहतर है। "सबसे कुशल तरीके" को देखते हुए, मुझे संदेह है कि ओपी ओएफ के बारे में परवाह करता है।
chux -

1

नकारात्मक घातीय पर विचार करते हुए अधिक सामान्य समाधान

private static int pow(int base, int exponent) {

    int result = 1;
    if (exponent == 0)
        return result; // base case;

    if (exponent < 0)
        return 1 / pow(base, -exponent);
    int temp = pow(base, exponent / 2);
    if (exponent % 2 == 0)
        return temp * temp;
    else
        return (base * temp * temp);
}

1
पूर्णांक विभाजन का परिणाम पूर्णांक में होता है, इसलिए आपका नकारात्मक घातांक बहुत अधिक कुशल हो सकता है क्योंकि यह केवल 0, 1, या -1 को
लौटाएगा

pow(i, INT_MIN)एक अनंत लूप हो सकता है।
चक्स - मोनिका

1
@chux: यह आपकी हार्डडिस्क को फॉर्मेट कर सकता है: पूर्णांक ओवरफ्लो यूबी है।
एमएसलेटर

@एमएसल्टर्स pow(i, INT_MIN)पूर्णांक अतिप्रवाह नहीं है। उस परिणाम का काम tempनिश्चित रूप से ओवरफ्लो हो सकता है, संभावित समय का अंत हो सकता है , लेकिन मैं एक प्रतीत होता है यादृच्छिक मूल्य के लिए व्यवस्थित करूंगा। :-)
chux -

0

एक और कार्यान्वयन (जावा में)। सबसे अधिक कुशल समाधान नहीं हो सकता है लेकिन # पुनरावृत्तियों का # घातीय समाधान के समान है।

public static long pow(long base, long exp){        
    if(exp ==0){
        return 1;
    }
    if(exp ==1){
        return base;
    }

    if(exp % 2 == 0){
        long half = pow(base, exp/2);
        return half * half;
    }else{
        long half = pow(base, (exp -1)/2);
        return base * half * half;
    }       
}

जावा सवाल नहीं!
काकाहुइते फ्रिटो

0

मैं पुनरावर्ती का उपयोग करता हूं, अगर एक्सप भी है, 5 ^ 10 = 25 ^ 5।

int pow(float base,float exp){
   if (exp==0)return 1;
   else if(exp>0&&exp%2==0){
      return pow(base*base,exp/2);
   }else if (exp>0&&exp%2!=0){
      return base*pow(base,exp-1);
   }
}

0

एलियास के जवाब के अलावा, जो हस्ताक्षरित पूर्णांक के साथ लागू होने पर अपरिभाषित व्यवहार का कारण बनता है, और अहस्ताक्षरित पूर्णांक के साथ लागू होने पर उच्च इनपुट के लिए गलत मान,

यहाँ स्क्वेरिंग द्वारा एक्सप्रेशन का एक संशोधित संस्करण है जो हस्ताक्षरित पूर्णांक प्रकारों के साथ भी काम करता है, और गलत मान नहीं देता है:

#include <stdint.h>

#define SQRT_INT64_MAX (INT64_C(0xB504F333))

int64_t alx_pow_s64 (int64_t base, uint8_t exp)
{
    int_fast64_t    base_;
    int_fast64_t    result;

    base_   = base;

    if (base_ == 1)
        return  1;
    if (!exp)
        return  1;
    if (!base_)
        return  0;

    result  = 1;
    if (exp & 1)
        result *= base_;
    exp >>= 1;
    while (exp) {
        if (base_ > SQRT_INT64_MAX)
            return  0;
        base_ *= base_;
        if (exp & 1)
            result *= base_;
        exp >>= 1;
    }

    return  result;
}

इस समारोह के लिए विचार:

(1 ** N) == 1
(N ** 0) == 1
(0 ** 0) == 1
(0 ** N) == 0

यदि कोई ओवरफ्लो या रैपिंग होने वाली है, return 0;

मैंने उपयोग किया int64_t, लेकिन किसी भी चौड़ाई (हस्ताक्षरित या अहस्ताक्षरित) का उपयोग थोड़ा संशोधन के साथ किया जा सकता है। हालांकि, अगर आप एक गैर निश्चित-चौड़ाई पूर्णांक प्रकार उपयोग करने की आवश्यकता है, तो आप परिवर्तन करने की आवश्यकता होगी SQRT_INT64_MAXद्वारा (int)sqrt(INT_MAX)(का उपयोग कर के मामले में intया कुछ इसी तरह की है, जो अनुकूलित किया जाना चाहिए), लेकिन यह भद्दा है, और नहीं एक सी निरंतर अभिव्यक्ति। इसके अलावा का परिणाम कास्टिंग sqrt()के लिए एक intहै क्योंकि एक पूर्ण वर्ग के मामले में चल बिन्दु precission का बहुत अच्छा नहीं है, लेकिन जैसा कि मैंने किसी भी कार्यान्वयन जहां का पता नहीं है INT_MAX-या किसी भी type- की अधिकतम एक पूर्ण वर्ग है, तो आप रह सकते हैं उस के साथ।


0

मैंने एल्गोरिथ्म को लागू किया है जो सभी गणना की गई शक्तियों को याद करता है और फिर जरूरत पड़ने पर उनका उपयोग करता है। इसलिए उदाहरण के लिए x ^ 13 बराबर है (x ^ 2) ^ 2 ^ 2 * 2 ^ x ^ 2 ^ 2 * x जहां x ^ 2 ^ 2 ने इसे एक बार फिर से गणना करने के बजाय तालिका से लिया। यह मूल रूप से @Pramod उत्तर (लेकिन C # में) का कार्यान्वयन है। आवश्यक गुणन की संख्या Ceil (Log n) है

public static int Power(int base, int exp)
{
    int tab[] = new int[exp + 1];
    tab[0] = 1;
    tab[1] = base;
    return Power(base, exp, tab);
}

public static int Power(int base, int exp, int tab[])
    {
         if(exp == 0) return 1;
         if(exp == 1) return base;
         int i = 1;
         while(i < exp/2)
         {  
            if(tab[2 * i] <= 0)
                tab[2 * i] = tab[i] * tab[i];
            i = i << 1;
          }
    if(exp <=  i)
        return tab[i];
     else return tab[i] * Power(base, exp - i, tab);
}

public? 2 कार्यों का नाम समान है? यह एक C प्रश्न है।
काकाहुइट फ्रिटो

-1

मेरा मामला थोड़ा अलग है, मैं एक शक्ति से एक मुखौटा बनाने की कोशिश कर रहा हूं, लेकिन मुझे लगा कि मैं वैसे भी समाधान साझा करूंगा।

जाहिर है, यह केवल 2 की शक्तियों के लिए काम करता है।

Mask1 = 1 << (Exponent - 1);
Mask2 = Mask1 - 1;
return Mask1 + Mask2;

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

क्या वह 1 << 64 के लिए था? वह एक अतिप्रवाह है। सबसे बड़ा पूर्णांक इसके ठीक नीचे है: (1 << 64) - 1.
माइकेल रॉय

1 << 64 == 0, यही कारण है कि। हो सकता है कि आपका प्रतिनिधित्व आपके ऐप के लिए सबसे अच्छा हो। मैं एक अतिरिक्त चर के बिना, मैक्रो में रखे जाने वाले सामान को पसंद कर सकता हूं, जैसे #define MASK(e) (((e) >= 64) ? -1 :( (1 << (e)) - 1)), ताकि संकलन समय पर गणना की जा सके
माइकेल रॉय

हाँ, मुझे पता है कि अतिप्रवाह क्या है। सिर्फ इसलिए कि मैंने उस शब्द का उपयोग नहीं किया है, वह अनावश्यक रूप से कृपालु होने का निमंत्रण नहीं है। जैसा कि मैंने कहा, यह मेरे लिए काम करता है और इसलिए इसे साझा करने के लिए खोज करने में थोड़ा प्रयास किया गया। यह इत्ना आसान है।
मार्कस जे।

अगर तुम्हें बुरा लगा तो माफ़ करें। मैं वास्तव में मतलब नहीं था।
माइकल रॉय

-1

यदि आप कंपाइलर-टाइम पर घातांक (और यह पूर्णांक है) जानते हैं, तो आप लूप को अनियंत्रित करने के लिए टेम्प्लेट का उपयोग कर सकते हैं। इसे और अधिक कुशल बनाया जा सकता है, लेकिन मैं यहां मूल सिद्धांत को प्रदर्शित करना चाहता था:

#include <iostream>

template<unsigned long N>
unsigned long inline exp_unroll(unsigned base) {
    return base * exp_unroll<N-1>(base);
}

हम खाका विशेषज्ञता का उपयोग करके पुनरावृत्ति को समाप्त करते हैं:

template<>
unsigned long inline exp_unroll<1>(unsigned base) {
    return base;
}

घातांक को रनटाइम पर जाना चाहिए,

int main(int argc, char * argv[]) {
    std::cout << argv[1] <<"**5= " << exp_unroll<5>(atoi(argv[1])) << ;std::endl;
}

1
यह स्पष्ट रूप से C ++ प्रश्न नहीं है। (c != c++) == 1
काकाहुइटे फ्रिटो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.