From 917dbff89d30ce93c0853b7fc5cb1f25c498b4b5 Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Fri, 13 Apr 2018 20:48:48 +0100 Subject: [PATCH] Add math.fixed function for truncating floats --- sql/funcs.go | 1 + util/fncs/args.go | 6 ++++++ util/fncs/fnc.go | 2 ++ util/fncs/math.go | 9 +++++++++ util/fncs/math_test.go | 9 +++++++++ 5 files changed, 27 insertions(+) diff --git a/sql/funcs.go b/sql/funcs.go index 5af8f608..e3ff9967 100644 --- a/sql/funcs.go +++ b/sql/funcs.go @@ -123,6 +123,7 @@ var funcs = map[string]map[int]interface{}{ "math.ceil": {1: nil}, "math.correlation": {2: nil}, "math.covariance": {2: nil}, + "math.fixed": {2: nil}, "math.floor": {1: nil}, "math.geometricmean": {1: nil}, "math.harmonicmean": {1: nil}, diff --git a/util/fncs/args.go b/util/fncs/args.go index 715a8afd..0bb1423d 100644 --- a/util/fncs/args.go +++ b/util/fncs/args.go @@ -36,6 +36,12 @@ func outputFloat(val float64) (interface{}, error) { } } +func outputFixed(val float64, pre int64) (interface{}, error) { + out := math.Pow(10, float64(pre)) + rnd := int(val*out + math.Copysign(0.5, val*out)) + return float64(rnd) / out, nil +} + func ensureString(val interface{}) (out string, ok bool) { switch val := val.(type) { case string: diff --git a/util/fncs/fnc.go b/util/fncs/fnc.go index 7c52dddb..7ac2500e 100644 --- a/util/fncs/fnc.go +++ b/util/fncs/fnc.go @@ -116,6 +116,8 @@ func Run(ctx context.Context, name string, args ...interface{}) (interface{}, er return mathCorrelation(ctx, args...) case "math.covariance": return mathCovariance(ctx, args...) + case "math.fixed": + return mathFixed(ctx, args...) case "math.floor": return mathFloor(ctx, args...) case "math.geometricmean": diff --git a/util/fncs/math.go b/util/fncs/math.go index 4a676181..50322f41 100644 --- a/util/fncs/math.go +++ b/util/fncs/math.go @@ -54,6 +54,15 @@ func mathCovariance(ctx context.Context, args ...interface{}) (out interface{}, return outputFloat(math.Covariance(a, b)) } +func mathFixed(ctx context.Context, args ...interface{}) (out interface{}, err error) { + if val, ok := ensureFloat(args[0]); ok { + if pre, ok := ensureInt(args[1]); ok { + return outputFixed(val, pre) + } + } + return +} + func mathFloor(ctx context.Context, args ...interface{}) (out interface{}, err error) { if val, ok := ensureFloat(args[0]); ok { return outputFloat(math.Floor(val)) diff --git a/util/fncs/math_test.go b/util/fncs/math_test.go index 9590c349..4f00e22a 100644 --- a/util/fncs/math_test.go +++ b/util/fncs/math_test.go @@ -80,6 +80,15 @@ func TestMath(t *testing.T) { So(res, ShouldEqual, -1) }) + Convey("math.fixed() works properly", t, func() { + res, _ = Run(context.Background(), "math.fixed", "test") + So(res, ShouldEqual, nil) + res, _ = Run(context.Background(), "math.fixed", 10, 2) + So(res, ShouldEqual, 10) + res, _ = Run(context.Background(), "math.fixed", 1.51837461, 2) + So(res, ShouldEqual, 1.52) + }) + Convey("math.floor() works properly", t, func() { res, _ = Run(context.Background(), "math.floor", "test") So(res, ShouldEqual, nil)