1 /** 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 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 */ 15 16 #include "intrinsics.h" 17 #include "plugins/ets/runtime/types/ets_string.h" 18 #include "plugins/ets/runtime/intrinsics/helpers/ets_intrinsics_helpers.h" 19 #include "plugins/ets/runtime/intrinsics/helpers/ets_to_string_cache.h" 20 21 namespace ark::ets::intrinsics { 22 StdCoreFloatToString(float number,int radix)23EtsString *StdCoreFloatToString(float number, int radix) 24 { 25 if (UNLIKELY(radix != helpers::DECIMAL)) { 26 return helpers::FpToString(number, radix); 27 } 28 auto *cache = PandaEtsVM::GetCurrent()->GetFloatToStringCache(); 29 ASSERT(cache != nullptr); 30 return cache->GetOrCache(EtsCoroutine::GetCurrent(), number); 31 } 32 StdCoreFloatIsNan(float v)33extern "C" EtsBoolean StdCoreFloatIsNan(float v) 34 { 35 return ToEtsBoolean(v != v); 36 } 37 StdCoreFloatIsFinite(float v)38extern "C" EtsBoolean StdCoreFloatIsFinite(float v) 39 { 40 static const float POSITIVE_INFINITY = 1.0 / 0.0; 41 static const float NEGATIVE_INFINITY = -1.0 / 0.0; 42 43 return ToEtsBoolean(v == v && v != POSITIVE_INFINITY && v != NEGATIVE_INFINITY); 44 } 45 StdCoreFloatBitCastFromInt(EtsInt i)46extern "C" EtsFloat StdCoreFloatBitCastFromInt(EtsInt i) 47 { 48 return bit_cast<EtsFloat>(i); 49 } 50 StdCoreFloatBitCastToInt(EtsFloat f)51extern "C" EtsInt StdCoreFloatBitCastToInt(EtsFloat f) 52 { 53 return bit_cast<EtsInt>(f); 54 } 55 IsInteger(float v)56static inline bool IsInteger(float v) 57 { 58 return std::isfinite(v) && (std::fabs(v - std::trunc(v)) <= std::numeric_limits<float>::epsilon()); 59 } 60 StdCoreFloatIsInteger(float v)61extern "C" EtsBoolean StdCoreFloatIsInteger(float v) 62 { 63 return ToEtsBoolean(IsInteger(v)); 64 } 65 66 /* 67 * In ETS Float.isSafeInteger returns (Float.isInteger(v) && (abs(v) <= Float.MAX_SAFE_INTEGER)). 68 * MAX_SAFE_INTEGER is a max integer value that can be used as a float without losing precision. 69 */ StdCoreFloatIsSafeInteger(float v)70extern "C" EtsBoolean StdCoreFloatIsSafeInteger(float v) 71 { 72 return ToEtsBoolean(IsInteger(v) && (std::fabs(v) <= helpers::MaxSafeInteger<float>())); 73 } 74 75 } // namespace ark::ets::intrinsics 76