diff --git a/builtin/builtin.go b/builtin/builtin.go index 87e73614a..21aac40ca 100644 --- a/builtin/builtin.go +++ b/builtin/builtin.go @@ -141,6 +141,13 @@ var Builtins = []*Function{ return anyType, fmt.Errorf("invalid argument for abs (type %s)", args[0]) }, }, + { + Name: "log2", + Fast: Log2, + Validate: func(args []reflect.Type) (reflect.Type, error) { + return validateRoundFunc("log2", args) + }, + }, { Name: "ceil", Fast: Ceil, diff --git a/builtin/builtin_test.go b/builtin/builtin_test.go index 0d0dec357..ec7085a41 100644 --- a/builtin/builtin_test.go +++ b/builtin/builtin_test.go @@ -46,6 +46,8 @@ func TestBuiltin(t *testing.T) { {`abs(-5)`, 5}, {`abs(.5)`, .5}, {`abs(-.5)`, .5}, + {`log2(8)`, 3.0}, + {`log2(0.5)`, -1.0}, {`ceil(5.5)`, 6.0}, {`ceil(5)`, 5.0}, {`floor(5.5)`, 5.0}, @@ -253,6 +255,8 @@ func TestBuiltin_errors(t *testing.T) { {`abs()`, `invalid number of arguments (expected 1, got 0)`}, {`abs(1, 2)`, `invalid number of arguments (expected 1, got 2)`}, {`abs("foo")`, `invalid argument for abs (type string)`}, + {`log2()`, `invalid number of arguments (expected 1, got 0)`}, + {`log2("foo")`, `invalid argument for log2 (type string)`}, {`int()`, `invalid number of arguments (expected 1, got 0)`}, {`int(1, 2)`, `invalid number of arguments (expected 1, got 2)`}, {`float()`, `invalid number of arguments (expected 1, got 0)`}, diff --git a/builtin/lib.go b/builtin/lib.go index 61748da08..3441d33b3 100644 --- a/builtin/lib.go +++ b/builtin/lib.go @@ -115,6 +115,10 @@ func Abs(x any) any { panic(fmt.Sprintf("invalid argument for abs (type %T)", x)) } +func Log2(x any) any { + return math.Log2(Float(x).(float64)) +} + func Ceil(x any) any { switch x := x.(type) { case float32: diff --git a/docs/language-definition.md b/docs/language-definition.md index 69efbdfa9..b77d9b193 100644 --- a/docs/language-definition.md +++ b/docs/language-definition.md @@ -580,6 +580,14 @@ Returns the absolute value of a number. abs(-5) == 5 ``` +### log2(n) {#log2} + +Returns the binary logarithm of a number. + +```expr +log2(8) == 3.0 +``` + ### ceil(n) {#ceil} Returns the least integer value greater than or equal to x.