diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-22 11:21:13 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-22 11:21:13 +0300 |
| commit | 407f1dd6f3bcd7916c3e555e4d9814a04566b88c (patch) | |
| tree | 1bc1b80b45a33c8bbea3d61a2e9f735714dccd96 /internal/rpn/operations_arithmetic.go | |
| parent | ef9951b6f114ed1ac59b855030a12c9d9963d68c (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.
Diffstat (limited to 'internal/rpn/operations_arithmetic.go')
| -rw-r--r-- | internal/rpn/operations_arithmetic.go | 28 |
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") |
