ref: d184e5059c72c15df055192b01da0fd8c5b0fc5c
parent: 322c285ba2f3aa95826fe2135646b4d35f4d2a30
author: Chris Dennis <ssa@fbcs.co.uk>
date: Mon Feb 24 17:45:04 EST 2020
tpl: Add math.Sqrt Fixes #6941
--- a/docs/content/en/functions/math.md
+++ b/docs/content/en/functions/math.md
@@ -4,7 +4,7 @@
godocref:
date: 2017-02-01
publishdate: 2017-02-01
-lastmod: 2017-02-01
+lastmod: 2020-02-23
keywords: [math, operators]
categories: [functions]
menu:
@@ -36,3 +36,6 @@
| `math.Ceil` | Returns the least integer value greater than or equal to the given number. | `{{math.Ceil 2.1}}` → `3` |
| `math.Floor` | Returns the greatest integer value less than or equal to the given number. | `{{math.Floor 1.9}}` → `1` |
| `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` |
+
--- a/tpl/math/init.go
+++ b/tpl/math/init.go
@@ -64,6 +64,13 @@
},
)
+ ns.AddMethodMapping(ctx.Sqrt,
+ nil,
+ [][2]string{
+ {"{{math.Sqrt 81}}", "9"},
+ },
+ )
+
ns.AddMethodMapping(ctx.Mod,
[]string{"mod"},
[][2]string{
--- a/tpl/math/math.go
+++ b/tpl/math/math.go
@@ -72,6 +72,18 @@
return math.Log(af), nil
}
+// Sqrt returns the square root of a number.
+// NOTE: will return for NaN for negative values of a
+func (ns *Namespace) Sqrt(a interface{}) (float64, error) {
+ af, err := cast.ToFloat64E(a)
+
+ if err != nil {
+ return 0, errors.New("Sqrt operator can't be used with non integer or float value")
+ }
+
+ return math.Sqrt(af), nil
+}
+
// Mod returns a % b.
func (ns *Namespace) Mod(a, b interface{}) (int64, error) {
ai, erra := cast.ToInt64E(a)
--- a/tpl/math/math_test.go
+++ b/tpl/math/math_test.go
@@ -153,6 +153,51 @@
c.Assert(err, qt.IsNil)
c.Assert(result, qt.Equals, test.expect)
}
+
+ // Separate test for Log(-1) -- returns NaN
+ result, err := ns.Log(-1)
+ c.Assert(err, qt.IsNil)
+ c.Assert(result, qt.Satisfies, math.IsNaN)
+}
+
+func TestSqrt(t *testing.T) {
+ t.Parallel()
+ c := qt.New(t)
+
+ ns := New()
+
+ for _, test := range []struct {
+ a interface{}
+ expect interface{}
+ }{
+ {81, float64(9)},
+ {0.25, float64(0.5)},
+ {0, float64(0)},
+ {"abc", false},
+ } {
+
+ result, err := ns.Sqrt(test.a)
+
+ 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
+ if result != math.Inf(-1) {
+ result = float64(int(result*10000)) / 10000
+ }
+
+ c.Assert(err, qt.IsNil)
+ c.Assert(result, qt.Equals, test.expect)
+ }
+
+ // Separate test for Sqrt(-1) -- returns NaN
+ result, err := ns.Sqrt(-1)
+ c.Assert(err, qt.IsNil)
+ c.Assert(result, qt.Satisfies, math.IsNaN)
+
}
func TestMod(t *testing.T) {