एलियास के जवाब के अलावा, जो हस्ताक्षरित पूर्णांक के साथ लागू होने पर अपरिभाषित व्यवहार का कारण बनता है, और अहस्ताक्षरित पूर्णांक के साथ लागू होने पर उच्च इनपुट के लिए गलत मान,
यहाँ स्क्वेरिंग द्वारा एक्सप्रेशन का एक संशोधित संस्करण है जो हस्ताक्षरित पूर्णांक प्रकारों के साथ भी काम करता है, और गलत मान नहीं देता है:
#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- की अधिकतम एक पूर्ण वर्ग है, तो आप रह सकते हैं उस के साथ।