diff --git a/docs/changes.md b/docs/changes.md index 9b21ed2551..728e53dbf6 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -1,5 +1,8 @@ # 最新动态 +2023/12/05 + * 完善fscript部分数学函数。 + 2023/12/04 * 完善combobox的options,如果选项第一个字符不是数字,里面存在':',也不视为分隔符。比如http://localhost视为一个整体。 * 增加函数tk\_levelize。fscript增加levelize函数。 diff --git a/src/tkc/fscript.c b/src/tkc/fscript.c index 2d787accc8..e7ab7ba9c7 100644 --- a/src/tkc/fscript.c +++ b/src/tkc/fscript.c @@ -2832,64 +2832,103 @@ static ret_t func_assert(fscript_t* fscript, fscript_args_t* args, value_t* resu } static ret_t func_min(fscript_t* fscript, fscript_args_t* args, value_t* result) { - double v1 = 0; - double v2 = 0; FSCRIPT_FUNC_CHECK(args->size == 2, RET_BAD_PARAMS); - v1 = value_double(args->args); - v2 = value_double(args->args + 1); - value_set_double(result, tk_min(v1, v2)); + if (value_double(args->args) < value_double(args->args + 1)) { + value_deep_copy(result, args->args); + } else { + value_deep_copy(result, args->args + 1); + } return RET_OK; } static ret_t func_max(fscript_t* fscript, fscript_args_t* args, value_t* result) { - double v1 = 0; - double v2 = 0; FSCRIPT_FUNC_CHECK(args->size == 2, RET_BAD_PARAMS); - v1 = value_double(args->args); - v2 = value_double(args->args + 1); - value_set_double(result, tk_max(v1, v2)); + if (value_double(args->args) > value_double(args->args + 1)) { + value_deep_copy(result, args->args); + } else { + value_deep_copy(result, args->args + 1); + } return RET_OK; } static ret_t func_clamp(fscript_t* fscript, fscript_args_t* args, value_t* result) { - double v1 = 0; - double v2 = 0; - double v3 = 0; FSCRIPT_FUNC_CHECK(args->size == 3, RET_BAD_PARAMS); - v1 = value_double(args->args); - v2 = value_double(args->args + 1); - v3 = value_double(args->args + 2); - value_set_double(result, tk_clamp(v1, v2, v3)); + if (value_double(args->args) < value_double(args->args + 1)) { + value_deep_copy(result, args->args + 1); + } else if (value_double(args->args) > value_double(args->args + 2)) { + value_deep_copy(result, args->args + 2); + } else { + value_deep_copy(result, args->args); + } return RET_OK; } static ret_t func_round(fscript_t* fscript, fscript_args_t* args, value_t* result) { FSCRIPT_FUNC_CHECK(args->size == 1, RET_BAD_PARAMS); - value_set_double(result, tk_roundi(value_double(args->args))); + value_set_int64(result, round(value_double(args->args))); return RET_OK; } static ret_t func_floor(fscript_t* fscript, fscript_args_t* args, value_t* result) { FSCRIPT_FUNC_CHECK(args->size == 1, RET_BAD_PARAMS); - value_set_double(result, floor(value_double(args->args))); + value_set_int64(result, floor(value_double(args->args))); return RET_OK; } static ret_t func_ceil(fscript_t* fscript, fscript_args_t* args, value_t* result) { FSCRIPT_FUNC_CHECK(args->size == 1, RET_BAD_PARAMS); - value_set_double(result, ceil(value_double(args->args))); + value_set_int64(result, ceil(value_double(args->args))); return RET_OK; } static ret_t func_abs(fscript_t* fscript, fscript_args_t* args, value_t* result) { + value_t* v = NULL; FSCRIPT_FUNC_CHECK(args->size == 1, RET_BAD_PARAMS); - value_set_double(result, tk_abs(value_double(args->args))); + v = args->args; + switch (v->type) { + case VALUE_TYPE_INT8: { + value_set_int8(result, tk_abs(value_int8(v))); + break; + } + case VALUE_TYPE_UINT8: { + value_set_uint8(result, tk_abs(value_uint8(v))); + break; + } + case VALUE_TYPE_INT16: { + value_set_int16(result, tk_abs(value_int16(v))); + break; + } + case VALUE_TYPE_UINT16: { + value_set_uint16(result, tk_abs(value_uint16(v))); + break; + } + case VALUE_TYPE_INT32: { + value_set_int(result, tk_abs(value_int(v))); + break; + } + case VALUE_TYPE_UINT32: { + value_set_uint32(result, tk_abs(value_uint32(v))); + break; + } + case VALUE_TYPE_INT64: { + value_set_int64(result, tk_abs(value_int64(v))); + break; + } + case VALUE_TYPE_UINT64: { + value_set_uint64(result, tk_abs(value_uint64(v))); + break; + } + default: { + value_set_double(result, tk_abs(value_double(v))); + break; + } + } return RET_OK; } diff --git a/tests/fscript_test.cc b/tests/fscript_test.cc index 3018b0da9b..1d5e6636fd 100644 --- a/tests/fscript_test.cc +++ b/tests/fscript_test.cc @@ -3249,3 +3249,185 @@ TEST(FScript, levelize) { TK_OBJECT_UNREF(obj); } +TEST(FExr, min) { + value_t v; + tk_object_t* obj = object_default_create(); + + fscript_eval(obj, "min(1, 2)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT32); + ASSERT_EQ(value_int32(&v), 1); + + fscript_eval(obj, "min(1, 2.1)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT32); + ASSERT_EQ(value_int32(&v), 1); + + fscript_eval(obj, "min(i8(1), 2.1)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT8); + ASSERT_EQ(value_int32(&v), 1); + + fscript_eval(obj, "min(1.0, 2)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_DOUBLE); + ASSERT_EQ(value_int32(&v), 1); + + value_reset(&v); + + TK_OBJECT_UNREF(obj); +} + +TEST(FExr, max) { + value_t v; + tk_object_t* obj = object_default_create(); + + fscript_eval(obj, "max(1, 0)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT32); + ASSERT_EQ(value_int32(&v), 1); + + fscript_eval(obj, "max(1, 0.1)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT32); + ASSERT_EQ(value_int32(&v), 1); + + fscript_eval(obj, "max(i8(1), 0.1)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT8); + ASSERT_EQ(value_int32(&v), 1); + + fscript_eval(obj, "max(1.0, 0.2)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_DOUBLE); + ASSERT_EQ(value_int32(&v), 1); + + value_reset(&v); + + TK_OBJECT_UNREF(obj); +} + +TEST(FExr, clamp) { + value_t v; + tk_object_t* obj = object_default_create(); + + fscript_eval(obj, "clamp(1, 2, 5.0)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT32); + ASSERT_EQ(value_int32(&v), 2); + + fscript_eval(obj, "clamp(1, 0.1, 5)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT32); + ASSERT_EQ(value_int32(&v), 1); + + fscript_eval(obj, "clamp(i8(1), 0.1, 6)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT8); + ASSERT_EQ(value_int32(&v), 1); + + fscript_eval(obj, "clamp(1.0, 0.1, 10)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_DOUBLE); + ASSERT_EQ(value_int32(&v), 1); + + fscript_eval(obj, "clamp(1, i8(3), 6)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT8); + ASSERT_EQ(value_int32(&v), 3); + + fscript_eval(obj, "clamp(10, i8(3), i8(6))", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT8); + ASSERT_EQ(value_int32(&v), 6); + + fscript_eval(obj, "clamp(10, i8(3), 6.0)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_DOUBLE); + ASSERT_EQ(value_int32(&v), 6); + + value_reset(&v); + + TK_OBJECT_UNREF(obj); +} + +TEST(FExr, round) { + value_t v; + tk_object_t* obj = object_default_create(); + + fscript_eval(obj, "round(1)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT64); + ASSERT_EQ(value_int32(&v), 1); + value_reset(&v); + + fscript_eval(obj, "round(1.2)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT64); + ASSERT_EQ(value_int32(&v), 1); + + fscript_eval(obj, "round(1.5)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT64); + ASSERT_EQ(value_int32(&v), 2); + value_reset(&v); + + TK_OBJECT_UNREF(obj); +} + +TEST(FExr, floor) { + value_t v; + tk_object_t* obj = object_default_create(); + + fscript_eval(obj, "floor(1)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT64); + ASSERT_EQ(value_int32(&v), 1); + value_reset(&v); + + fscript_eval(obj, "floor(1.2)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT64); + ASSERT_EQ(value_int32(&v), 1); + + fscript_eval(obj, "floor(1.5)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT64); + ASSERT_EQ(value_int32(&v), 1); + value_reset(&v); + + TK_OBJECT_UNREF(obj); +} + +TEST(FExr, ceil) { + value_t v; + tk_object_t* obj = object_default_create(); + + fscript_eval(obj, "ceil(1)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT64); + ASSERT_EQ(value_int32(&v), 1); + value_reset(&v); + + fscript_eval(obj, "ceil(1.2)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT64); + ASSERT_EQ(value_int32(&v), 2); + + fscript_eval(obj, "ceil(1.5)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT64); + ASSERT_EQ(value_int32(&v), 2); + value_reset(&v); + + TK_OBJECT_UNREF(obj); +} + +TEST(FExr, abs) { + value_t v; + tk_object_t* obj = object_default_create(); + + fscript_eval(obj, "abs(1)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT32); + ASSERT_EQ(value_int32(&v), 1); + value_reset(&v); + + fscript_eval(obj, "abs(1.0)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_DOUBLE); + ASSERT_EQ(value_int32(&v), 1); + value_reset(&v); + + fscript_eval(obj, "abs(i8(-1))", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT8); + ASSERT_EQ(value_int32(&v), 1); + value_reset(&v); + + fscript_eval(obj, "abs(-1)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_INT32); + ASSERT_EQ(value_int32(&v), 1); + value_reset(&v); + + fscript_eval(obj, "abs(-1.0)", &v); + ASSERT_EQ(v.type, VALUE_TYPE_DOUBLE); + ASSERT_EQ(value_int32(&v), 1); + value_reset(&v); + + TK_OBJECT_UNREF(obj); +} +