İşaretli tamsayılarla uygulandığında Tanımsız Davranışa ve işaretsiz tamsayılarla uygulandığında yüksek girdi için yanlış değerlere neden olan Elias tarafından verilen cevaba ek olarak,
imzalı tam sayı türleriyle de çalışan ve yanlış değerler vermeyen Squaring ile Exponentiation'un değiştirilmiş bir sürümü:
#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;
}
Bu işlev için dikkat edilmesi gerekenler:
(1 ** N) == 1
(N ** 0) == 1
(0 ** 0) == 1
(0 ** N) == 0
Herhangi bir taşma veya sarma gerçekleşecekse, return 0;
Kullandım int64_t
, ancak herhangi bir genişlik (imzalı veya imzasız) küçük bir değişiklikle kullanılabilir. Bununla birlikte, bir sabit-olmayan genişlikte bir tamsayı türü kullanmak gerekir, eğer değiştirmek gerekir SQRT_INT64_MAX
ile (int)sqrt(INT_MAX)
(kullanıldığı durumda int
ya da optimize edilmelidir benzer bir), ancak bir Cı sabit ifade çirkin bir olup. Ayrıca mükemmel bir kare durumunda kayan nokta hassasiyeti nedeniyle sqrt()
bir sonucun dökülmesi int
çok iyi değildir, ancak INT_MAX
-veya herhangi bir türün maksimumunun - mükemmel bir kare olduğu herhangi bir uygulama bilmiyorum. Bununla.