diff options
author | Joe Mooring <joe.mooring@veriphor.com> | 2020-05-13 20:35:07 +0300 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2020-05-14 11:00:31 +0300 |
commit | 991934497e88dcd4134a369a213bb5072c51c139 (patch) | |
tree | d8a6aa405dc93f821dc1b389f70827e14fea6bce | |
parent | 558c09305e2be16953238c6c0e828f62b950e4f5 (diff) |
Add math.Pow
Closes #7266
-rw-r--r-- | docs/content/en/functions/math.md | 2 | ||||
-rw-r--r-- | tpl/math/init.go | 7 | ||||
-rw-r--r-- | tpl/math/math.go | 12 | ||||
-rw-r--r-- | tpl/math/math_test.go | 40 |
4 files changed, 60 insertions, 1 deletions
diff --git a/docs/content/en/functions/math.md b/docs/content/en/functions/math.md index 29fe16985..58cc5d5db 100644 --- a/docs/content/en/functions/math.md +++ b/docs/content/en/functions/math.md @@ -38,4 +38,4 @@ aliases: [] | `math.Round` | Returns the nearest integer, rounding half away from zero. | `{{math.Round 1.5}}` → `2` | | `math.Log` | Returns the natural logarithm of the given number. | `{{math.Log 42}}` → `3.737` | | `math.Sqrt` | Returns the square root of the given number. | `{{math.Sqrt 81}}` → `9` | - +| `math.Pow` | Returns the first number raised to the power of the second number. | `{{math.Pow 2 3}}` → `8` | diff --git a/tpl/math/init.go b/tpl/math/init.go index 45240c5e1..e7f9114ba 100644 --- a/tpl/math/init.go +++ b/tpl/math/init.go @@ -92,6 +92,13 @@ func init() { }, ) + ns.AddMethodMapping(ctx.Pow, + []string{"pow"}, + [][2]string{ + {"{{math.Pow 2 3}}", "8"}, + }, + ) + ns.AddMethodMapping(ctx.Round, nil, [][2]string{ diff --git a/tpl/math/math.go b/tpl/math/math.go index 950d95905..ecaf61ebc 100644 --- a/tpl/math/math.go +++ b/tpl/math/math.go @@ -115,6 +115,18 @@ func (ns *Namespace) Mul(a, b interface{}) (interface{}, error) { return _math.DoArithmetic(a, b, '*') } +// Pow returns a raised to the power of b. +func (ns *Namespace) Pow(a, b interface{}) (float64, error) { + af, erra := cast.ToFloat64E(a) + bf, errb := cast.ToFloat64E(b) + + if erra != nil || errb != nil { + return 0, errors.New("Pow operator can't be used with non-float value") + } + + return math.Pow(af, bf), nil +} + // Round returns the nearest integer, rounding half away from zero. func (ns *Namespace) Round(x interface{}) (float64, error) { xf, err := cast.ToFloat64E(x) diff --git a/tpl/math/math_test.go b/tpl/math/math_test.go index 70f6749ba..c48f71837 100644 --- a/tpl/math/math_test.go +++ b/tpl/math/math_test.go @@ -318,3 +318,43 @@ func TestRound(t *testing.T) { c.Assert(result, qt.Equals, test.expect) } } + +func TestPow(t *testing.T) { + t.Parallel() + c := qt.New(t) + + ns := New() + + for _, test := range []struct { + a interface{} + b interface{} + expect interface{} + }{ + {0, 0, float64(1)}, + {2, 0, float64(1)}, + {2, 3, float64(8)}, + {-2, 3, float64(-8)}, + {2, -3, float64(0.125)}, + {-2, -3, float64(-0.125)}, + {0.2, 3, float64(0.008)}, + {2, 0.3, float64(1.2311)}, + {0.2, 0.3, float64(0.617)}, + {"aaa", "3", false}, + {"2", "aaa", false}, + } { + + result, err := ns.Pow(test.a, test.b) + + if b, ok := test.expect.(bool); ok && !b { + c.Assert(err, qt.Not(qt.IsNil)) + continue + } + + // we compare only 4 digits behind point if its a real float + // otherwise we usually get different float values on the last positions + result = float64(int(result*10000)) / 10000 + + c.Assert(err, qt.IsNil) + c.Assert(result, qt.Equals, test.expect) + } +} |