summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-23 22:56:10 +0300
committerPaul Buetow <paul@buetow.org>2026-05-23 22:56:10 +0300
commit357f939503630fc03e810770a241908f8f55cd12 (patch)
treed37c8979e50d89f26cb7e7f230709b47f0555f02
parent4fbbb78125b58a7360d9441fbd175e658e03f534 (diff)
refactor: extract shared logOp() helper for Log2/Log10/Ln
Log2, Log10, and Ln were ~13 lines each, nearly identical except for the log function and error messages. Created private logOp() helper that wraps popStack, toFloat64, validation, and stack.Push. All three methods now delegate to logOp() with the appropriate math.Log2/math.Log10/math.Log function.
-rw-r--r--internal/rpn/operations_arithmetic.go52
1 files changed, 13 insertions, 39 deletions
diff --git a/internal/rpn/operations_arithmetic.go b/internal/rpn/operations_arithmetic.go
index fd1b0fa..d243140 100644
--- a/internal/rpn/operations_arithmetic.go
+++ b/internal/rpn/operations_arithmetic.go
@@ -291,63 +291,37 @@ func binaryExponentiationFloat(base float64, exp int) float64 {
// 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")
- if err != nil {
- return err
- }
-
- val, err := toFloat64(a, "log2")
- if err != nil {
- return err
- }
- if val <= 0 {
- return buildError("lg", fmt.Errorf("log2 undefined for non-positive numbers"))
- }
-
- // Compute log2 using the number interface
- mode := o.GetMode()
- stack.Push(NewNumber(math.Log2(val), mode))
- return nil
+ return o.logOp(stack, "lg", math.Log2)
}
// Log10 pops one value from stack, computes log base 10 (log₁₀(a)), and pushes result.
func (o *Operations) Log10(stack *Stack) error {
- a, err := popStack(stack, "log")
- if err != nil {
- return err
- }
-
- val, err := toFloat64(a, "log10")
- if err != nil {
- return err
- }
- if val <= 0 {
- return buildError("log", fmt.Errorf("log10 undefined for non-positive numbers"))
- }
-
- // Compute log10 using the number interface
- mode := o.GetMode()
- stack.Push(NewNumber(math.Log10(val), mode))
- return nil
+ return o.logOp(stack, "log", math.Log10)
}
// Ln pops one value from stack, computes natural log (ln(a)), and pushes result.
func (o *Operations) Ln(stack *Stack) error {
- a, err := popStack(stack, "ln")
+ return o.logOp(stack, "ln", math.Log)
+}
+
+// logOp computes a logarithmic operation on the stack top value.
+// logFn is the actual log function (math.Log2, math.Log10, math.Log).
+// opName is used for error messages and popStack context.
+func (o *Operations) logOp(stack *Stack, opName string, logFn func(float64) float64) error {
+ a, err := popStack(stack, opName)
if err != nil {
return err
}
- val, err := toFloat64(a, "ln")
+ val, err := toFloat64(a, opName)
if err != nil {
return err
}
if val <= 0 {
- return buildError("ln", fmt.Errorf("ln undefined for non-positive numbers"))
+ return buildError(opName, fmt.Errorf("%s undefined for non-positive numbers", opName))
}
- // Compute ln using the number interface
mode := o.GetMode()
- stack.Push(NewNumber(math.Log(val), mode))
+ stack.Push(NewNumber(logFn(val), mode))
return nil
}