summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-22 11:21:13 +0300
committerPaul Buetow <paul@buetow.org>2026-05-22 11:21:13 +0300
commit407f1dd6f3bcd7916c3e555e4d9814a04566b88c (patch)
tree1bc1b80b45a33c8bbea3d61a2e9f735714dccd96
parentef9951b6f114ed1ac59b855030a12c9d9963d68c (diff)
fix(rpn): restore binary exponentiation in FastPower
After dead-code removal, FastPower used math.Pow instead of binaryExponentiationFloat, losing O(log n) efficiency for large integer exponents and potentially reducing accuracy. Restore the square-and-multiply helper in operations_arithmetic.go.
-rw-r--r--internal/rpn/operations_arithmetic.go28
1 files changed, 27 insertions, 1 deletions
diff --git a/internal/rpn/operations_arithmetic.go b/internal/rpn/operations_arithmetic.go
index 3b6a1fd..429a14c 100644
--- a/internal/rpn/operations_arithmetic.go
+++ b/internal/rpn/operations_arithmetic.go
@@ -215,11 +215,37 @@ func (o *Operations) FastPower(stack *Stack) error {
stack.Push(NewNumber(1, o.GetMode(), GetCoolMetric()))
return nil
}
- resultVal := math.Pow(aF, float64(exp))
+ resultVal := binaryExponentiationFloat(aF, exp)
stack.Push(NewNumber(resultVal, o.GetMode(), GetCoolMetric()))
return nil
}
+// binaryExponentiationFloat computes base^exp using the square-and-multiply algorithm.
+// Time Complexity: O(log exp)
+// Space Complexity: O(1)
+func binaryExponentiationFloat(base float64, exp int) float64 {
+ if exp == 0 {
+ return 1.0
+ }
+
+ // Handle negative exponents: base^-exp = 1 / (base^exp)
+ if exp < 0 {
+ return 1.0 / binaryExponentiationFloat(base, -exp)
+ }
+
+ res := 1.0
+ for exp > 0 {
+ // If exponent is odd, multiply result by current base
+ if exp%2 == 1 {
+ res *= base
+ }
+ // Square the base and divide exponent by 2
+ base *= base
+ exp /= 2
+ }
+ return res
+}
+
// Log2 pops one value from stack, computes log base 2 (logâ‚‚(a)), and pushes result.
func (o *Operations) Log2(stack *Stack) error {
a, err := popStack(stack, "lg")