การคำนวณ $base^{exponent}$ ใน C# มีหลายวิธี ตั้งแต่ Built-in Method จนถึง Custom Implementation
วิธีที่ 1: Math.Pow (Built-in - Double)
using System;
double n = 7;
double p = 3;
double res = Math.Pow(n, p); // 343.0
Console.WriteLine($"Exponent Power = {n}");
Console.WriteLine($"Result = {res}");
ผลลัพธ์
Exponent Power= 7
Result= 343
⚠️ ข้อควรระวังกับ Math.Pow
- รับและคืนค่า **double** - อาจมี Precision Error กับจำนวนเต็มใหญ่
- ตัวอย่าง:
Math.Pow(10, 15)อาจได้999999999999999.9แทน1000000000000000 - ไม่รองรับ Negative Base กับ Fractional Exponent (NaN)
วิธีที่ 2: Integer Power (Exact - No Precision Loss)
A. Simple Loop (O(n))
public static long IntPow(long base, int exp) {
if (exp < 0) throw new ArgumentException("Negative exponent");
long result = 1;
for (int i = 0; i < exp; i++) result *= base;
return result;
}
B. Exponentiation by Squaring (O(log n) - แนะนำ)
public static long IntPowFast(long base, int exp) {
if (exp < 0) throw new ArgumentException("Negative exponent not supported for integers");
long result = 1;
while (exp > 0) {
if ((exp & 1) == 1) // exp is odd
result *= base;
base *= base;
exp >>= 1; // exp /= 2
}
return result;
}
// Trace: 5^13
// exp=13(odd) result=5 base=25 exp=6
// exp=6(even) result=5 base=625 exp=3
// exp=3(odd) result=3125 base=390625 exp=1
// exp=1(odd) result=1220703125 base=... exp=0
// Done
C. Recursive (Clean but Stack Overhead)
public static long IntPowRecursive(long base, int exp) {
if (exp == 0) return 1;
if (exp == 1) return base;
long half = IntPowRecursive(base, exp / 2);
if (exp % 2 == 0)
return half * half;
else
return half * half * base;
}
วิธีที่ 3: BigInteger (Unlimited Size)
using System.Numerics;
public static BigInteger BigPow(BigInteger base, int exp) {
if (exp < 0) throw new ArgumentException("Negative exponent");
BigInteger result = 1;
while (exp > 0) {
if ((exp & 1) == 1) result *= base;
base *= base;
exp >>= 1;
}
return result;
}
// 2^1000
var huge = BigPow(2, 1000); // 301 digits
วิธีที่ 4: Bit Shifting (เฉพาะ Power of 2)
// 2^n = 1 << n (Bit Shift)
int pow2_10 = 1 << 10; // 1024
long pow2_60 = 1L << 60; // 1,152,921,504,606,846,976
// ใช้ได้เฉพาะ Base = 2 และ Exponent >= 0
Benchmark (10^10)
| Method | Time Complexity | Precision | Use Case |
|---|---|---|---|
| Math.Pow | O(1) Hardware | Double (~15 digits) | Scientific, Float, Fractional Exp |
| Simple Loop | O(n) | Exact (Integer) | Small Exponent (< 30) |
| Exponentiation by Squaring | O(log n) | Exact (Integer) | General Integer Power ✅ Best |
| BigInteger | O(log n) × M(n) | Exact (Unlimited) | Very Large Numbers |
| Bit Shift (1 << n) | O(1) | Exact | Power of 2 Only |
Negative Exponents
// Math.Pow รองรับ Negative Exponent
double result = Math.Pow(2, -3); // 0.125
// Integer Power - ไม่รองรับ Negative (ต้องคืน Fraction)
// ใช้ double หรือ Rational/BigRational Library แทน
Best Practice Helper Class
public static class MathUtils {
// Integer Power - Fast & Exact
public static long Pow(long base, int exp) {
if (exp < 0) throw new ArgumentOutOfRangeException(nameof(exp));
long result = 1;
while (exp > 0) {
if ((exp & 1) == 1) result *= base;
base *= base;
exp >>= 1;
}
return result;
}
// Safe Power with Overflow Check
public static long PowChecked(long base, int exp) {
long result = 1;
while (exp > 0) {
if ((exp & 1) == 1) checked { result *= base; }
checked { base *= base; }
exp >>= 1;
}
return result;
}
}