একটি পূর্ণসংখ্যার ভিত্তিক পাওয়ার ফাংশন পাও (ইনট, ইনট) কার্যকর করার সবচেয়ে কার্যকর উপায়


249

সি-তে অন্য কোনও পূর্ণসংখ্যার শক্তিতে পূর্ণসংখ্যা বাড়াতে সবচেয়ে কার্যকর উপায় কী?

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

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

3
আপনি যখন "দক্ষতা" বলছেন তখন আপনাকে কী সম্পর্কিত দক্ষতা নির্দিষ্ট করতে হবে। গতি? মেমরি ব্যবহার? কোডের আকার? Maintainability?
অ্যান্ডি লেস্টার

সি এর কোন পাও () ফাংশন নেই?
জলফ

16
হ্যাঁ, তবে এটি ফ্লোট বা ডাবলসে কাজ করে,
ইনটসে

1
আপনি যদি সত্যিকারের int(এবং কোনও বিশাল-অন্তর্গত শ্রেণীর না হয়ে) আঁকড়ে থাকেন তবে আইপুতে প্রচুর কলগুলি উপচে পড়বে। এটি আমাকে বিস্মিত করে তোলে যে কোনও টেবিলের প্রাক-গণনা করার এবং সরল টেবিল অনুসন্ধানে সমস্ত অ-উপচে পড়া সংমিশ্রণ হ্রাস করার কোনও চতুর উপায় আছে। এটি বেশিরভাগ সাধারণ উত্তরের চেয়ে বেশি স্মৃতি গ্রহণ করবে তবে গতির ক্ষেত্রে সম্ভবত আরও দক্ষ।
অ্যাড্রিয়ান ম্যাকার্থি

pow()নিরাপদ ফাংশন নয়
ইসমা:

উত্তর:


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
আপনার সম্ভবত একটি চেক যুক্ত করা উচিত যা "এক্সপ্রেস" নেতিবাচক নয়। বর্তমানে, এই ফাংশনটি হয় ভুল উত্তর দেয় বা চিরতরে লুপ করে দেয়। (একটি স্বাক্ষরিত ইন এর উপর >> = শূন্য-প্যাডিং বা সাইন-এক্সটেনশন করে কিনা তার উপর নির্ভর করে - সি সংকলকগণ উভয়ই আচরণ বাছাই করার অনুমতিপ্রাপ্ত)।
ব্যবহারকারী9876

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
@ জিনানএক্সিং গুণের এন গুণগুলি আরও গুণে ফলাফল দেয় এবং ধীর হয়। এই পদ্ধতিটি কার্যকরভাবে পুনরায় ব্যবহার করে গুণগুলি সংরক্ষণ করে। উদাহরণস্বরূপ, n ^ 8 গণনা করার জন্য n*n*n*n*n*n*n*n7 টি গুণের ব্যবহারের ভীরু পদ্ধতি । এই অ্যালগরিদম পরিবর্তে গণনা করে m=n*n, তারপরে o=m*m, p=o*oযেখানে p= n ^ 8, কেবল তিনটি গুণ দ্বারা। বড় এক্সপোজারগুলির সাথে পারফরম্যান্সের পার্থক্য উল্লেখযোগ্য।
bames53

68

নোট করুন যে স্কোয়ারিং দ্বারা ক্ষয়ক্ষতি সর্বাধিক অনুকূল পদ্ধতি নয়। এটি সাধারণ পদ্ধতির হিসাবে আপনি সবচেয়ে ভাল করতে পারেন যা সমস্ত ক্ষতিকারক মানগুলির জন্য কাজ করে তবে একটি নির্দিষ্ট পরিমাণের মানের জন্য আরও ভাল ক্রম হতে পারে যার জন্য আরও কম গুণ করা দরকার।

উদাহরণস্বরূপ, আপনি যদি 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 for এর সংক্ষিপ্ত সংযোজন শৃঙ্খলে, a⁶ এর সাব-প্রব্লেমটি অবশ্যই (a³) হিসাবে গণনা করা উচিত ² যেহেতু a³ পুনরায় ব্যবহৃত হয় (বলুন, a⁶ = a² (a²) ², যার জন্য তিনটি গুণও প্রয়োজন )।


