funcs_math.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. // Copyright 2022-2023 EMQ Technologies Co., Ltd.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package function
  15. import (
  16. "fmt"
  17. "github.com/lf-edge/ekuiper/pkg/api"
  18. "github.com/lf-edge/ekuiper/pkg/ast"
  19. "github.com/lf-edge/ekuiper/pkg/cast"
  20. "math"
  21. "math/rand"
  22. )
  23. func registerMathFunc() {
  24. builtins["abs"] = builtinFunc{
  25. fType: ast.FuncTypeScalar,
  26. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  27. switch v := args[0].(type) {
  28. case int:
  29. return int(math.Abs(float64(v))), true
  30. case int64:
  31. return int64(math.Abs(float64(v))), true
  32. case float64:
  33. return math.Abs(v), true
  34. default:
  35. if vi, err := cast.ToInt(v, cast.STRICT); err == nil {
  36. return int(math.Abs(float64(vi))), true
  37. }
  38. if vf, err := cast.ToFloat64(v, cast.STRICT); err == nil {
  39. return math.Abs(vf), true
  40. }
  41. return fmt.Errorf("only float64 & int type are supported"), false
  42. }
  43. },
  44. val: ValidateOneNumberArg,
  45. }
  46. builtins["acos"] = builtinFunc{
  47. fType: ast.FuncTypeScalar,
  48. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  49. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  50. return math.Acos(v), true
  51. } else {
  52. return e, false
  53. }
  54. },
  55. val: ValidateOneNumberArg,
  56. }
  57. builtins["asin"] = builtinFunc{
  58. fType: ast.FuncTypeScalar,
  59. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  60. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  61. return math.Asin(v), true
  62. } else {
  63. return e, false
  64. }
  65. },
  66. val: ValidateOneNumberArg,
  67. }
  68. builtins["atan"] = builtinFunc{
  69. fType: ast.FuncTypeScalar,
  70. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  71. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  72. return math.Atan(v), true
  73. } else {
  74. return e, false
  75. }
  76. },
  77. val: ValidateOneNumberArg,
  78. }
  79. builtins["atan2"] = builtinFunc{
  80. fType: ast.FuncTypeScalar,
  81. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  82. if v1, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  83. if v2, e1 := cast.ToFloat64(args[1], cast.CONVERT_SAMEKIND); e1 == nil {
  84. return math.Atan2(v1, v2), true
  85. } else {
  86. return e1, false
  87. }
  88. } else {
  89. return e, false
  90. }
  91. },
  92. val: ValidateTwoNumberArg,
  93. }
  94. builtins["bitand"] = builtinFunc{
  95. fType: ast.FuncTypeScalar,
  96. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  97. v1, err := cast.ToInt(args[0], cast.STRICT)
  98. if err != nil {
  99. return fmt.Errorf("Expect int type for the first operand but got %v", args[0]), false
  100. }
  101. v2, err := cast.ToInt(args[0], cast.STRICT)
  102. if err != nil {
  103. return fmt.Errorf("Expect int type for the second operand but got %v", args[1]), false
  104. }
  105. return v1 & v2, true
  106. },
  107. val: ValidateTwoIntArg,
  108. }
  109. builtins["bitor"] = builtinFunc{
  110. fType: ast.FuncTypeScalar,
  111. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  112. v1, err := cast.ToInt(args[0], cast.STRICT)
  113. if err != nil {
  114. return fmt.Errorf("Expect int type for the first operand but got %v", args[0]), false
  115. }
  116. v2, err := cast.ToInt(args[0], cast.STRICT)
  117. if err != nil {
  118. return fmt.Errorf("Expect int type for the second operand but got %v", args[1]), false
  119. }
  120. return v1 | v2, true
  121. },
  122. val: ValidateTwoIntArg,
  123. }
  124. builtins["bitxor"] = builtinFunc{
  125. fType: ast.FuncTypeScalar,
  126. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  127. v1, err := cast.ToInt(args[0], cast.STRICT)
  128. if err != nil {
  129. return fmt.Errorf("Expect int type for the first operand but got %v", args[0]), false
  130. }
  131. v2, err := cast.ToInt(args[0], cast.STRICT)
  132. if err != nil {
  133. return fmt.Errorf("Expect int type for the second operand but got %v", args[1]), false
  134. }
  135. return v1 ^ v2, true
  136. },
  137. val: ValidateTwoIntArg,
  138. }
  139. builtins["bitnot"] = builtinFunc{
  140. fType: ast.FuncTypeScalar,
  141. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  142. v1, err := cast.ToInt(args[0], cast.STRICT)
  143. if err != nil {
  144. return fmt.Errorf("Expect int type for operand but got %v", args[0]), false
  145. }
  146. return ^v1, true
  147. },
  148. val: func(_ api.FunctionContext, args []ast.Expr) error {
  149. if err := ValidateLen(1, len(args)); err != nil {
  150. return err
  151. }
  152. if ast.IsFloatArg(args[0]) || ast.IsStringArg(args[0]) || ast.IsTimeArg(args[0]) || ast.IsBooleanArg(args[0]) {
  153. return ProduceErrInfo(0, "int")
  154. }
  155. return nil
  156. },
  157. }
  158. builtins["ceil"] = builtinFunc{
  159. fType: ast.FuncTypeScalar,
  160. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  161. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  162. return math.Ceil(v), true
  163. } else {
  164. return e, false
  165. }
  166. },
  167. val: ValidateOneNumberArg,
  168. }
  169. builtins["cos"] = builtinFunc{
  170. fType: ast.FuncTypeScalar,
  171. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  172. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  173. return math.Cos(v), true
  174. } else {
  175. return e, false
  176. }
  177. },
  178. val: ValidateOneNumberArg,
  179. }
  180. builtins["cosh"] = builtinFunc{
  181. fType: ast.FuncTypeScalar,
  182. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  183. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  184. return math.Cosh(v), true
  185. } else {
  186. return e, false
  187. }
  188. },
  189. val: ValidateOneNumberArg,
  190. }
  191. builtins["exp"] = builtinFunc{
  192. fType: ast.FuncTypeScalar,
  193. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  194. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  195. return math.Exp(v), true
  196. } else {
  197. return e, false
  198. }
  199. },
  200. val: ValidateOneNumberArg,
  201. }
  202. builtins["ln"] = builtinFunc{
  203. fType: ast.FuncTypeScalar,
  204. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  205. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  206. return math.Log2(v), true
  207. } else {
  208. return e, false
  209. }
  210. },
  211. val: ValidateOneNumberArg,
  212. }
  213. builtins["log"] = builtinFunc{
  214. fType: ast.FuncTypeScalar,
  215. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  216. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  217. return math.Log10(v), true
  218. } else {
  219. return e, false
  220. }
  221. },
  222. val: ValidateOneNumberArg,
  223. }
  224. builtins["mod"] = builtinFunc{
  225. fType: ast.FuncTypeScalar,
  226. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  227. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  228. if v1, e1 := cast.ToFloat64(args[1], cast.CONVERT_SAMEKIND); e == nil {
  229. return math.Mod(v, v1), true
  230. } else {
  231. return e1, false
  232. }
  233. } else {
  234. return e, false
  235. }
  236. },
  237. val: ValidateTwoNumberArg,
  238. }
  239. builtins["power"] = builtinFunc{
  240. fType: ast.FuncTypeScalar,
  241. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  242. if v1, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  243. if v2, e2 := cast.ToFloat64(args[1], cast.CONVERT_SAMEKIND); e2 == nil {
  244. return math.Pow(v1, v2), true
  245. } else {
  246. return e2, false
  247. }
  248. } else {
  249. return e, false
  250. }
  251. },
  252. val: ValidateTwoNumberArg,
  253. }
  254. builtins["rand"] = builtinFunc{
  255. fType: ast.FuncTypeScalar,
  256. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  257. return rand.Float64(), true
  258. },
  259. val: ValidateOneArg,
  260. }
  261. builtins["round"] = builtinFunc{
  262. fType: ast.FuncTypeScalar,
  263. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  264. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  265. return math.Round(v), true
  266. } else {
  267. return e, false
  268. }
  269. },
  270. val: ValidateOneNumberArg,
  271. }
  272. builtins["sign"] = builtinFunc{
  273. fType: ast.FuncTypeScalar,
  274. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  275. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  276. if v > 0 {
  277. return 1, true
  278. } else if v < 0 {
  279. return -1, true
  280. } else {
  281. return 0, true
  282. }
  283. } else {
  284. return e, false
  285. }
  286. },
  287. val: ValidateOneNumberArg,
  288. }
  289. builtins["sin"] = builtinFunc{
  290. fType: ast.FuncTypeScalar,
  291. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  292. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  293. return math.Sin(v), true
  294. } else {
  295. return e, false
  296. }
  297. },
  298. val: ValidateOneNumberArg,
  299. }
  300. builtins["sinh"] = builtinFunc{
  301. fType: ast.FuncTypeScalar,
  302. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  303. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  304. return math.Sinh(v), true
  305. } else {
  306. return e, false
  307. }
  308. },
  309. val: ValidateOneNumberArg,
  310. }
  311. builtins["sqrt"] = builtinFunc{
  312. fType: ast.FuncTypeScalar,
  313. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  314. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  315. return math.Sqrt(v), true
  316. } else {
  317. return e, false
  318. }
  319. },
  320. val: ValidateOneNumberArg,
  321. }
  322. builtins["tan"] = builtinFunc{
  323. fType: ast.FuncTypeScalar,
  324. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  325. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  326. return math.Tan(v), true
  327. } else {
  328. return e, false
  329. }
  330. },
  331. val: ValidateOneNumberArg,
  332. }
  333. builtins["tanh"] = builtinFunc{
  334. fType: ast.FuncTypeScalar,
  335. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  336. if v, e := cast.ToFloat64(args[0], cast.CONVERT_SAMEKIND); e == nil {
  337. return math.Tanh(v), true
  338. } else {
  339. return e, false
  340. }
  341. },
  342. val: ValidateOneNumberArg,
  343. }
  344. }