Add math.Max and math.Min

Closes #8583
This commit is contained in:
Joe Mooring
2021-05-27 08:34:49 -07:00
committed by Bjørn Erik Pedersen
parent 845a7ba4fc
commit 01758f99b9
4 changed files with 129 additions and 12 deletions

View File

@@ -64,10 +64,17 @@ func init() {
},
)
ns.AddMethodMapping(ctx.Sqrt,
ns.AddMethodMapping(ctx.Max,
nil,
[][2]string{
{"{{math.Sqrt 81}}", "9"},
{"{{math.Max 1 2 }}", "2"},
},
)
ns.AddMethodMapping(ctx.Min,
nil,
[][2]string{
{"{{math.Min 1 2 }}", "1"},
},
)
@@ -106,6 +113,13 @@ func init() {
},
)
ns.AddMethodMapping(ctx.Sqrt,
nil,
[][2]string{
{"{{math.Sqrt 81}}", "9"},
},
)
ns.AddMethodMapping(ctx.Sub,
[]string{"sub"},
[][2]string{

View File

@@ -71,15 +71,28 @@ func (ns *Namespace) Log(a interface{}) (float64, error) {
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")
// Max returns the greater of two numbers.
func (ns *Namespace) Max(a, b interface{}) (float64, error) {
af, erra := cast.ToFloat64E(a)
bf, errb := cast.ToFloat64E(b)
if erra != nil || errb != nil {
return 0, errors.New("Max operator can't be used with non-float value")
}
return math.Sqrt(af), nil
return math.Max(af, bf), nil
}
// Min returns the smaller of two numbers.
func (ns *Namespace) Min(a, b interface{}) (float64, error) {
af, erra := cast.ToFloat64E(a)
bf, errb := cast.ToFloat64E(b)
if erra != nil || errb != nil {
return 0, errors.New("Min operator can't be used with non-float value")
}
return math.Min(af, bf), nil
}
// Mod returns a % b.
@@ -135,6 +148,16 @@ func (ns *Namespace) Round(x interface{}) (float64, error) {
return _round(xf), nil
}
// Sqrt returns the square root of a number.
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
}
// Sub subtracts two numbers.
func (ns *Namespace) Sub(a, b interface{}) (interface{}, error) {
return _math.DoArithmetic(a, b, '-')

View File

@@ -357,3 +357,81 @@ func TestPow(t *testing.T) {
c.Assert(result, qt.Equals, test.expect)
}
}
func TestMax(t *testing.T) {
t.Parallel()
c := qt.New(t)
ns := New()
for _, test := range []struct {
a interface{}
b interface{}
expect interface{}
}{
{-1, -1, float64(-1)},
{-1, 0, float64(0)},
{-1, 1, float64(1)},
{0, -1, float64(0)},
{0, 0, float64(0)},
{0, 1, float64(1)},
{1, -1, float64(1)},
{1, 0, float64(1)},
{1, 1, float64(1)},
{1.2, 1.23, float64(1.23)},
{-1.2, -1.23, float64(-1.2)},
{0, "a", false},
{"a", 0, false},
{"a", "b", false},
} {
result, err := ns.Max(test.a, test.b)
if b, ok := test.expect.(bool); ok && !b {
c.Assert(err, qt.Not(qt.IsNil))
continue
}
c.Assert(err, qt.IsNil)
c.Assert(result, qt.Equals, test.expect)
}
}
func TestMin(t *testing.T) {
t.Parallel()
c := qt.New(t)
ns := New()
for _, test := range []struct {
a interface{}
b interface{}
expect interface{}
}{
{-1, -1, float64(-1)},
{-1, 0, float64(-1)},
{-1, 1, float64(-1)},
{0, -1, float64(-1)},
{0, 0, float64(0)},
{0, 1, float64(0)},
{1, -1, float64(-1)},
{1, 0, float64(0)},
{1, 1, float64(1)},
{1.2, 1.23, float64(1.2)},
{-1.2, -1.23, float64(-1.23)},
{0, "a", false},
{"a", 0, false},
{"a", "b", false},
} {
result, err := ns.Min(test.a, test.b)
if b, ok := test.expect.(bool); ok && !b {
c.Assert(err, qt.Not(qt.IsNil))
continue
}
c.Assert(err, qt.IsNil)
c.Assert(result, qt.Equals, test.expect)
}
}