diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-24 18:43:34 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-24 18:43:34 +0300 |
| commit | a03e4511536a3cdafb51e187aa3bb9df764e8fec (patch) | |
| tree | 14da6319172e99c23e8f6bcc1c1ae8765b3f7a34 | |
| parent | dfe36f2e29199b5a864ff02b0a6de0bd0f2010f4 (diff) | |
fix(rpn): delegate Modulo to binaryMetricOp (task gk)
| -rw-r--r-- | internal/rpn/operations_arithmetic.go | 60 |
1 files changed, 18 insertions, 42 deletions
diff --git a/internal/rpn/operations_arithmetic.go b/internal/rpn/operations_arithmetic.go index 4468edb..d47adef 100644 --- a/internal/rpn/operations_arithmetic.go +++ b/internal/rpn/operations_arithmetic.go @@ -170,48 +170,24 @@ func (o *Operations) Power(stack *Stack) error { // Modulo pops two values from stack, computes modulo (a % b), and pushes result. func (o *Operations) Modulo(stack *Stack) error { - a, b, err := popTwo(stack, "%") - if err != nil { - return err - } - - bF, err := toFloat64(b, "%") - if err != nil { - return err - } - if bF == 0 { - return buildError("%", fmt.Errorf("modulo by zero")) - } - - aM, err := resolveMetric(o.metricRegistry, a) - if err != nil { - return buildError("%", err) - } - bM, err := resolveMetric(o.metricRegistry, b) - if err != nil { - return buildError("%", err) - } - if !categoriesCompatible(aM, bM) { - return metricError("%", aM, bM) - } - - pm := o.GetPrefixMode() - resultMetric := compatibleMetric(o.metricRegistry, aM, bM) - aBase, err := convertToBase(o.metricRegistry, a, pm, resultMetric) - if err != nil { - return buildError("%", err) - } - bBase, err := convertToBase(o.metricRegistry, b, pm, resultMetric) - if err != nil { - return buildError("%", err) - } - resultVal, err := convertFromBase(o.metricRegistry, math.Mod(aBase, bBase), resultMetric, pm) - if err != nil { - return buildError("%", err) - } - - stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), resultMetric)) - return nil + return o.binaryMetricOp( + stack, "%", + nil, // no compatibility check — compatibleMetric handles result type + func(a, b float64) float64 { return math.Mod(a, b) }, + func(reg MetricReader, aM, bM *Metric) (*Metric, error) { + return compatibleMetric(reg, aM, bM), nil + }, + func(sv StackValue) error { + f, err := toFloat64(sv, "%") + if err != nil { + return err + } + if f == 0 { + return buildError("%", fmt.Errorf("modulo by zero")) + } + return nil + }, + ) } // FastPower pops two values from stack, raises first to integer power of second (a ** b), and pushes result. |
