14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/builtins/builtins_math.h"
174514f5e3Sopenharmony_ci#include <random>
184514f5e3Sopenharmony_ci#include <sys/time.h>
194514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value-inl.h"
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_cinamespace panda::ecmascript::builtins {
224514f5e3Sopenharmony_ciusing NumberHelper = base::NumberHelper;
234514f5e3Sopenharmony_ciusing RandomGenerator = base::RandomGenerator;
244514f5e3Sopenharmony_ci
254514f5e3Sopenharmony_ci// 20.2.2.1
264514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Abs(EcmaRuntimeCallInfo *argv)
274514f5e3Sopenharmony_ci{
284514f5e3Sopenharmony_ci    ASSERT(argv);
294514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Abs);
304514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
314514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
324514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
334514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
344514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
354514f5e3Sopenharmony_ci    if (numberValue.IsDouble()) {
364514f5e3Sopenharmony_ci        // if number_value is double,NaN,Undefine, deal in this case
374514f5e3Sopenharmony_ci        // if number_value is a String ,which can change to double. e.g."100",deal in this case
384514f5e3Sopenharmony_ci        return GetTaggedDouble(std::fabs(numberValue.GetDouble()));
394514f5e3Sopenharmony_ci    }
404514f5e3Sopenharmony_ci    // if number_value is int,boolean,null, deal in this case
414514f5e3Sopenharmony_ci    int value = numberValue.GetInt();
424514f5e3Sopenharmony_ci    if (value == INT_MIN) {
434514f5e3Sopenharmony_ci        return GetTaggedDouble(-static_cast<int64_t>(INT_MIN));
444514f5e3Sopenharmony_ci    }
454514f5e3Sopenharmony_ci    return GetTaggedInt(std::abs(value));
464514f5e3Sopenharmony_ci}
474514f5e3Sopenharmony_ci
484514f5e3Sopenharmony_ci// 20.2.2.2
494514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Acos(EcmaRuntimeCallInfo *argv)
504514f5e3Sopenharmony_ci{
514514f5e3Sopenharmony_ci    ASSERT(argv);
524514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Acos);
534514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
544514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
554514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
564514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
574514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
584514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
594514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
604514f5e3Sopenharmony_ci    // value == -NaN , <-1  or > 1,result is  NaN
614514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value)) && value <= 1 && value >= -1) {
624514f5e3Sopenharmony_ci        result = std::acos(value);
634514f5e3Sopenharmony_ci    }
644514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
654514f5e3Sopenharmony_ci}
664514f5e3Sopenharmony_ci
674514f5e3Sopenharmony_ci// 20.2.2.3
684514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Acosh(EcmaRuntimeCallInfo *argv)
694514f5e3Sopenharmony_ci{
704514f5e3Sopenharmony_ci    ASSERT(argv);
714514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Acosh);
724514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
734514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
744514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
754514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
764514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
774514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
784514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
794514f5e3Sopenharmony_ci    if (value >= 1) {
804514f5e3Sopenharmony_ci        result = std::acosh(value);
814514f5e3Sopenharmony_ci    }
824514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
834514f5e3Sopenharmony_ci}
844514f5e3Sopenharmony_ci
854514f5e3Sopenharmony_ci// 20.2.2.4
864514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Asin(EcmaRuntimeCallInfo *argv)
874514f5e3Sopenharmony_ci{
884514f5e3Sopenharmony_ci    ASSERT(argv);
894514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Asin);
904514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
914514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
924514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
934514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
944514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
954514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
964514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
974514f5e3Sopenharmony_ci    if (value >= -1 && value <= 1) {
984514f5e3Sopenharmony_ci        result = std::asin(value);
994514f5e3Sopenharmony_ci    }
1004514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
1014514f5e3Sopenharmony_ci}
1024514f5e3Sopenharmony_ci
1034514f5e3Sopenharmony_ci// 20.2.2.5
1044514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Asinh(EcmaRuntimeCallInfo *argv)
1054514f5e3Sopenharmony_ci{
1064514f5e3Sopenharmony_ci    ASSERT(argv);
1074514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Asinh);
1084514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1094514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1104514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
1114514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
1124514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1134514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
1144514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
1154514f5e3Sopenharmony_ci    // value == -NaN, NaN, result is  NaN
1164514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value))) {
1174514f5e3Sopenharmony_ci        result = base::MathHelper::Asinh(value);
1184514f5e3Sopenharmony_ci    }
1194514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
1204514f5e3Sopenharmony_ci}
1214514f5e3Sopenharmony_ci
1224514f5e3Sopenharmony_ci// 20.2.2.6
1234514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Atan(EcmaRuntimeCallInfo *argv)
1244514f5e3Sopenharmony_ci{
1254514f5e3Sopenharmony_ci    ASSERT(argv);
1264514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Atan);
1274514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1284514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1294514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
1304514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
1314514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1324514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
1334514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
1344514f5e3Sopenharmony_ci    // value == -NaN, NaN, result is  NaN
1354514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value))) {
1364514f5e3Sopenharmony_ci        result = std::atan(value);
1374514f5e3Sopenharmony_ci    }
1384514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
1394514f5e3Sopenharmony_ci}
1404514f5e3Sopenharmony_ci
1414514f5e3Sopenharmony_ci// 20.2.2.7
1424514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Atanh(EcmaRuntimeCallInfo *argv)
1434514f5e3Sopenharmony_ci{
1444514f5e3Sopenharmony_ci    ASSERT(argv);
1454514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Atanh);
1464514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1474514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1484514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
1494514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
1504514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1514514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
1524514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
1534514f5e3Sopenharmony_ci    if (value >= -1 && value <= 1) {
1544514f5e3Sopenharmony_ci        result = base::MathHelper::Atanh(value);
1554514f5e3Sopenharmony_ci    }
1564514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
1574514f5e3Sopenharmony_ci}
1584514f5e3Sopenharmony_ci
1594514f5e3Sopenharmony_ci// 20.2.2.8
1604514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Atan2(EcmaRuntimeCallInfo *argv)
1614514f5e3Sopenharmony_ci{
1624514f5e3Sopenharmony_ci    ASSERT(argv);
1634514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Atan2);
1644514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1654514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1664514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msgY = GetCallArg(argv, 0);
1674514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msgX = GetCallArg(argv, 1);
1684514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
1694514f5e3Sopenharmony_ci    JSTaggedNumber numberValueY = JSTaggedValue::ToNumber(thread, msgY);
1704514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1714514f5e3Sopenharmony_ci    JSTaggedNumber numberValueX = JSTaggedValue::ToNumber(thread, msgX);
1724514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1734514f5e3Sopenharmony_ci    double valueY = numberValueY.GetNumber();
1744514f5e3Sopenharmony_ci    double valueX = numberValueX.GetNumber();
1754514f5e3Sopenharmony_ci    // y = +0 and x > +0, return +0
1764514f5e3Sopenharmony_ci    // y = -0 and x > +0, return -0
1774514f5e3Sopenharmony_ci    if (valueY == 0 && valueX > 0) {
1784514f5e3Sopenharmony_ci        result = valueY;
1794514f5e3Sopenharmony_ci    } else if (std::isfinite(valueY) && valueX == std::numeric_limits<double>::infinity()) {
1804514f5e3Sopenharmony_ci        // y < 0 and y is finite and x is POSITIVE_INFINITY,return -0
1814514f5e3Sopenharmony_ci        // y >= 0 and y is finite and x is POSITIVE_INFINITY,return +0
1824514f5e3Sopenharmony_ci        result = valueY >= 0 ? 0 : -0.0;
1834514f5e3Sopenharmony_ci    } else if (!std::isnan(std::abs(valueY)) && !std::isnan(std::abs(valueX))) {
1844514f5e3Sopenharmony_ci        // If either x or y is NaN, the result is NaN
1854514f5e3Sopenharmony_ci        result = std::atan2(valueY, valueX);
1864514f5e3Sopenharmony_ci    }
1874514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
1884514f5e3Sopenharmony_ci}
1894514f5e3Sopenharmony_ci
1904514f5e3Sopenharmony_ci// 20.2.2.9
1914514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Cbrt(EcmaRuntimeCallInfo *argv)
1924514f5e3Sopenharmony_ci{
1934514f5e3Sopenharmony_ci    ASSERT(argv);
1944514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Cbrt);
1954514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1964514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1974514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
1984514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
1994514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2004514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
2014514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
2024514f5e3Sopenharmony_ci    // if value == -NaN, NaN, result is NaN
2034514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value))) {
2044514f5e3Sopenharmony_ci        result = std::cbrt(value);
2054514f5e3Sopenharmony_ci    }
2064514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
2074514f5e3Sopenharmony_ci}
2084514f5e3Sopenharmony_ci
2094514f5e3Sopenharmony_ci// 20.2.2.10
2104514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Ceil(EcmaRuntimeCallInfo *argv)
2114514f5e3Sopenharmony_ci{
2124514f5e3Sopenharmony_ci    ASSERT(argv);
2134514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Ceil);
2144514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2154514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2164514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
2174514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
2184514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2194514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
2204514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
2214514f5e3Sopenharmony_ci    // If value is NaN or -NaN, +infinite, -infinite,return value
2224514f5e3Sopenharmony_ci    if (!std::isfinite(value)) {
2234514f5e3Sopenharmony_ci        // if value is -NaN , return NaN, else return value
2244514f5e3Sopenharmony_ci        if (!std::isnan(std::abs(value))) {
2254514f5e3Sopenharmony_ci            result = value;
2264514f5e3Sopenharmony_ci        }
2274514f5e3Sopenharmony_ci    } else {
2284514f5e3Sopenharmony_ci        result = std::ceil(value);
2294514f5e3Sopenharmony_ci    }
2304514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
2314514f5e3Sopenharmony_ci}
2324514f5e3Sopenharmony_ci
2334514f5e3Sopenharmony_ci// 20.2.2.11
2344514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Clz32(EcmaRuntimeCallInfo *argv)
2354514f5e3Sopenharmony_ci{
2364514f5e3Sopenharmony_ci    ASSERT(argv);
2374514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Clz32);
2384514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2394514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2404514f5e3Sopenharmony_ci    constexpr int defaultValue = 32;
2414514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
2424514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
2434514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2444514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
2454514f5e3Sopenharmony_ci    auto tmpValue = std::abs(value);
2464514f5e3Sopenharmony_ci    auto result = numberValue.ToUint32();
2474514f5e3Sopenharmony_ci    if (!std::isfinite(tmpValue) || tmpValue == 0 || result == 0) {
2484514f5e3Sopenharmony_ci        // If value is NaN or -NaN, +infinite, -infinite, 0,return 32
2494514f5e3Sopenharmony_ci        return GetTaggedInt(defaultValue);
2504514f5e3Sopenharmony_ci    }
2514514f5e3Sopenharmony_ci    return GetTaggedInt(__builtin_clz(result));
2524514f5e3Sopenharmony_ci}
2534514f5e3Sopenharmony_ci
2544514f5e3Sopenharmony_ci// 20.2.2.12
2554514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Cos(EcmaRuntimeCallInfo *argv)
2564514f5e3Sopenharmony_ci{
2574514f5e3Sopenharmony_ci    ASSERT(argv);
2584514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Cos);
2594514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2604514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2614514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
2624514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
2634514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2644514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
2654514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
2664514f5e3Sopenharmony_ci    //  If value is NaN or -NaN, +infinite, -infinite, result is NaN
2674514f5e3Sopenharmony_ci    if (std::isfinite(std::abs(value))) {
2684514f5e3Sopenharmony_ci        result = std::cos(value);
2694514f5e3Sopenharmony_ci    }
2704514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
2714514f5e3Sopenharmony_ci}
2724514f5e3Sopenharmony_ci
2734514f5e3Sopenharmony_ci// 20.2.2.13
2744514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Cosh(EcmaRuntimeCallInfo *argv)
2754514f5e3Sopenharmony_ci{
2764514f5e3Sopenharmony_ci    ASSERT(argv);
2774514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Cosh);
2784514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2794514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2804514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
2814514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
2824514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2834514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
2844514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
2854514f5e3Sopenharmony_ci    // if value is NaN or -NaN, result is NaN
2864514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value))) {
2874514f5e3Sopenharmony_ci        result = std::cosh(value);
2884514f5e3Sopenharmony_ci    }
2894514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
2904514f5e3Sopenharmony_ci}
2914514f5e3Sopenharmony_ci
2924514f5e3Sopenharmony_ci// 20.2.2.14
2934514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Exp(EcmaRuntimeCallInfo *argv)
2944514f5e3Sopenharmony_ci{
2954514f5e3Sopenharmony_ci    ASSERT(argv);
2964514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Exp);
2974514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2984514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2994514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
3004514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
3014514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3024514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
3034514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
3044514f5e3Sopenharmony_ci    // if value is NaN or -NaN, result is NaN
3054514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value))) {
3064514f5e3Sopenharmony_ci        result = std::exp(value);
3074514f5e3Sopenharmony_ci    }
3084514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
3094514f5e3Sopenharmony_ci}
3104514f5e3Sopenharmony_ci
3114514f5e3Sopenharmony_ci// 20.2.2.15
3124514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Expm1(EcmaRuntimeCallInfo *argv)
3134514f5e3Sopenharmony_ci{
3144514f5e3Sopenharmony_ci    ASSERT(argv);
3154514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Expm1);
3164514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
3174514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
3184514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
3194514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
3204514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3214514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
3224514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
3234514f5e3Sopenharmony_ci    // if value is NaN or -NaN, result is NaN
3244514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value))) {
3254514f5e3Sopenharmony_ci        result = std::expm1(value);
3264514f5e3Sopenharmony_ci    }
3274514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
3284514f5e3Sopenharmony_ci}
3294514f5e3Sopenharmony_ci
3304514f5e3Sopenharmony_ci// 20.2.2.16
3314514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Floor(EcmaRuntimeCallInfo *argv)
3324514f5e3Sopenharmony_ci{
3334514f5e3Sopenharmony_ci    ASSERT(argv);
3344514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Floor);
3354514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
3364514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
3374514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
3384514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
3394514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3404514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
3414514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
3424514f5e3Sopenharmony_ci    // If value is NaN or -NaN, +infinite, -infinite, +0, -0, return value
3434514f5e3Sopenharmony_ci    if (!std::isfinite(value) || value == 0) {
3444514f5e3Sopenharmony_ci        // If value is -NaN, return NaN, else return value
3454514f5e3Sopenharmony_ci        if (!std::isnan(std::abs(value))) {
3464514f5e3Sopenharmony_ci            result = value;
3474514f5e3Sopenharmony_ci        }
3484514f5e3Sopenharmony_ci    } else if (value > 0 && value < 1) {
3494514f5e3Sopenharmony_ci        // If x is greater than 0 but less than 1, the result is +0
3504514f5e3Sopenharmony_ci        result = 0;
3514514f5e3Sopenharmony_ci    } else {
3524514f5e3Sopenharmony_ci        result = std::floor(value);
3534514f5e3Sopenharmony_ci    }
3544514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
3554514f5e3Sopenharmony_ci}
3564514f5e3Sopenharmony_ci
3574514f5e3Sopenharmony_ci// 20.2.2.17
3584514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Fround(EcmaRuntimeCallInfo *argv)
3594514f5e3Sopenharmony_ci{
3604514f5e3Sopenharmony_ci    ASSERT(argv);
3614514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Fround);
3624514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
3634514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
3644514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
3654514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
3664514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3674514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
3684514f5e3Sopenharmony_ci    double result;
3694514f5e3Sopenharmony_ci    if (std::isnan(std::abs(value))) {
3704514f5e3Sopenharmony_ci        // If result is NaN or -NaN, the result is NaN
3714514f5e3Sopenharmony_ci        result = base::NAN_VALUE;
3724514f5e3Sopenharmony_ci    } else {
3734514f5e3Sopenharmony_ci        result = static_cast<float>(value);
3744514f5e3Sopenharmony_ci    }
3754514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
3764514f5e3Sopenharmony_ci}
3774514f5e3Sopenharmony_ci
3784514f5e3Sopenharmony_ci// 20.2.2.18
3794514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Hypot(EcmaRuntimeCallInfo *argv)
3804514f5e3Sopenharmony_ci{
3814514f5e3Sopenharmony_ci    ASSERT(argv);
3824514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Hypot);
3834514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
3844514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
3854514f5e3Sopenharmony_ci    double result = 0;
3864514f5e3Sopenharmony_ci    double value = 0;
3874514f5e3Sopenharmony_ci    uint32_t argLen = argv->GetArgsNumber();
3884514f5e3Sopenharmony_ci    auto numberValue = JSTaggedNumber(0);
3894514f5e3Sopenharmony_ci    for (uint32_t i = 0; i < argLen; i++) {
3904514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> msg = GetCallArg(argv, i);
3914514f5e3Sopenharmony_ci        numberValue = JSTaggedValue::ToNumber(thread, msg);
3924514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3934514f5e3Sopenharmony_ci        value = numberValue.GetNumber();
3944514f5e3Sopenharmony_ci        result = std::hypot(result, value);
3954514f5e3Sopenharmony_ci    }
3964514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
3974514f5e3Sopenharmony_ci}
3984514f5e3Sopenharmony_ci
3994514f5e3Sopenharmony_ci// 20.2.2.19
4004514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Imul(EcmaRuntimeCallInfo *argv)
4014514f5e3Sopenharmony_ci{
4024514f5e3Sopenharmony_ci    ASSERT(argv);
4034514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Imul);
4044514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
4054514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
4064514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg1 = GetCallArg(argv, 0);
4074514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg2 = GetCallArg(argv, 1);
4084514f5e3Sopenharmony_ci    JSTaggedNumber numberValue1 = JSTaggedValue::ToNumber(thread, msg1);
4094514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4104514f5e3Sopenharmony_ci    JSTaggedNumber numberValue2 = JSTaggedValue::ToNumber(thread, msg2);
4114514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4124514f5e3Sopenharmony_ci    auto value1 = numberValue1.GetNumber();
4134514f5e3Sopenharmony_ci    auto value2 = numberValue2.GetNumber();
4144514f5e3Sopenharmony_ci    if (!std::isfinite(value1) || !std::isfinite(value2)) {
4154514f5e3Sopenharmony_ci        // If value is NaN or -NaN, +infinite, -infinite
4164514f5e3Sopenharmony_ci        return GetTaggedInt(0);
4174514f5e3Sopenharmony_ci    }
4184514f5e3Sopenharmony_ci    value1 = numberValue1.ToInt32();
4194514f5e3Sopenharmony_ci    value2 = numberValue2.ToInt32();
4204514f5e3Sopenharmony_ci    // purposely ignoring overflow
4214514f5e3Sopenharmony_ci    auto result = static_cast<int32_t>(static_cast<int64_t>(value1) * static_cast<int64_t>(value2));
4224514f5e3Sopenharmony_ci    return GetTaggedInt(result);
4234514f5e3Sopenharmony_ci}
4244514f5e3Sopenharmony_ci
4254514f5e3Sopenharmony_ci// 20.2.2.20
4264514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Log(EcmaRuntimeCallInfo *argv)
4274514f5e3Sopenharmony_ci{
4284514f5e3Sopenharmony_ci    ASSERT(argv);
4294514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Log);
4304514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
4314514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
4324514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
4334514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
4344514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4354514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
4364514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
4374514f5e3Sopenharmony_ci    // If value is NaN , -NaN , or < 0,result is NaN
4384514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value)) && value >= 0) {
4394514f5e3Sopenharmony_ci        result = std::log(value);
4404514f5e3Sopenharmony_ci    }
4414514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
4424514f5e3Sopenharmony_ci}
4434514f5e3Sopenharmony_ci
4444514f5e3Sopenharmony_ci// 20.2.2.21
4454514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Log1p(EcmaRuntimeCallInfo *argv)
4464514f5e3Sopenharmony_ci{
4474514f5e3Sopenharmony_ci    ASSERT(argv);
4484514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Log1p);
4494514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
4504514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
4514514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
4524514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
4534514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4544514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
4554514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
4564514f5e3Sopenharmony_ci    // If value is NaN , -NaN , or < -1,result is NaN
4574514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value)) && value >= -1) {
4584514f5e3Sopenharmony_ci        result = std::log1p(value);
4594514f5e3Sopenharmony_ci    }
4604514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
4614514f5e3Sopenharmony_ci}
4624514f5e3Sopenharmony_ci
4634514f5e3Sopenharmony_ci// 20.2.2.22
4644514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Log10(EcmaRuntimeCallInfo *argv)
4654514f5e3Sopenharmony_ci{
4664514f5e3Sopenharmony_ci    ASSERT(argv);
4674514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Log10);
4684514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
4694514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
4704514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
4714514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
4724514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4734514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
4744514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
4754514f5e3Sopenharmony_ci    // If value is NaN , -NaN , or < 0,result is NaN
4764514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value)) && value >= 0) {
4774514f5e3Sopenharmony_ci        result = std::log10(value);
4784514f5e3Sopenharmony_ci    }
4794514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
4804514f5e3Sopenharmony_ci}
4814514f5e3Sopenharmony_ci
4824514f5e3Sopenharmony_ci// 20.2.2.23
4834514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Log2(EcmaRuntimeCallInfo *argv)
4844514f5e3Sopenharmony_ci{
4854514f5e3Sopenharmony_ci    ASSERT(argv);
4864514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Log2);
4874514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
4884514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
4894514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
4904514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
4914514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4924514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
4934514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
4944514f5e3Sopenharmony_ci    // If value is NaN , -NaN , or < 0,result is NaN
4954514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value)) && value >= 0) {
4964514f5e3Sopenharmony_ci        result = std::log2(value);
4974514f5e3Sopenharmony_ci    }
4984514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
4994514f5e3Sopenharmony_ci}
5004514f5e3Sopenharmony_ci
5014514f5e3Sopenharmony_ciinline bool IsNegZero(double value)
5024514f5e3Sopenharmony_ci{
5034514f5e3Sopenharmony_ci    return (value == 0.0 && (base::bit_cast<uint64_t>(value) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK);
5044514f5e3Sopenharmony_ci}
5054514f5e3Sopenharmony_ci
5064514f5e3Sopenharmony_ci// 20.2.2.24
5074514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Max(EcmaRuntimeCallInfo *argv)
5084514f5e3Sopenharmony_ci{
5094514f5e3Sopenharmony_ci    ASSERT(argv);
5104514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Max);
5114514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
5124514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
5134514f5e3Sopenharmony_ci    uint32_t argLen = argv->GetArgsNumber();
5144514f5e3Sopenharmony_ci    auto numberValue = JSTaggedNumber(-base::POSITIVE_INFINITY);
5154514f5e3Sopenharmony_ci    // If no arguments are given, the result is -inf
5164514f5e3Sopenharmony_ci    auto result = JSTaggedNumber(-base::POSITIVE_INFINITY);
5174514f5e3Sopenharmony_ci    auto tmpMax = -base::POSITIVE_INFINITY;
5184514f5e3Sopenharmony_ci    auto value = -base::POSITIVE_INFINITY;
5194514f5e3Sopenharmony_ci    bool flag = false;
5204514f5e3Sopenharmony_ci    uint32_t i = 0;
5214514f5e3Sopenharmony_ci    for (; i < argLen; i++) {
5224514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> msg = GetCallArg(argv, i);
5234514f5e3Sopenharmony_ci        numberValue = JSTaggedValue::ToNumber(thread, msg);
5244514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
5254514f5e3Sopenharmony_ci        value = numberValue.GetNumber();
5264514f5e3Sopenharmony_ci        if (std::isnan(std::abs(value))) {
5274514f5e3Sopenharmony_ci            // If any value is NaN, or -NaN, the max result is NaN
5284514f5e3Sopenharmony_ci            result = numberValue;
5294514f5e3Sopenharmony_ci            flag = true;
5304514f5e3Sopenharmony_ci            i++;
5314514f5e3Sopenharmony_ci            break;
5324514f5e3Sopenharmony_ci        }
5334514f5e3Sopenharmony_ci        if (value > tmpMax) {
5344514f5e3Sopenharmony_ci            result = numberValue;
5354514f5e3Sopenharmony_ci            tmpMax = value;
5364514f5e3Sopenharmony_ci        } else if (value == 0 && tmpMax == 0 && IsNegZero(tmpMax) && !IsNegZero(value)) {
5374514f5e3Sopenharmony_ci            // if tmp_max is -0, value is 0, max is 0
5384514f5e3Sopenharmony_ci            result = numberValue;
5394514f5e3Sopenharmony_ci            tmpMax = value;
5404514f5e3Sopenharmony_ci        }
5414514f5e3Sopenharmony_ci    }
5424514f5e3Sopenharmony_ci    if (flag) {
5434514f5e3Sopenharmony_ci        for (; i < argLen; i++) {
5444514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> msg = GetCallArg(argv, i);
5454514f5e3Sopenharmony_ci            numberValue = JSTaggedValue::ToNumber(thread, msg);
5464514f5e3Sopenharmony_ci            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
5474514f5e3Sopenharmony_ci        }
5484514f5e3Sopenharmony_ci    }
5494514f5e3Sopenharmony_ci    return result;
5504514f5e3Sopenharmony_ci}
5514514f5e3Sopenharmony_ci
5524514f5e3Sopenharmony_ci// 20.2.2.25
5534514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Min(EcmaRuntimeCallInfo *argv)
5544514f5e3Sopenharmony_ci{
5554514f5e3Sopenharmony_ci    ASSERT(argv);
5564514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Min);
5574514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
5584514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
5594514f5e3Sopenharmony_ci    uint32_t argLen = argv->GetArgsNumber();
5604514f5e3Sopenharmony_ci    auto numberValue = JSTaggedNumber(base::POSITIVE_INFINITY);
5614514f5e3Sopenharmony_ci    // If no arguments are given, the result is inf
5624514f5e3Sopenharmony_ci    auto result = JSTaggedNumber(base::POSITIVE_INFINITY);
5634514f5e3Sopenharmony_ci    auto tmpMin = base::POSITIVE_INFINITY;
5644514f5e3Sopenharmony_ci    auto value = base::POSITIVE_INFINITY;
5654514f5e3Sopenharmony_ci    bool flag = false;
5664514f5e3Sopenharmony_ci    uint32_t i = 0;
5674514f5e3Sopenharmony_ci    for (; i < argLen; i++) {
5684514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> msg = GetCallArg(argv, i);
5694514f5e3Sopenharmony_ci        numberValue = JSTaggedValue::ToNumber(thread, msg);
5704514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
5714514f5e3Sopenharmony_ci        value = numberValue.GetNumber();
5724514f5e3Sopenharmony_ci        if (std::isnan(std::abs(value))) {
5734514f5e3Sopenharmony_ci            // If any value is NaN or -NaN, the min result is NaN
5744514f5e3Sopenharmony_ci            result = numberValue;
5754514f5e3Sopenharmony_ci            flag = true;
5764514f5e3Sopenharmony_ci            i++;
5774514f5e3Sopenharmony_ci            break;
5784514f5e3Sopenharmony_ci        }
5794514f5e3Sopenharmony_ci        if (value < tmpMin) {
5804514f5e3Sopenharmony_ci            result = numberValue;
5814514f5e3Sopenharmony_ci            tmpMin = value;
5824514f5e3Sopenharmony_ci        } else if (value == 0 && tmpMin == 0 && !IsNegZero(tmpMin) && IsNegZero(value)) {
5834514f5e3Sopenharmony_ci            // if tmp_min is 0, value is -0, min is -0
5844514f5e3Sopenharmony_ci            result = numberValue;
5854514f5e3Sopenharmony_ci            tmpMin = value;
5864514f5e3Sopenharmony_ci        }
5874514f5e3Sopenharmony_ci    }
5884514f5e3Sopenharmony_ci    if (flag) {
5894514f5e3Sopenharmony_ci        for (; i < argLen; i++) {
5904514f5e3Sopenharmony_ci            JSHandle<JSTaggedValue> msg = GetCallArg(argv, i);
5914514f5e3Sopenharmony_ci            numberValue = JSTaggedValue::ToNumber(thread, msg);
5924514f5e3Sopenharmony_ci            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
5934514f5e3Sopenharmony_ci        }
5944514f5e3Sopenharmony_ci    }
5954514f5e3Sopenharmony_ci    return result;
5964514f5e3Sopenharmony_ci}
5974514f5e3Sopenharmony_ci
5984514f5e3Sopenharmony_ci// 20.2.2.26
5994514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Pow(EcmaRuntimeCallInfo *argv)
6004514f5e3Sopenharmony_ci{
6014514f5e3Sopenharmony_ci    ASSERT(argv);
6024514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Pow);
6034514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
6044514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
6054514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msgX = GetCallArg(argv, 0);
6064514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msgY = GetCallArg(argv, 1);
6074514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> baseVale = JSTaggedValue::ToNumeric(thread, msgX);
6084514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
6094514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> exponentValue = JSTaggedValue::ToNumeric(thread, msgY);
6104514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
6114514f5e3Sopenharmony_ci    if (baseVale->IsBigInt() || exponentValue->IsBigInt()) {
6124514f5e3Sopenharmony_ci        if (baseVale->IsBigInt() && exponentValue->IsBigInt()) {
6134514f5e3Sopenharmony_ci            JSHandle<BigInt> bigBaseVale(baseVale);
6144514f5e3Sopenharmony_ci            JSHandle<BigInt> bigExponentValue(exponentValue);
6154514f5e3Sopenharmony_ci            return  BigInt::Exponentiate(thread, bigBaseVale, bigExponentValue).GetTaggedValue();
6164514f5e3Sopenharmony_ci        }
6174514f5e3Sopenharmony_ci        THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot mix BigInt and other types, use explicit conversions",
6184514f5e3Sopenharmony_ci                                    JSTaggedValue::Exception());
6194514f5e3Sopenharmony_ci    }
6204514f5e3Sopenharmony_ci    double valueX = baseVale->GetNumber();
6214514f5e3Sopenharmony_ci    double valueY = exponentValue->GetNumber();
6224514f5e3Sopenharmony_ci    // If abs(x) is 1 and y is inf or -inf, the result is NaN
6234514f5e3Sopenharmony_ci    if (std::abs(valueX) == 1 && !std::isfinite(valueY)) {
6244514f5e3Sopenharmony_ci        return GetTaggedDouble(base::NAN_VALUE);
6254514f5e3Sopenharmony_ci    }
6264514f5e3Sopenharmony_ci    double result = std::pow(valueX, valueY);
6274514f5e3Sopenharmony_ci    if (std::isnan(std::abs(result))) {
6284514f5e3Sopenharmony_ci        // If result is NaN or -NaN, the result is NaN
6294514f5e3Sopenharmony_ci        result = base::NAN_VALUE;
6304514f5e3Sopenharmony_ci    }
6314514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
6324514f5e3Sopenharmony_ci}
6334514f5e3Sopenharmony_ci
6344514f5e3Sopenharmony_ci// 20.2.2.27
6354514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Random(EcmaRuntimeCallInfo *argv)
6364514f5e3Sopenharmony_ci{
6374514f5e3Sopenharmony_ci    ASSERT(argv);
6384514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
6394514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(thread, Math, Random);
6404514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
6414514f5e3Sopenharmony_ci    return GetTaggedDouble(RandomGenerator::NextDouble());
6424514f5e3Sopenharmony_ci}
6434514f5e3Sopenharmony_ci
6444514f5e3Sopenharmony_ci// 20.2.2.28
6454514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Round(EcmaRuntimeCallInfo *argv)
6464514f5e3Sopenharmony_ci{
6474514f5e3Sopenharmony_ci    ASSERT(argv);
6484514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Round);
6494514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
6504514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
6514514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
6524514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
6534514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
6544514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
6554514f5e3Sopenharmony_ci    auto result = base::NAN_VALUE;
6564514f5e3Sopenharmony_ci    const double diff = 0.5;
6574514f5e3Sopenharmony_ci    double absValue = std::abs(value);
6584514f5e3Sopenharmony_ci    if (!std::isfinite(absValue) || absValue == 0) {
6594514f5e3Sopenharmony_ci        // If value is NaN, +infinite, or -infinite, VRegisterTag is DOUBLE
6604514f5e3Sopenharmony_ci        if (!std::isnan(absValue)) {
6614514f5e3Sopenharmony_ci            // If value is NaN or -NaN, the result is default NaN, else is value
6624514f5e3Sopenharmony_ci            result = value;
6634514f5e3Sopenharmony_ci        }
6644514f5e3Sopenharmony_ci        return GetTaggedDouble(result);
6654514f5e3Sopenharmony_ci    }
6664514f5e3Sopenharmony_ci    // If x is less than 0 but greater than or equal to -0.5, the result is -0
6674514f5e3Sopenharmony_ci    if (value < 0 && value >= -diff) {
6684514f5e3Sopenharmony_ci        return GetTaggedDouble(-0.0);
6694514f5e3Sopenharmony_ci    }
6704514f5e3Sopenharmony_ci    // If x is greater than 0 but less than 0.5, the result is +0
6714514f5e3Sopenharmony_ci    if (value > 0 && value < diff) {
6724514f5e3Sopenharmony_ci        return GetTaggedInt(0);
6734514f5e3Sopenharmony_ci    }
6744514f5e3Sopenharmony_ci    // For huge integers
6754514f5e3Sopenharmony_ci    result = std::ceil(value);
6764514f5e3Sopenharmony_ci    if (result - value > diff) {
6774514f5e3Sopenharmony_ci        result -= 1;
6784514f5e3Sopenharmony_ci    }
6794514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
6804514f5e3Sopenharmony_ci}
6814514f5e3Sopenharmony_ci
6824514f5e3Sopenharmony_ci// 20.2.2.29
6834514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Sign(EcmaRuntimeCallInfo *argv)
6844514f5e3Sopenharmony_ci{
6854514f5e3Sopenharmony_ci    ASSERT(argv);
6864514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Sign);
6874514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
6884514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
6894514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
6904514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
6914514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
6924514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
6934514f5e3Sopenharmony_ci    if (std::isnan(std::abs(value))) {
6944514f5e3Sopenharmony_ci        return GetTaggedDouble(std::abs(value));
6954514f5e3Sopenharmony_ci    }
6964514f5e3Sopenharmony_ci    if (value == 0.0) {
6974514f5e3Sopenharmony_ci        return GetTaggedDouble(value);
6984514f5e3Sopenharmony_ci    }
6994514f5e3Sopenharmony_ci    if (value < 0) {
7004514f5e3Sopenharmony_ci        return GetTaggedInt(-1);
7014514f5e3Sopenharmony_ci    }
7024514f5e3Sopenharmony_ci    return GetTaggedInt(1);
7034514f5e3Sopenharmony_ci}
7044514f5e3Sopenharmony_ci
7054514f5e3Sopenharmony_ci// 20.2.2.30
7064514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Sin(EcmaRuntimeCallInfo *argv)
7074514f5e3Sopenharmony_ci{
7084514f5e3Sopenharmony_ci    ASSERT(argv);
7094514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Sin);
7104514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
7114514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
7124514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
7134514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
7144514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
7154514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
7164514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
7174514f5e3Sopenharmony_ci    // If value is NaN or -NaN, the result is NaN
7184514f5e3Sopenharmony_ci    if (std::isfinite(std::abs(value))) {
7194514f5e3Sopenharmony_ci        result = std::sin(value);
7204514f5e3Sopenharmony_ci    }
7214514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
7224514f5e3Sopenharmony_ci}
7234514f5e3Sopenharmony_ci
7244514f5e3Sopenharmony_ci// 20.2.2.31
7254514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Sinh(EcmaRuntimeCallInfo *argv)
7264514f5e3Sopenharmony_ci{
7274514f5e3Sopenharmony_ci    ASSERT(argv);
7284514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Sinh);
7294514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
7304514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
7314514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
7324514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
7334514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
7344514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
7354514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
7364514f5e3Sopenharmony_ci    // If value is NaN or -NaN, the result is NaN
7374514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value))) {
7384514f5e3Sopenharmony_ci        result = std::sinh(value);
7394514f5e3Sopenharmony_ci    }
7404514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
7414514f5e3Sopenharmony_ci}
7424514f5e3Sopenharmony_ci
7434514f5e3Sopenharmony_ci// 20.2.2.32
7444514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Sqrt(EcmaRuntimeCallInfo *argv)
7454514f5e3Sopenharmony_ci{
7464514f5e3Sopenharmony_ci    ASSERT(argv);
7474514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Sqrt);
7484514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
7494514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
7504514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
7514514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
7524514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
7534514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
7544514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
7554514f5e3Sopenharmony_ci    // If value is negative, include -NaN and -Infinity but not -0.0, the result is NaN
7564514f5e3Sopenharmony_ci    if (std::signbit(value) && value != 0) {
7574514f5e3Sopenharmony_ci        return GetTaggedDouble(result);
7584514f5e3Sopenharmony_ci    }
7594514f5e3Sopenharmony_ci    // If value is NaN, the result is NaN
7604514f5e3Sopenharmony_ci    if (!std::isnan(value)) {
7614514f5e3Sopenharmony_ci        result = std::sqrt(value);
7624514f5e3Sopenharmony_ci    }
7634514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
7644514f5e3Sopenharmony_ci}
7654514f5e3Sopenharmony_ci
7664514f5e3Sopenharmony_ci// 20.2.2.33
7674514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Tan(EcmaRuntimeCallInfo *argv)
7684514f5e3Sopenharmony_ci{
7694514f5e3Sopenharmony_ci    ASSERT(argv);
7704514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Tan);
7714514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
7724514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
7734514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
7744514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
7754514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
7764514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
7774514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
7784514f5e3Sopenharmony_ci    // If value is NaN or -NaN, +infinite, -infinite, result is NaN
7794514f5e3Sopenharmony_ci    if (std::isfinite(value)) {
7804514f5e3Sopenharmony_ci        result = std::tan(value);
7814514f5e3Sopenharmony_ci    }
7824514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
7834514f5e3Sopenharmony_ci}
7844514f5e3Sopenharmony_ci
7854514f5e3Sopenharmony_ci// 20.2.2.34
7864514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Tanh(EcmaRuntimeCallInfo *argv)
7874514f5e3Sopenharmony_ci{
7884514f5e3Sopenharmony_ci    ASSERT(argv);
7894514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Tanh);
7904514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
7914514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
7924514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
7934514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
7944514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
7954514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
7964514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
7974514f5e3Sopenharmony_ci    if (!std::isnan(std::abs(value))) {
7984514f5e3Sopenharmony_ci        result = std::tanh(value);
7994514f5e3Sopenharmony_ci    }
8004514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
8014514f5e3Sopenharmony_ci}
8024514f5e3Sopenharmony_ci
8034514f5e3Sopenharmony_ci// 20.2.2.35
8044514f5e3Sopenharmony_ciJSTaggedValue BuiltinsMath::Trunc(EcmaRuntimeCallInfo *argv)
8054514f5e3Sopenharmony_ci{
8064514f5e3Sopenharmony_ci    ASSERT(argv);
8074514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Math, Trunc);
8084514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
8094514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
8104514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> msg = GetCallArg(argv, 0);
8114514f5e3Sopenharmony_ci    JSTaggedNumber numberValue = JSTaggedValue::ToNumber(thread, msg);
8124514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
8134514f5e3Sopenharmony_ci    double value = numberValue.GetNumber();
8144514f5e3Sopenharmony_ci    double result = base::NAN_VALUE;
8154514f5e3Sopenharmony_ci    if (!std::isfinite(value)) {
8164514f5e3Sopenharmony_ci        // if value is +infinite, -infinite, NaN, -NaN, VRegisterTag is double
8174514f5e3Sopenharmony_ci        if (!std::isnan(std::abs(value))) {
8184514f5e3Sopenharmony_ci            // if value is +infinite, -infinite, result is value
8194514f5e3Sopenharmony_ci            result = value;
8204514f5e3Sopenharmony_ci        }
8214514f5e3Sopenharmony_ci    } else {
8224514f5e3Sopenharmony_ci        result = std::trunc(value);
8234514f5e3Sopenharmony_ci    }
8244514f5e3Sopenharmony_ci    return GetTaggedDouble(result);
8254514f5e3Sopenharmony_ci}
8264514f5e3Sopenharmony_ci}  // namespace panda::ecmascript::builtins
827