4
@ জেরেমি সালওয়েন: যেমন এই উত্তরে বলা হয়েছে, বাইনারি এক্সপেনসিয়েশন সাধারণভাবে সর্বাধিক অনুকূল পদ্ধতি নয়। গুণের নূন্যতম ক্রম সন্ধানের জন্য বর্তমানে কোনও দক্ষ অ্যালগরিদম নেই।
এরিক পোস্টপিসিল

2
@ এরিকপোস্টপিসিল, এটি আপনার আবেদনের উপর নির্ভর করে। সাধারণত সমস্ত সংখ্যার জন্য কাজ করার জন্য আমাদের সাধারণ অ্যালগরিদমের প্রয়োজন হয় না । আর্ট অফ কম্পিউটার প্রোগ্রামিং দেখুন, খণ্ড। 2: সেমিনিয়ামিক্যাল অ্যালগরিদমস
পেসারিয়ার

3
আলেকজান্ডার স্টেপানোভ এবং ড্যানিয়েল রোজের গণিত থেকে জেনেরিক প্রোগ্রামিংয়ের ক্ষেত্রে এই সঠিক সমস্যার উত্সাহ রয়েছে। এই বইটি প্রতিটি সফটওয়্যার প্র্যাকটিশনার, আইএমএইচওর তাক হতে হবে on
টবি স্পিড

2
আরও দেখুন en.wikedia.org/wiki/…
lhf

এটি পূর্ণসংখ্যার জন্য অনুকূলিত হতে পারে কারণ 255 পূর্ণসংখ্যার শক্তির নীচে ভাল রয়েছে যা 32 বিট পূর্ণসংখ্যার জন্য ওভারফ্লো করতে পারে না। আপনি প্রতিটি int এর জন্য অনুকূল গুণন কাঠামো ক্যাশে করতে পারেন। আমি কল্পনা করেছি যে কোড + ডেটা কেবল সমস্ত ক্ষমতা ক্যাশে করার চেয়ে ছোট হবে ...
জোশিয়াহ যোদার

22

আপনার যদি প্রয়োজন হয় একটি পাওয়ার 2 বাড়াতে। এটির দ্রুততম উপায়টি হ'ল বিদ্যুৎ থেকে বিট শিফট।

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

এটি করার জন্য এখানে কি একটি দুর্দান্ত উপায় আছে যাতে 2 ** 0 == 1?
রব স্মলশায়ার

16
2 ** 0 == 1 << 0 == 1
জেক 18

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;
}

বড় সংখ্যা হিসাবে কাজ করে না যেমন পা (71045970,41535484)
আনুশ্রী আচার্জি

16
@ আনুশ্রীআচার্জি অবশ্যই তা নয়। এই জাতীয় সংখ্যার গণনা করার জন্য নির্বিচারে নির্ভুল গণিতের প্রয়োজন হবে।
ডেভিড এলটার 21

বড় সংখ্যার জন্য বিগইন্টেগার # মোডপাও বা বিগিন্টেজার # পাউ ব্যবহার করুন, যুক্তির আকারের উপর ভিত্তি করে যথাযথ অ্যালগরিদমগুলি ইতিমধ্যে বাস্তবায়িত হয়েছে
রমন ইয়েলিয়ানভিচ

এটি কোনও জাভা প্রশ্ন নয়!
কাকাহুতে ফ্রেটো

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)
এমসাল্টার

শুধুমাত্র নেতিবাচক সূচক যে হতে পারে আপনি int- এ পরিসীমা বের করে নয় -1। এবং এটি কেবল তখনই কাজ করে যদি বেস 1 বা -1 হয়। সুতরাং এক্সপ <0 এর সাথে কেবলমাত্র দুটি জোড়া (বেস, এক্সপ্রেস) রয়েছে যা অ ইন্টিজার শক্তিগুলিতে নেতৃত্ব দেয় না। যদিও আমি একজন গণিতজ্ঞ এবং আমি কোয়ান্টিফায়ারদের পছন্দ করি, আমি মনে করি এই ক্ষেত্রে
বাস্তবে বাস্তবে

6

আপনি যদি কোনও জিনিসের শক্তিতে উত্থিত 2 এর জন্য একটি পূর্ণসংখ্যার মান পেতে চান তবে শিফ্ট বিকল্পটি ব্যবহার করা সর্বদা ভাল is

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)গণনা করা হবে তা বিবেচনা করুন )।
গ্রেইবার্ড

