mirror of
https://github.com/chaisql/chai.git
synced 2025-10-08 09:00:08 +08:00
Add more math functions (#421)
* Add math.acos and math.abs * Add acosh, asin, asinh, atan and atan2 * Test for proper function documentation * Cast to double on math functions * Use the new types.Value interface
This commit is contained in:

committed by
GitHub

parent
edadca5086
commit
1659ae24e5
@@ -3,6 +3,7 @@ package functions
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/genjidb/genji/document"
|
||||
"github.com/genjidb/genji/internal/stringutil"
|
||||
"github.com/genjidb/genji/types"
|
||||
)
|
||||
@@ -13,10 +14,17 @@ func MathFunctions() Definitions {
|
||||
}
|
||||
|
||||
var mathFunctions = Definitions{
|
||||
"floor": floorFunc,
|
||||
"floor": floor,
|
||||
"abs": abs,
|
||||
"acos": acos,
|
||||
"acosh": acosh,
|
||||
"asin": asin,
|
||||
"asinh": asinh,
|
||||
"atan": atan,
|
||||
"atan2": atan2,
|
||||
}
|
||||
|
||||
var floorFunc = &ScalarDefinition{
|
||||
var floor = &ScalarDefinition{
|
||||
name: "floor",
|
||||
arity: 1,
|
||||
callFn: func(args ...types.Value) (types.Value, error) {
|
||||
@@ -30,3 +38,129 @@ var floorFunc = &ScalarDefinition{
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var abs = &ScalarDefinition{
|
||||
name: "abs",
|
||||
arity: 1,
|
||||
callFn: func(args ...types.Value) (types.Value, error) {
|
||||
if args[0].Type() == types.NullValue {
|
||||
return types.NewNullValue(), nil
|
||||
}
|
||||
v, err := document.CastAs(args[0], types.DoubleValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := math.Abs(v.V().(float64))
|
||||
if args[0].Type() == types.IntegerValue {
|
||||
return document.CastAs(types.NewDoubleValue(res), types.IntegerValue)
|
||||
}
|
||||
return types.NewDoubleValue(res), nil
|
||||
},
|
||||
}
|
||||
|
||||
var acos = &ScalarDefinition{
|
||||
name: "acos",
|
||||
arity: 1,
|
||||
callFn: func(args ...types.Value) (types.Value, error) {
|
||||
if args[0].Type() == types.NullValue {
|
||||
return types.NewNullValue(), nil
|
||||
}
|
||||
v, err := document.CastAs(args[0], types.DoubleValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vv := v.V().(float64)
|
||||
if vv > 1.0 || vv < -1.0 {
|
||||
return nil, stringutil.Errorf("out of range, acos(arg1) expects arg1 to be within [-1, 1]")
|
||||
}
|
||||
res := math.Acos(vv)
|
||||
return types.NewDoubleValue(res), nil
|
||||
},
|
||||
}
|
||||
|
||||
var acosh = &ScalarDefinition{
|
||||
name: "acosh",
|
||||
arity: 1,
|
||||
callFn: func(args ...types.Value) (types.Value, error) {
|
||||
if args[0].Type() == types.NullValue {
|
||||
return types.NewNullValue(), nil
|
||||
}
|
||||
v, err := document.CastAs(args[0], types.DoubleValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vv := v.V().(float64)
|
||||
if vv < 1.0 {
|
||||
return nil, stringutil.Errorf("out of range, acosh(arg1) expects arg1 >= 1")
|
||||
}
|
||||
res := math.Acosh(vv)
|
||||
return types.NewDoubleValue(res), nil
|
||||
},
|
||||
}
|
||||
|
||||
var asin = &ScalarDefinition{
|
||||
name: "asin",
|
||||
arity: 1,
|
||||
callFn: func(args ...types.Value) (types.Value, error) {
|
||||
if args[0].Type() == types.NullValue {
|
||||
return types.NewNullValue(), nil
|
||||
}
|
||||
v, err := document.CastAs(args[0], types.DoubleValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vv := v.V().(float64)
|
||||
if vv > 1.0 || vv < -1.0 {
|
||||
return nil, stringutil.Errorf("out of range, asin(arg1) expects arg1 to be within [-1, 1]")
|
||||
}
|
||||
res := math.Asin(vv)
|
||||
return types.NewDoubleValue(res), nil
|
||||
},
|
||||
}
|
||||
|
||||
var asinh = &ScalarDefinition{
|
||||
name: "asinh",
|
||||
arity: 1,
|
||||
callFn: func(args ...types.Value) (types.Value, error) {
|
||||
v, err := document.CastAs(args[0], types.DoubleValue)
|
||||
if err != nil || v.Type() == types.NullValue {
|
||||
return v, err
|
||||
}
|
||||
vv := v.V().(float64)
|
||||
res := math.Asinh(vv)
|
||||
return types.NewDoubleValue(res), nil
|
||||
},
|
||||
}
|
||||
|
||||
var atan = &ScalarDefinition{
|
||||
name: "atan",
|
||||
arity: 1,
|
||||
callFn: func(args ...types.Value) (types.Value, error) {
|
||||
v, err := document.CastAs(args[0], types.DoubleValue)
|
||||
if err != nil || v.Type() == types.NullValue {
|
||||
return v, err
|
||||
}
|
||||
vv := v.V().(float64)
|
||||
res := math.Atan(vv)
|
||||
return types.NewDoubleValue(res), nil
|
||||
},
|
||||
}
|
||||
|
||||
var atan2 = &ScalarDefinition{
|
||||
name: "atan2",
|
||||
arity: 2,
|
||||
callFn: func(args ...types.Value) (types.Value, error) {
|
||||
vA, err := document.CastAs(args[0], types.DoubleValue)
|
||||
if err != nil || vA.Type() == types.NullValue {
|
||||
return vA, err
|
||||
}
|
||||
vvA := vA.V().(float64)
|
||||
vB, err := document.CastAs(args[1], types.DoubleValue)
|
||||
if err != nil || vB.Type() == types.NullValue {
|
||||
return vB, err
|
||||
}
|
||||
vvB := vB.V().(float64)
|
||||
res := math.Atan2(vvA, vvB)
|
||||
return types.NewDoubleValue(res), nil
|
||||
},
|
||||
}
|
||||
|
Reference in New Issue
Block a user