summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-22 13:02:56 +0300
committerPaul Buetow <paul@buetow.org>2026-05-22 13:02:56 +0300
commit3757c00ea3e3a44c40eaec1a43adc2dd730accb9 (patch)
treee99f9071c2dc77c6966ad2248326aefce9e4c844
parentd0cb0dfad408553f4e90e12ea4b235b912885dd1 (diff)
refactor(rpn): extract shared hyperLog helper for log operations
Replace the near-duplicate HyperLog2, HyperLog10, and HyperLn implementations with a single hyperLog helper that accepts the operation name, log function, and error message as parameters. Each public method is now a one-line call to the shared helper.
-rw-r--r--internal/rpn/operations_hyper.go69
1 files changed, 19 insertions, 50 deletions
diff --git a/internal/rpn/operations_hyper.go b/internal/rpn/operations_hyper.go
index c6c4beb..955832f 100644
--- a/internal/rpn/operations_hyper.go
+++ b/internal/rpn/operations_hyper.go
@@ -4,6 +4,7 @@
package rpn
import (
+ "errors"
"fmt"
"math"
)
@@ -222,24 +223,24 @@ func (o *Operations) HyperModulo(stack *Stack) error {
return nil
}
-// HyperLog2 pops all values from stack, computes sum of log2 for all values, and pushes result.
-// No metric validation; uses raw float64 values. Result is always Cool (unitless).
-func (o *Operations) HyperLog2(stack *Stack) error {
- values, err := popAll(stack, "[lg]")
+// hyperLog computes the sum of a log function over all stack values.
+// Each value must be positive. Result is pushed with Cool metric.
+func (o *Operations) hyperLog(stack *Stack, opName string, logFn func(float64) float64, errMsg string) error {
+ values, err := popAll(stack, opName)
if err != nil {
return err
}
- var result float64 = 0
- for i := 0; i < len(values); i++ {
- val, err := values[i].Float64()
+ var result float64
+ for i, v := range values {
+ val, err := v.Float64()
if err != nil {
- return buildError("[lg]", fmt.Errorf("operand %d: %w", i, err))
+ return buildError(opName, fmt.Errorf("operand %d: %w", i, err))
}
if val <= 0 {
- return buildError("[lg]", fmt.Errorf("log2 undefined for non-positive numbers"))
+ return buildError(opName, errors.New(errMsg))
}
- result += math.Log2(val)
+ result += logFn(val)
}
cool := coolMetric(o.metricRegistry)
@@ -247,54 +248,22 @@ func (o *Operations) HyperLog2(stack *Stack) error {
return nil
}
+// HyperLog2 pops all values from stack, computes sum of log2 for all values, and pushes result.
+// No metric validation; uses raw float64 values. Result is always Cool (unitless).
+func (o *Operations) HyperLog2(stack *Stack) error {
+ return o.hyperLog(stack, "[lg]", math.Log2, "log2 undefined for non-positive numbers")
+}
+
// HyperLog10 pops all values from stack, computes sum of log10 for all values, and pushes result.
// No metric validation; uses raw float64 values. Result is always Cool (unitless).
func (o *Operations) HyperLog10(stack *Stack) error {
- values, err := popAll(stack, "[log]")
- if err != nil {
- return err
- }
-
- var result float64 = 0
- for i := 0; i < len(values); i++ {
- val, err := values[i].Float64()
- if err != nil {
- return buildError("[log]", fmt.Errorf("operand %d: %w", i, err))
- }
- if val <= 0 {
- return buildError("[log]", fmt.Errorf("log10 undefined for non-positive numbers"))
- }
- result += math.Log10(val)
- }
-
- cool := coolMetric(o.metricRegistry)
- stack.Push(NewNumber(result, o.GetMode(), cool))
- return nil
+ return o.hyperLog(stack, "[log]", math.Log10, "log10 undefined for non-positive numbers")
}
// HyperLn pops all values from stack, computes sum of natural log for all values, and pushes result.
// No metric validation; uses raw float64 values. Result is always Cool (unitless).
func (o *Operations) HyperLn(stack *Stack) error {
- values, err := popAll(stack, "[ln]")
- if err != nil {
- return err
- }
-
- var result float64 = 0
- for i := 0; i < len(values); i++ {
- val, err := values[i].Float64()
- if err != nil {
- return buildError("[ln]", fmt.Errorf("operand %d: %w", i, err))
- }
- if val <= 0 {
- return buildError("[ln]", fmt.Errorf("ln undefined for non-positive numbers"))
- }
- result += math.Log(val)
- }
-
- cool := coolMetric(o.metricRegistry)
- stack.Push(NewNumber(result, o.GetMode(), cool))
- return nil
+ return o.hyperLog(stack, "[ln]", math.Log, "ln undefined for non-positive numbers")
}