Skip to content

Commit ad76382

Browse files
authored
Sqrt func (#1166)
* Adding math square root function * Adding info to readme on math square root function * Handle overload error and test NaN * adding version 2
1 parent 9ed72dd commit ad76382

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

ext/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,23 @@ Examples:
356356
math.isFinite(0.0/0.0) // returns false
357357
math.isFinite(1.2) // returns true
358358

359+
### Math.Sqrt
360+
361+
Introduced at version: 2
362+
363+
Returns the square root of the given input as double
364+
Throws error for negative or non-numeric inputs
365+
366+
math.sqrt(<double>) -> <double>
367+
math.sqrt(<int>) -> <double>
368+
math.sqrt(<uint>) -> <double>
369+
370+
Examples:
371+
372+
math.sqrt(81) // returns 9.0
373+
math.sqrt(985.25) // returns 31.388692231439016
374+
math.sqrt(-15) // returns NaN
375+
359376
## Protos
360377

361378
Protos configure extended macros and functions for proto manipulation.

ext/math.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,23 @@ import (
325325
//
326326
// math.isFinite(0.0/0.0) // returns false
327327
// math.isFinite(1.2) // returns true
328+
//
329+
// # Math.Sqrt
330+
//
331+
// Introduced at version: 2
332+
//
333+
// Returns the square root of the given input as double
334+
// Throws error for negative or non-numeric inputs
335+
//
336+
// math.sqrt(<double>) -> <double>
337+
// math.sqrt(<int>) -> <double>
338+
// math.sqrt(<uint>) -> <double>
339+
//
340+
// Examples:
341+
//
342+
// math.sqrt(81) // returns 9.0
343+
// math.sqrt(985.25) // returns 31.388692231439016
344+
// math.sqrt(-15) // returns NaN
328345
func Math(options ...MathOption) cel.EnvOption {
329346
m := &mathLib{version: math.MaxUint32}
330347
for _, o := range options {
@@ -357,6 +374,9 @@ const (
357374
absFunc = "math.abs"
358375
signFunc = "math.sign"
359376

377+
// SquareRoot function
378+
sqrtFunc = "math.sqrt"
379+
360380
// Bitwise functions
361381
bitAndFunc = "math.bitAnd"
362382
bitOrFunc = "math.bitOr"
@@ -548,6 +568,18 @@ func (lib *mathLib) CompileOptions() []cel.EnvOption {
548568
),
549569
)
550570
}
571+
if lib.version >= 2 {
572+
opts = append(opts,
573+
cel.Function(sqrtFunc,
574+
cel.Overload("math_sqrt_double", []*cel.Type{cel.DoubleType}, cel.DoubleType,
575+
cel.UnaryBinding(sqrt)),
576+
cel.Overload("math_sqrt_int", []*cel.Type{cel.IntType}, cel.DoubleType,
577+
cel.UnaryBinding(sqrt)),
578+
cel.Overload("math_sqrt_uint", []*cel.Type{cel.UintType}, cel.DoubleType,
579+
cel.UnaryBinding(sqrt)),
580+
),
581+
)
582+
}
551583
return opts
552584
}
553585

@@ -691,6 +723,21 @@ func sign(val ref.Val) ref.Val {
691723
}
692724
}
693725

726+
727+
func sqrt(val ref.Val) ref.Val {
728+
switch v := val.(type) {
729+
case types.Double:
730+
return types.Double(math.Sqrt(float64(v)))
731+
case types.Int:
732+
return types.Double(math.Sqrt(float64(v)))
733+
case types.Uint:
734+
return types.Double(math.Sqrt(float64(v)))
735+
default:
736+
return types.NewErr("no such overload: sqrt")
737+
}
738+
}
739+
740+
694741
func bitAndPairInt(first, second ref.Val) ref.Val {
695742
l := first.(types.Int)
696743
r := second.(types.Int)

ext/math_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,15 @@ func TestMath(t *testing.T) {
181181
{expr: "math.abs(1) == 1"},
182182
{expr: "math.abs(-234.5) == 234.5"},
183183
{expr: "math.abs(234.5) == 234.5"},
184+
185+
// Tests for Square root function
186+
{expr: "math.sqrt(49.0) == 7.0"},
187+
{expr: "math.sqrt(0) == 0.0"},
188+
{expr: "math.sqrt(1) == 1.0"},
189+
{expr: "math.sqrt(25u) == 5.0"},
190+
{expr: "math.sqrt(82) == 9.055385138137417"},
191+
{expr: "math.sqrt(985.25) == 31.388692231439016"},
192+
{expr: "math.isNaN(math.sqrt(-15.34))"},
184193
}
185194

186195
env := testMathEnv(t,
@@ -472,6 +481,10 @@ func TestMathRuntimeErrors(t *testing.T) {
472481
expr: "math.trunc(dyn(1u))",
473482
err: "no such overload: math.trunc(uint)",
474483
},
484+
{
485+
expr: "math.sqrt(dyn(''))",
486+
err: "no such overload: math.sqrt(string)",
487+
},
475488
}
476489

477490
env := testMathEnv(t,
@@ -599,6 +612,12 @@ func TestMathVersions(t *testing.T) {
599612
"bitShiftRight": `math.bitShiftRight(4, 2) == 1`,
600613
},
601614
},
615+
{
616+
version: 2,
617+
supportedFunctions: map[string]string{
618+
"sqrt": `math.sqrt(25) == 5.0`,
619+
},
620+
},
602621
}
603622
for _, lib := range versionCases {
604623
env, err := cel.NewEnv(Math(MathVersion(lib.version)))

0 commit comments

Comments
 (0)