@ গ্রেইবার্ড আমি কিছু মন্তব্য উল্লেখ করেছি। এটি হতে পারে যা আপনার প্রশ্নের সমাধান করতে পারে
রুট ট্রাভেলার

1
জিএনইউ বৈজ্ঞানিক লাইব্রেরিতে ইতিমধ্যে আপনার দ্বিতীয় ফাংশন রয়েছে: gnu.org/software/gsl/manual/html_node/Small-integer-powers.html
ক্যাকাহুয়েত ফ্রিটো

@রোট্রাভেলার আপনি কি দয়া করে negative exp and float baseসমাধানটি ব্যাখ্যা করতে পারেন ? আমরা কেন টেম্পর, 2 দ্বারা আলাদা এক্সপ্রেস এবং চেক এক্সপ (এমনকি / বিজোড়) ব্যবহার করব? ধন্যবাদ!
লেভ

6

একটি অত্যন্ত বিশিষ্ট কেসটি হ'ল, যখন আপনার 2 ^ (- x থেকে y) বলা দরকার, যেখানে এক্স অবশ্যই negativeণাত্মক এবং y খুব সহজেই কোনও int এ স্থানান্তরিত করতে পারে না। আপনি এখনও ভাসা দিয়ে স্ক্রু করে স্থির সময়ে 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 এর আরও বেশি পাওয়ার পেতে পারেন। (এই পোস্টটি বর্গাকারে সাহায্য করার জন্য মন্তব্যকারীদের অনেক ধন্যবাদ)

এছাড়াও সম্ভাবনা রয়েছে যে আইইইই ভাসমান সম্পর্কে আরও শিখতে , ক্ষয়ক্ষতির অন্যান্য বিশেষ ক্ষেত্রে তারা উপস্থাপন করতে পারে।


নিফটির সমাধান, তবে আনজিগেন্ড ??
paxdiablo

একটি আইইইই ফ্ল্যাট বেস x 2 ^ এক্সপ্রেস হয়, এক্সপোনেন্ট ভ্যালু পরিবর্তন করলে
দু'র

আপনি সমস্তই সঠিক, আমি ভুল সমাধান করেছিলাম যে আমার সমাধানটি মূলত 2 টি পাওয়ার জন্য স্পষ্টভাবে 2 এর শক্তির জন্য অনেক আগে লেখা হয়েছিল। আমি আমার উত্তরটি সমস্যার একটি বিশেষ কেস সমাধান হিসাবে পুনরায় লিখেছি।
ডগ টি।

প্রথমত, কোডটি উদ্ধৃত হিসাবে ভাঙা হয়েছে, এবং এটি সংকলন করার জন্য সম্পাদনা প্রয়োজন। দ্বিতীয়ত কোডটি জিসিসি ব্যবহার করে একটি কোর 2 ডি ভাঙা। দেখতে এই ডাম্প সম্ভবত আমি কিছু ভুল করেনি। তবে আমি মনে করি না এটি কার্যকর হবে, যেহেতু আইইইই ফ্লোট এক্সপোনেন্টটি বেস 10
ফ্রিস্পেস

3
বেস 10? আহ না, এটি বেস 2, আপনি যদি বাইনারি হিসাবে 10 বোঝাতে না চান :)
ড্রিলার

4

যেমন স্কোয়ারিংয়ের মাধ্যমে ক্ষয়ক্ষতির দক্ষতা সম্পর্কে মন্তব্যে অনুসরণ করা।

এই পদ্ধতির সুবিধা হ'ল এটি লগ (এন) সময়ে চলে। উদাহরণস্বরূপ, আপনি যদি এক্স something 1048575 (2 ^ 20 - 1) এর মতো বিশাল কিছু গণনা করতে যাচ্ছেন তবে নিখুঁত পদ্ধতির সাহায্যে আপনাকে 1 মিলিয়ন নয়, 20 বার লুপের মধ্য দিয়ে যেতে হবে।

এছাড়াও কোড জটিলতার নিরিখে, গুণের সর্বাধিক অনুকূল ক্রম সন্ধান করার চেয়ে এটি সহজ, একটি লা প্রমোদের পরামর্শ od

সম্পাদনা:

আমার ধারণা, ওভারফ্লোর সম্ভাবনার জন্য কেউ আমাকে ট্যাগ করার আগে আমার স্পষ্ট করা উচিত। এই পদ্ধতির ধরে নেওয়া হয় যে আপনার কাছে একরকম বিশালাকার লাইব্রেরি রয়েছে।


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। আপনি গুণ করতে পারেন তা পরীক্ষা করে বিবেচনা করুন বা স্বাক্ষরবিহীন থেকে সরানো যেতে এবং এটিকে চারপাশে মোড়ানো দিন।
কাকাহুতে ফ্রেটো

expস্বাক্ষর করার কোনও কারণ নেই । এটি বৈকল্পিক অবস্থার কারণে কোডটি জটিল করে তোলে যেখানে (-1) ** (-N)বৈধ এবং যে কোনওটি এর নেতিবাচক মূল্যবোধের জন্য abs(base) > 1হতে পারে , সুতরাং এটি স্বাক্ষরযুক্ত না করা এবং সেই কোডটি সংরক্ষণ করা ভাল। 0exp
ক্যাকাহুয়েত ফ্রিটো

1
@ ক্যাকাহুয়েফ্রেট্রিটো সত্য যে yসাইন ইন হিসাবে সত্যই প্রয়োজন হয় না এবং আপনার মন্তব্য করা জটিলতাগুলি নিয়ে আসে, তবুও ওপির অনুরোধ সুনির্দিষ্ট ছিল pow(int, int)। সুতরাং এই ভাল মন্তব্যগুলি ওপেনের প্রশ্নের সাথে সম্পর্কিত। ওপি ওভারফ্লোতে কী করা উচিত তা সুনির্দিষ্টভাবে উল্লেখ না করে, একটি ভাল সংজ্ঞায়িত ভুল উত্তরটি ইউবির চেয়ে কেবলমাত্র সামান্য ভাল better "সর্বাধিক দক্ষ উপায়" দেওয়া, আমি সন্দেহ করি ওপি অফ সম্পর্কে যত্নশীল about
chux -

1

নেতিবাচক exponenet বিবেচনা করে আরও জেনেরিক সমাধান

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)একটি অসীম লুপ হতে পারে।
chux -

1
@ চাক্স: এটি আপনার হার্ডডিস্ক ফর্ম্যাট করতে পারে: পূর্ণসংখ্যার ওভারফ্লো হ'ল ইউবি।
এমসাল্টার্স

@ এসএমএলটারগুলি 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)intsqrt()intINT_MAX


0

আমি অ্যালগরিদম প্রয়োগ করেছি যা সমস্ত গণনাকারী শক্তি মুখস্থ করে এবং তারপরে যখন প্রয়োজন হয় তখন তা ব্যবহার করে। সুতরাং উদাহরণস্বরূপ x ^ 13 এর সাথে সমান (x ^ 2) ^ 2 ^ 2 * x ^ 2 ^ 2 * x যেখানে x ^ 2 ^ 2 এটি আবার টেস্টিংয়ের পরিবর্তে টেবিল থেকে নেওয়া হয়েছিল। এটি মূলত @ প্রমোদ উত্তরের বাস্তবায়ন (তবে সি # তে)। প্রয়োজনীয় সংখ্যাটি হ'ল সিল (লগ এন)

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? ২ টি ফাংশন একই নামে? এটি একটি সি প্রশ্ন।
ক্যাকাহুয়েত ফ্রিটো

-1

আমার কেসটি অন্যরকম, আমি একটি শক্তি থেকে একটি মুখোশ তৈরি করার চেষ্টা করছি, তবে আমি ভেবেছিলাম যে সমাধানটি আমি যেভাবেই পেয়েছি তা ভাগ করে নেব।

স্পষ্টতই, এটি কেবল 2 এর ক্ষমতার জন্য কাজ করে।

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

আমি চেষ্টা করেছিলাম, এটি bit৪ বিটের জন্য কাজ করে না, এটি কখনই ফিরে আসবে না এবং এই নির্দিষ্ট ক্ষেত্রে আমি সমস্ত বিটকে এক্স সহ কম সেট করার চেষ্টা করছি।
মারকাসজে

এটি 1 << 64 এর জন্য ছিল? এটি একটি উপচে পড়া। বৃহত্তম পূর্ণসংখ্যা এর ঠিক নীচে: (1 << 64) - ১
মাইকেল রয়

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++) == 1
ক্যাকাহুয়েত ফ্রেটো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.