From 282c8621d9858b772357a1caefddc6bc8a4cc211 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 19 Apr 2021 12:47:39 -0700 Subject: [PATCH 1/2] Add a clrmath project to centrally manage math APIs --- src/coreclr/CMakeLists.txt | 2 + .../classlibnative/float/CMakeLists.txt | 3 +- .../classlibnative/float/floatdouble.cpp | 133 +++------- .../classlibnative/float/floatsingle.cpp | 118 +++----- src/coreclr/classlibnative/inc/floatdouble.h | 2 +- src/coreclr/classlibnative/inc/floatsingle.h | 2 +- src/coreclr/jit/CMakeLists.txt | 1 + src/coreclr/jit/jitpch.h | 1 + src/coreclr/jit/valuenum.cpp | 100 +++---- src/native/clrmath/CMakeLists.txt | 8 + src/native/clrmath/inc/clrmath.h | 251 ++++++++++++++++++ 11 files changed, 380 insertions(+), 241 deletions(-) create mode 100644 src/native/clrmath/CMakeLists.txt create mode 100644 src/native/clrmath/inc/clrmath.h diff --git a/src/coreclr/CMakeLists.txt b/src/coreclr/CMakeLists.txt index 8f82d83fa4b735..a5b93ef65c3b0b 100644 --- a/src/coreclr/CMakeLists.txt +++ b/src/coreclr/CMakeLists.txt @@ -154,6 +154,8 @@ if (CLR_CMAKE_HOST_UNIX) include_directories("pal/src/safecrt") endif (CLR_CMAKE_HOST_UNIX) +include(${CLR_SRC_NATIVE_DIR}/clrmath/CMakeLists.txt) + #------------------------------ # Add Product Directories #------------------------------ diff --git a/src/coreclr/classlibnative/float/CMakeLists.txt b/src/coreclr/classlibnative/float/CMakeLists.txt index b2c47ea39b65ea..c2603063c3abe5 100644 --- a/src/coreclr/classlibnative/float/CMakeLists.txt +++ b/src/coreclr/classlibnative/float/CMakeLists.txt @@ -10,9 +10,10 @@ set(FLOAT_SOURCES add_library_clr(comfloat_wks_obj OBJECT ${FLOAT_SOURCES} + ${SHARED_CLRMATH_SOURCES} ) add_dependencies(comfloat_wks_obj eventing_headers) add_library(comfloat_wks INTERFACE) -target_sources(comfloat_wks INTERFACE $) \ No newline at end of file +target_sources(comfloat_wks INTERFACE $) diff --git a/src/coreclr/classlibnative/float/floatdouble.cpp b/src/coreclr/classlibnative/float/floatdouble.cpp index 4b4b2a267c579e..5725d0a01c9050 100644 --- a/src/coreclr/classlibnative/float/floatdouble.cpp +++ b/src/coreclr/classlibnative/float/floatdouble.cpp @@ -7,40 +7,7 @@ #include #include "floatdouble.h" - -// The default compilation mode is /fp:precise, which disables floating-point intrinsics. This -// default compilation mode has previously caused performance regressions in floating-point code. -// We enable /fp:fast semantics for the majority of the math functions, as it will speed up performance -// and is really unlikely to cause any other code regressions. - -// Sin, Cos, and Tan on AMD64 Windows were previously implemented in vm\amd64\JitHelpers_Fast.asm -// by calling x87 floating point code (fsin, fcos, fptan) because the CRT helpers were too slow. This -// is no longer the case and the CRT call is used on all platforms. - -// Log, Log10 and Exp were previously slower with /fp:fast on SSE2 enabled hardware (see #500373). -// This is no longer the case and they now consume use the /fp:fast versions. - -// Exp(+/-INFINITY) did not previously return the expected results of +0.0 (for -INFINITY) -// and +INFINITY (for +INFINITY) so these cases were handled specially. As this is no longer -// the case and the expected results are now returned, the special handling has been removed. - -// Previously there was more special handling for the x86 Windows version of Pow. -// This additional handling was unnecessary and has since been removed. - -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -/// -/// beginning of /fp:fast scope -/// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// - -#ifdef _MSC_VER -#pragma float_control(push) -#pragma float_control(precise, off) -#endif +#include "clrmath.h" /*=====================================Abs====================================== ** @@ -48,7 +15,7 @@ FCIMPL1_V(double, COMDouble::Abs, double x) FCALL_CONTRACT; - return fabs(x); + return clrmath_fabs(x); FCIMPLEND /*=====================================Acos===================================== @@ -57,7 +24,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Acos, double x) FCALL_CONTRACT; - return acos(x); + return clrmath_acos(x); FCIMPLEND /*=====================================Acosh==================================== @@ -66,7 +33,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Acosh, double x) FCALL_CONTRACT; - return acosh(x); + return clrmath_acosh(x); FCIMPLEND /*=====================================Asin===================================== @@ -75,7 +42,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Asin, double x) FCALL_CONTRACT; - return asin(x); + return clrmath_asin(x); FCIMPLEND /*=====================================Asinh==================================== @@ -84,7 +51,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Asinh, double x) FCALL_CONTRACT; - return asinh(x); + return clrmath_asinh(x); FCIMPLEND /*=====================================Atan===================================== @@ -93,7 +60,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Atan, double x) FCALL_CONTRACT; - return atan(x); + return clrmath_atan(x); FCIMPLEND /*=====================================Atanh==================================== @@ -102,7 +69,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Atanh, double x) FCALL_CONTRACT; - return atanh(x); + return clrmath_atanh(x); FCIMPLEND /*=====================================Atan2==================================== @@ -111,7 +78,7 @@ FCIMPLEND FCIMPL2_VV(double, COMDouble::Atan2, double y, double x) FCALL_CONTRACT; - return atan2(y, x); + return clrmath_atan2(y, x); FCIMPLEND /*====================================Cbrt====================================== @@ -120,36 +87,25 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Cbrt, double x) FCALL_CONTRACT; - return cbrt(x); + return clrmath_cbrt(x); FCIMPLEND -#if defined(_MSC_VER) && defined(TARGET_AMD64) -// The /fp:fast form of `ceil` for AMD64 does not correctly handle: `-1.0 < value <= -0.0` -// https://github.com/dotnet/runtime/issues/11003 -#pragma float_control(push) -#pragma float_control(precise, on) -#endif - /*====================================Ceil====================================== ** ==============================================================================*/ FCIMPL1_V(double, COMDouble::Ceil, double x) FCALL_CONTRACT; - return ceil(x); + return clrmath_ceil(x); FCIMPLEND -#if defined(_MSC_VER) && defined(TARGET_AMD64) -#pragma float_control(pop) -#endif - /*=====================================Cos====================================== ** ==============================================================================*/ FCIMPL1_V(double, COMDouble::Cos, double x) FCALL_CONTRACT; - return cos(x); + return clrmath_cos(x); FCIMPLEND /*=====================================Cosh===================================== @@ -158,7 +114,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Cosh, double x) FCALL_CONTRACT; - return cosh(x); + return clrmath_cosh(x); FCIMPLEND /*=====================================Exp====================================== @@ -167,36 +123,25 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Exp, double x) FCALL_CONTRACT; - return exp(x); + return clrmath_exp(x); FCIMPLEND -#if defined(_MSC_VER) && defined(TARGET_X86) -// The /fp:fast form of `floor` for x86 does not correctly handle: `-0.0` -// https://github.com/dotnet/runtime/issues/11003 -#pragma float_control(push) -#pragma float_control(precise, on) -#endif - /*====================================Floor===================================== ** ==============================================================================*/ FCIMPL1_V(double, COMDouble::Floor, double x) FCALL_CONTRACT; - return floor(x); + return clrmath_floor(x); FCIMPLEND -#if defined(_MSC_VER) && defined(TARGET_X86) -#pragma float_control(pop) -#endif - /*=====================================FMod===================================== ** ==============================================================================*/ FCIMPL2_VV(double, COMDouble::FMod, double x, double y) FCALL_CONTRACT; - return fmod(x, y); + return clrmath_fmod(x, y); FCIMPLEND /*=====================================FusedMultiplyAdd========================== @@ -205,7 +150,7 @@ FCIMPLEND FCIMPL3_VVV(double, COMDouble::FusedMultiplyAdd, double x, double y, double z) FCALL_CONTRACT; - return fma(x, y, z); + return clrmath_fma(x, y, z); FCIMPLEND /*=====================================Ilog2==================================== @@ -214,7 +159,7 @@ FCIMPLEND FCIMPL1_V(int, COMDouble::ILogB, double x) FCALL_CONTRACT; - return ilogb(x); + return clrmath_ilogb(x); FCIMPLEND /*=====================================Log====================================== @@ -223,7 +168,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Log, double x) FCALL_CONTRACT; - return log(x); + return clrmath_log(x); FCIMPLEND /*=====================================Log2===================================== @@ -232,7 +177,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Log2, double x) FCALL_CONTRACT; - return log2(x); + return clrmath_log2(x); FCIMPLEND /*====================================Log10===================================== @@ -241,7 +186,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Log10, double x) FCALL_CONTRACT; - return log10(x); + return clrmath_log10(x); FCIMPLEND /*=====================================ModF===================================== @@ -250,7 +195,7 @@ FCIMPLEND FCIMPL2_VI(double, COMDouble::ModF, double x, double* intptr) FCALL_CONTRACT; - return modf(x, intptr); + return clrmath_modf(x, intptr); FCIMPLEND /*=====================================Pow====================================== @@ -259,7 +204,7 @@ FCIMPLEND FCIMPL2_VV(double, COMDouble::Pow, double x, double y) FCALL_CONTRACT; - return pow(x, y); + return clrmath_pow(x, y); FCIMPLEND /*=====================================Sin====================================== @@ -268,20 +213,20 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Sin, double x) FCALL_CONTRACT; - return sin(x); + return clrmath_sin(x); FCIMPLEND /*====================================SinCos==================================== ** ==============================================================================*/ -FCIMPL3_VII(void, COMDouble::SinCos, double x, double* pSin, double* pCos) +FCIMPL3_VII(void, COMDouble::SinCos, double x, double* sinr, double* cosr) FCALL_CONTRACT; #ifdef _MSC_VER - *pSin = sin(x); - *pCos = cos(x); + *sinr = sin(x); + *cosr = cos(x); #else - sincos(x, pSin, pCos); + sincos(x, sinr, cosr); #endif FCIMPLEND @@ -292,7 +237,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Sinh, double x) FCALL_CONTRACT; - return sinh(x); + return clrmath_sinh(x); FCIMPLEND /*=====================================Sqrt===================================== @@ -301,7 +246,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Sqrt, double x) FCALL_CONTRACT; - return sqrt(x); + return clrmath_sqrt(x); FCIMPLEND /*=====================================Tan====================================== @@ -310,7 +255,7 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Tan, double x) FCALL_CONTRACT; - return tan(x); + return clrmath_tan(x); FCIMPLEND /*=====================================Tanh===================================== @@ -319,19 +264,5 @@ FCIMPLEND FCIMPL1_V(double, COMDouble::Tanh, double x) FCALL_CONTRACT; - return tanh(x); + return clrmath_tanh(x); FCIMPLEND - -#ifdef _MSC_VER -#pragma float_control(pop) -#endif - -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -/// -/// End of /fp:fast scope -/// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/classlibnative/float/floatsingle.cpp b/src/coreclr/classlibnative/float/floatsingle.cpp index e2e7d8f638da5f..3765f205f52b7e 100644 --- a/src/coreclr/classlibnative/float/floatsingle.cpp +++ b/src/coreclr/classlibnative/float/floatsingle.cpp @@ -7,38 +7,7 @@ #include #include "floatsingle.h" - -// Windows x86 and Windows ARM/ARM64 may not define _isnanf() or _copysignf() but they do -// define _isnan() and _copysign(). We will redirect the macros to these other functions if -// the macro is not defined for the platform. This has the side effect of a possible implicit -// upcasting for arguments passed in and an explicit downcasting for the _copysign() call. -#if (defined(TARGET_X86) || defined(TARGET_ARM) || defined(TARGET_ARM64)) && !defined(TARGET_UNIX) - -#if !defined(_copysignf) -#define _copysignf (float)_copysign -#endif - -#endif - -// The default compilation mode is /fp:precise, which disables floating-point intrinsics. This -// default compilation mode has previously caused performance regressions in floating-point code. -// We enable /fp:fast semantics for the majority of the math functions, as it will speed up performance -// and is really unlikely to cause any other code regressions. - -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -/// -/// beginning of /fp:fast scope -/// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// - -#ifdef _MSC_VER -#pragma float_control(push) -#pragma float_control(precise, off) -#endif +#include "clrmath.h" /*=====================================Abs===================================== ** @@ -46,7 +15,7 @@ FCIMPL1_V(float, COMSingle::Abs, float x) FCALL_CONTRACT; - return fabsf(x); + return clrmath_fabsf(x); FCIMPLEND /*=====================================Acos===================================== @@ -55,7 +24,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Acos, float x) FCALL_CONTRACT; - return acosf(x); + return clrmath_acosf(x); FCIMPLEND /*=====================================Acosh==================================== @@ -64,7 +33,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Acosh, float x) FCALL_CONTRACT; - return acoshf(x); + return clrmath_acoshf(x); FCIMPLEND /*=====================================Asin===================================== @@ -73,7 +42,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Asin, float x) FCALL_CONTRACT; - return asinf(x); + return clrmath_asinf(x); FCIMPLEND /*=====================================Asinh==================================== @@ -82,7 +51,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Asinh, float x) FCALL_CONTRACT; - return asinhf(x); + return clrmath_asinhf(x); FCIMPLEND /*=====================================Atan===================================== @@ -91,7 +60,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Atan, float x) FCALL_CONTRACT; - return atanf(x); + return clrmath_atanf(x); FCIMPLEND /*=====================================Atanh==================================== @@ -100,7 +69,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Atanh, float x) FCALL_CONTRACT; - return atanhf(x); + return clrmath_atanhf(x); FCIMPLEND /*=====================================Atan2==================================== @@ -109,7 +78,7 @@ FCIMPLEND FCIMPL2_VV(float, COMSingle::Atan2, float y, float x) FCALL_CONTRACT; - return atan2f(y, x); + return clrmath_atan2f(y, x); FCIMPLEND /*====================================Cbrt====================================== @@ -118,36 +87,25 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Cbrt, float x) FCALL_CONTRACT; - return cbrtf(x); + return clrmath_cbrtf(x); FCIMPLEND -#if defined(_MSC_VER) && defined(TARGET_AMD64) -// The /fp:fast form of `ceilf` for AMD64 does not correctly handle: `-1.0 < value <= -0.0` -// https://github.com/dotnet/runtime/issues/11003 -#pragma float_control(push) -#pragma float_control(precise, on) -#endif - /*====================================Ceil====================================== ** ==============================================================================*/ FCIMPL1_V(float, COMSingle::Ceil, float x) FCALL_CONTRACT; - return ceilf(x); + return clrmath_ceilf(x); FCIMPLEND -#if defined(_MSC_VER) && defined(TARGET_AMD64) -#pragma float_control(pop) -#endif - /*=====================================Cos====================================== ** ==============================================================================*/ FCIMPL1_V(float, COMSingle::Cos, float x) FCALL_CONTRACT; - return cosf(x); + return clrmath_cosf(x); FCIMPLEND /*=====================================Cosh===================================== @@ -156,7 +114,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Cosh, float x) FCALL_CONTRACT; - return coshf(x); + return clrmath_coshf(x); FCIMPLEND /*=====================================Exp====================================== @@ -165,7 +123,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Exp, float x) FCALL_CONTRACT; - return expf(x); + return clrmath_expf(x); FCIMPLEND /*====================================Floor===================================== @@ -174,7 +132,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Floor, float x) FCALL_CONTRACT; - return floorf(x); + return clrmath_floorf(x); FCIMPLEND /*=====================================FMod===================================== @@ -183,7 +141,7 @@ FCIMPLEND FCIMPL2_VV(float, COMSingle::FMod, float x, float y) FCALL_CONTRACT; - return fmodf(x, y); + return clrmath_fmodf(x, y); FCIMPLEND /*=====================================FusedMultiplyAdd========================== @@ -192,7 +150,7 @@ FCIMPLEND FCIMPL3_VVV(float, COMSingle::FusedMultiplyAdd, float x, float y, float z) FCALL_CONTRACT; - return fmaf(x, y, z); + return clrmath_fmaf(x, y, z); FCIMPLEND /*=====================================Ilog2==================================== @@ -201,7 +159,7 @@ FCIMPLEND FCIMPL1_V(int, COMSingle::ILogB, float x) FCALL_CONTRACT; - return ilogbf(x); + return clrmath_ilogbf(x); FCIMPLEND /*=====================================Log====================================== @@ -210,7 +168,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Log, float x) FCALL_CONTRACT; - return logf(x); + return clrmath_logf(x); FCIMPLEND /*=====================================Log2===================================== @@ -219,7 +177,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Log2, float x) FCALL_CONTRACT; - return log2f(x); + return clrmath_log2f(x); FCIMPLEND /*====================================Log10===================================== @@ -237,7 +195,7 @@ FCIMPLEND FCIMPL2_VI(float, COMSingle::ModF, float x, float* intptr) FCALL_CONTRACT; - return modff(x, intptr); + return clrmath_modff(x, intptr); FCIMPLEND /*=====================================Pow====================================== @@ -246,7 +204,7 @@ FCIMPLEND FCIMPL2_VV(float, COMSingle::Pow, float x, float y) FCALL_CONTRACT; - return powf(x, y); + return clrmath_powf(x, y); FCIMPLEND /*=====================================Sin====================================== @@ -255,20 +213,20 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Sin, float x) FCALL_CONTRACT; - return sinf(x); + return clrmath_sinf(x); FCIMPLEND /*====================================SinCos==================================== ** ==============================================================================*/ -FCIMPL3_VII(void, COMSingle::SinCos, float x, float* pSin, float* pCos) +FCIMPL3_VII(void, COMSingle::SinCos, float x, float* sinr, float* cosr) FCALL_CONTRACT; #ifdef _MSC_VER - *pSin = sinf(x); - *pCos = cosf(x); + *sinr = sinf(x); + *cosr = cosf(x); #else - sincosf(x, pSin, pCos); + sincosf(x, sinr, cosr); #endif FCIMPLEND @@ -279,7 +237,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Sinh, float x) FCALL_CONTRACT; - return sinhf(x); + return clrmath_sinhf(x); FCIMPLEND /*=====================================Sqrt===================================== @@ -288,7 +246,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Sqrt, float x) FCALL_CONTRACT; - return sqrtf(x); + return clrmath_sqrtf(x); FCIMPLEND /*=====================================Tan====================================== @@ -297,7 +255,7 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Tan, float x) FCALL_CONTRACT; - return tanf(x); + return clrmath_tanf(x); FCIMPLEND /*=====================================Tanh===================================== @@ -306,19 +264,5 @@ FCIMPLEND FCIMPL1_V(float, COMSingle::Tanh, float x) FCALL_CONTRACT; - return tanhf(x); + return clrmath_tanhf(x); FCIMPLEND - -#ifdef _MSC_VER -#pragma float_control(pop) -#endif - -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -/// -/// End of /fp:fast scope -/// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/classlibnative/inc/floatdouble.h b/src/coreclr/classlibnative/inc/floatdouble.h index 80e49c0bd7ee5c..44318d1ce6d7b9 100644 --- a/src/coreclr/classlibnative/inc/floatdouble.h +++ b/src/coreclr/classlibnative/inc/floatdouble.h @@ -32,7 +32,7 @@ class COMDouble { FCDECL2_VI(static double, ModF, double x, double* intptr); FCDECL2_VV(static double, Pow, double x, double y); FCDECL1_V(static double, Sin, double x); - FCDECL3_VII(static void, SinCos, double x, double* sin, double* cos); + FCDECL3_VII(static void, SinCos, double x, double* sinr, double* cosr); FCDECL1_V(static double, Sinh, double x); FCDECL1_V(static double, Sqrt, double x); FCDECL1_V(static double, Tan, double x); diff --git a/src/coreclr/classlibnative/inc/floatsingle.h b/src/coreclr/classlibnative/inc/floatsingle.h index e14bebb3867bd6..cd0b1502abcbc2 100644 --- a/src/coreclr/classlibnative/inc/floatsingle.h +++ b/src/coreclr/classlibnative/inc/floatsingle.h @@ -32,7 +32,7 @@ class COMSingle { FCDECL2_VI(static float, ModF, float x, float* intptr); FCDECL2_VV(static float, Pow, float x, float y); FCDECL1_V(static float, Sin, float x); - FCDECL3_VII(static void, SinCos, float x, float* sin, float* cos); + FCDECL3_VII(static void, SinCos, float x, float* sinr, float* cosr); FCDECL1_V(static float, Sinh, float x); FCDECL1_V(static float, Sqrt, float x); FCDECL1_V(static float, Tan, float x); diff --git a/src/coreclr/jit/CMakeLists.txt b/src/coreclr/jit/CMakeLists.txt index 8d30df4c74bedd..fcc8079cb0fc1c 100644 --- a/src/coreclr/jit/CMakeLists.txt +++ b/src/coreclr/jit/CMakeLists.txt @@ -431,6 +431,7 @@ function(add_jit jitName) ${JIT_ARCH_SOURCES} ${JIT_DEF_FILE} ${JIT_DLL_MAIN_FILE} + ${SHARED_CLRMATH_SOURCES} ) if(CLR_CMAKE_TARGET_WIN32) diff --git a/src/coreclr/jit/jitpch.h b/src/coreclr/jit/jitpch.h index 61954c4288e670..176a18333595ba 100644 --- a/src/coreclr/jit/jitpch.h +++ b/src/coreclr/jit/jitpch.h @@ -29,3 +29,4 @@ #include "bitvec.h" #include "inline.h" #include "objectalloc.h" +#include "clrmath.h" diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 3957ff13c34700..a7f468ed95ae83 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -4619,75 +4619,75 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, NamedIntrinsic gtMathFN switch (gtMathFN) { case NI_System_Math_Abs: - res = fabs(arg0Val); + res = clrmath_fabs(arg0Val); break; case NI_System_Math_Acos: - res = acos(arg0Val); + res = clrmath_acos(arg0Val); break; case NI_System_Math_Acosh: - res = acosh(arg0Val); + res = clrmath_acosh(arg0Val); break; case NI_System_Math_Asin: - res = asin(arg0Val); + res = clrmath_asin(arg0Val); break; case NI_System_Math_Asinh: - res = asinh(arg0Val); + res = clrmath_asinh(arg0Val); break; case NI_System_Math_Atan: - res = atan(arg0Val); + res = clrmath_atan(arg0Val); break; case NI_System_Math_Atanh: - res = atanh(arg0Val); + res = clrmath_atanh(arg0Val); break; case NI_System_Math_Cbrt: - res = cbrt(arg0Val); + res = clrmath_cbrt(arg0Val); break; case NI_System_Math_Ceiling: - res = ceil(arg0Val); + res = clrmath_ceil(arg0Val); break; case NI_System_Math_Cos: - res = cos(arg0Val); + res = clrmath_cos(arg0Val); break; case NI_System_Math_Cosh: - res = cosh(arg0Val); + res = clrmath_cosh(arg0Val); break; case NI_System_Math_Exp: - res = exp(arg0Val); + res = clrmath_exp(arg0Val); break; case NI_System_Math_Floor: - res = floor(arg0Val); + res = clrmath_floor(arg0Val); break; case NI_System_Math_Log: - res = log(arg0Val); + res = clrmath_log(arg0Val); break; case NI_System_Math_Log2: - res = log2(arg0Val); + res = clrmath_log2(arg0Val); break; case NI_System_Math_Log10: - res = log10(arg0Val); + res = clrmath_log10(arg0Val); break; case NI_System_Math_Sin: - res = sin(arg0Val); + res = clrmath_sin(arg0Val); break; case NI_System_Math_Sinh: - res = sinh(arg0Val); + res = clrmath_sinh(arg0Val); break; case NI_System_Math_Round: @@ -4695,15 +4695,15 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, NamedIntrinsic gtMathFN break; case NI_System_Math_Sqrt: - res = sqrt(arg0Val); + res = clrmath_sqrt(arg0Val); break; case NI_System_Math_Tan: - res = tan(arg0Val); + res = clrmath_tan(arg0Val); break; case NI_System_Math_Tanh: - res = tanh(arg0Val); + res = clrmath_tanh(arg0Val); break; default: @@ -4723,75 +4723,75 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, NamedIntrinsic gtMathFN switch (gtMathFN) { case NI_System_Math_Abs: - res = fabsf(arg0Val); + res = clrmath_fabsf(arg0Val); break; case NI_System_Math_Acos: - res = acosf(arg0Val); + res = clrmath_acosf(arg0Val); break; case NI_System_Math_Acosh: - res = acoshf(arg0Val); + res = clrmath_acoshf(arg0Val); break; case NI_System_Math_Asin: - res = asinf(arg0Val); + res = clrmath_asinf(arg0Val); break; case NI_System_Math_Asinh: - res = asinhf(arg0Val); + res = clrmath_asinhf(arg0Val); break; case NI_System_Math_Atan: - res = atanf(arg0Val); + res = clrmath_atanf(arg0Val); break; case NI_System_Math_Atanh: - res = atanhf(arg0Val); + res = clrmath_atanhf(arg0Val); break; case NI_System_Math_Cbrt: - res = cbrtf(arg0Val); + res = clrmath_cbrtf(arg0Val); break; case NI_System_Math_Ceiling: - res = ceilf(arg0Val); + res = clrmath_ceilf(arg0Val); break; case NI_System_Math_Cos: - res = cosf(arg0Val); + res = clrmath_cosf(arg0Val); break; case NI_System_Math_Cosh: - res = coshf(arg0Val); + res = clrmath_coshf(arg0Val); break; case NI_System_Math_Exp: - res = expf(arg0Val); + res = clrmath_expf(arg0Val); break; case NI_System_Math_Floor: - res = floorf(arg0Val); + res = clrmath_floorf(arg0Val); break; case NI_System_Math_Log: - res = logf(arg0Val); + res = clrmath_logf(arg0Val); break; case NI_System_Math_Log2: - res = log2f(arg0Val); + res = clrmath_log2f(arg0Val); break; case NI_System_Math_Log10: - res = log10f(arg0Val); + res = clrmath_log10f(arg0Val); break; case NI_System_Math_Sin: - res = sinf(arg0Val); + res = clrmath_sinf(arg0Val); break; case NI_System_Math_Sinh: - res = sinhf(arg0Val); + res = clrmath_sinhf(arg0Val); break; case NI_System_Math_Round: @@ -4799,15 +4799,15 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, NamedIntrinsic gtMathFN break; case NI_System_Math_Sqrt: - res = sqrtf(arg0Val); + res = clrmath_sqrtf(arg0Val); break; case NI_System_Math_Tan: - res = tanf(arg0Val); + res = clrmath_tanf(arg0Val); break; case NI_System_Math_Tanh: - res = tanhf(arg0Val); + res = clrmath_tanhf(arg0Val); break; default: @@ -4829,14 +4829,14 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, NamedIntrinsic gtMathFN case TYP_DOUBLE: { double arg0Val = GetConstantDouble(arg0VN); - res = ilogb(arg0Val); + res = clrmath_ilogb(arg0Val); break; } case TYP_FLOAT: { float arg0Val = GetConstantSingle(arg0VN); - res = ilogbf(arg0Val); + res = clrmath_ilogbf(arg0Val); break; } @@ -4998,7 +4998,7 @@ ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, NamedIntrinsic gtMathF { assert(typ == TypeOfVN(arg1VN)); double arg1Val = GetConstantDouble(arg1VN); - res = atan2(arg0Val, arg1Val); + res = clrmath_atan2(arg0Val, arg1Val); break; } @@ -5006,7 +5006,7 @@ ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, NamedIntrinsic gtMathF { assert(typ == TypeOfVN(arg1VN)); double arg1Val = GetConstantDouble(arg1VN); - res = fmod(arg0Val, arg1Val); + res = clrmath_fmod(arg0Val, arg1Val); break; } @@ -5014,7 +5014,7 @@ ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, NamedIntrinsic gtMathF { assert(typ == TypeOfVN(arg1VN)); double arg1Val = GetConstantDouble(arg1VN); - res = pow(arg0Val, arg1Val); + res = clrmath_pow(arg0Val, arg1Val); break; } @@ -5039,7 +5039,7 @@ ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, NamedIntrinsic gtMathF { assert(typ == TypeOfVN(arg1VN)); float arg1Val = GetConstantSingle(arg1VN); - res = atan2f(arg0Val, arg1Val); + res = clrmath_atan2f(arg0Val, arg1Val); break; } @@ -5047,7 +5047,7 @@ ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, NamedIntrinsic gtMathF { assert(typ == TypeOfVN(arg1VN)); float arg1Val = GetConstantSingle(arg1VN); - res = fmodf(arg0Val, arg1Val); + res = clrmath_fmodf(arg0Val, arg1Val); break; } @@ -5055,7 +5055,7 @@ ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, NamedIntrinsic gtMathF { assert(typ == TypeOfVN(arg1VN)); float arg1Val = GetConstantSingle(arg1VN); - res = powf(arg0Val, arg1Val); + res = clrmath_powf(arg0Val, arg1Val); break; } diff --git a/src/native/clrmath/CMakeLists.txt b/src/native/clrmath/CMakeLists.txt new file mode 100644 index 00000000000000..521eb2c3b179fc --- /dev/null +++ b/src/native/clrmath/CMakeLists.txt @@ -0,0 +1,8 @@ +set(SHARED_CLRMATH_BASE_DIR ${CMAKE_CURRENT_LIST_DIR}) + +set(SHARED_CLRMATH_INCLUDE_DIR ${SHARED_CLRMATH_BASE_DIR}/inc) +set(SHARED_CLRMATH_SOURCE_DIR ${SHARED_CLRMATH_BASE_DIR}/src) + +set(SHARED_CLRMATH_SOURCES "") + +include_directories("${SHARED_CLRMATH_INCLUDE_DIR}") diff --git a/src/native/clrmath/inc/clrmath.h b/src/native/clrmath/inc/clrmath.h new file mode 100644 index 00000000000000..07a3aca8ad0ade --- /dev/null +++ b/src/native/clrmath/inc/clrmath.h @@ -0,0 +1,251 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef _CLRMATH_H_ +#define _CLRMATH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + /********************************/ + /* 7.12.3 Classification Macros */ + /********************************/ + + // fpclassify + // isfinite + // isinf + // isnan + // isnormal + // signbit + + /**********************************/ + /* 7.12.4 Trigonometric functions */ + /**********************************/ + + #define clrmath_acos acos + #define clrmath_acosf acosf + + #define clrmath_asin asin + #define clrmath_asinf asinf + + #define clrmath_atan atan + #define clrmath_atanf atanf + + #define clrmath_atan2 atan2 + #define clrmath_atan2f atan2f + + #define clrmath_cos cos + #define clrmath_cosf cosf + + #define clrmath_sin sin + #define clrmath_sinf sinf + + #define clrmath_tan tan + #define clrmath_tanf tanf + + /*******************************/ + /* 7.12.5 Hyperbolic functions */ + /*******************************/ + + #define clrmath_acosh acosh + #define clrmath_acoshf acoshf + + #define clrmath_asinh asinh + #define clrmath_asinhf asinhf + + #define clrmath_atanh atan + #define clrmath_atanhf atanhf + + #define clrmath_cosh cosh + #define clrmath_coshf coshf + + #define clrmath_sinh sinh + #define clrmath_sinhf sinhf + + #define clrmath_tanh tanh + #define clrmath_tanhf tanhf + + /************************************************/ + /* 7.12.6 Exponential and logarithmic functions */ + /************************************************/ + + #define clrmath_exp exp + #define clrmath_expf expf + + #define clrmath_exp2 exp2 + #define clrmath_exp2f exp2f + + #define clrmath_expm1 expm1 + #define clrmath_expm1f expm1f + + #define clrmath_frexp frexp + #define clrmath_frexpf frexpf + + #define clrmath_ilogb ilogb + #define clrmath_ilogbf ilogbf + + #define clrmath_ldexp ldexp + #define clrmath_ldexpf ldexpf + + #define clrmath_log log + #define clrmath_logf logf + + #define clrmath_log10 log10 + #define clrmath_log10f log10f + + #define clrmath_logb logb + #define clrmath_logbf logbf + + #define clrmath_log1p log1p + #define clrmath_log1pf log1pf + + #define clrmath_log2 log2 + #define clrmath_log2f log2f + + #define clrmath_logb logb + #define clrmath_logbf logbf + + #define clrmath_modf modf + #define clrmath_modff modff + + #define clrmath_scalbn scalbn + #define clrmath_scalbnf scalbnf + + #define clrmath_scalbln scalbln + #define clrmath_scalblnf scalblnf + + /*********************************************/ + /* 7.12.7 Power and absolute-value functions */ + /*********************************************/ + + #define clrmath_cbrt cbrt + #define clrmath_cbrtf cbrtf + + #define clrmath_fabs fabs + #define clrmath_fabsf fabsf + + #define clrmath_hypot hypot + #define clrmath_hypotf hypot + + #define clrmath_pow pow + #define clrmath_powf powf + + #define clrmath_sqrt sqrt + #define clrmath_sqrtf sqrtf + + /************************************/ + /* 7.12.8 Error and gamma functions */ + /************************************/ + + #define clrmath_erf erf + #define clrmath_erff erff + + #define clrmath_erfc erfc + #define clrmath_erfcf erfcf + + #define clrmath_lgamma lgamma + #define clrmath_lgammaf lgammaf + + #define clrmath_tgamma tgamma + #define clrmath_tgammaf tgammaf + + /************************************/ + /* 7.12.9 Nearest integer functions */ + /************************************/ + + #define clrmath_ceil ceil + #define clrmath_ceilf ceilf + + #define clrmath_floor floor + #define clrmath_floorf floorf + + #define clrmath_nearbyint nearbyint + #define clrmath_nearbyintf nearbyintf + + #define clrmath_rint rint + #define clrmath_rintf rintf + + #define clrmath_lrint lrint + #define clrmath_lrintf lrintf + + #define clrmath_llrint llrint + #define clrmath_llrintf llrintf + + #define clrmath_round round + #define clrmath_roundf roundf + + #define clrmath_lround lround + #define clrmath_lroundf lroundf + + #define clrmath_llround llround + #define clrmath_llroundf llroundf + + #define clrmath_trunc trunc + #define clrmath_truncf truncf + + /*******************************/ + /* 7.12.10 Remainder functions */ + /*******************************/ + + #define clrmath_fmod fmod + #define clrmath_fmodf fmodf + + #define clrmath_remainder remainder + #define clrmath_remainderf remainderf + + #define clrmath_remquo remquo + #define clrmath_remquof remquof + + /**********************************/ + /* 7.12.11 Manipulation functions */ + /**********************************/ + + #define clrmath_copysign copysign + #define clrmath_copysignf copysignf + + #define clrmath_nan nan + #define clrmath_nanf nanf + + #define clrmath_nextafter nextafter + #define clrmath_nextafterf nextafterf + + #define clrmath_nexttoward nexttoward + #define clrmath_nexttowardf nexttowardf + + /***************************************************************/ + /* 7.12.12 Maximum, minimum, and positive difference functions */ + /***************************************************************/ + + #define clrmath_fdim fdim + #define clrmath_fdimf fdimf + + #define clrmath_fmax fmax + #define clrmath_fmaxf fmaxf + + #define clrmath_fmin fmin + #define clrmath_fminf fminf + + /*************************************/ + /* 7.12.13 Floating multiply-address */ + /*************************************/ + + #define clrmath_fma fma + #define clrmath_fmaf fmaf + + /*****************************/ + /* 7.12.14 Comparison Macros */ + /*****************************/ + + // isgreater + // isgreaterequal + // isless + // islessequal + // islessgreater + // isunordered + +#ifdef __cplusplus +} +#endif + +#endif // _CLRMATH_H_ From 095eef030062950a025459baf94f345f20e34bde Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sat, 17 Apr 2021 14:26:10 -0700 Subject: [PATCH 2/2] Updating most math functions to use the aocl-libm-ose implementation --- THIRD-PARTY-NOTICES.TXT | 27 + src/coreclr/pal/inc/pal.h | 42 +- src/coreclr/pal/src/config.h.in | 9 - src/coreclr/pal/src/configure.cmake | 181 - src/coreclr/pal/src/cruntime/math.cpp | 548 --- src/coreclr/pal/src/include/pal/palinternal.h | 2 + src/coreclr/pal/tests/palsuite/CMakeLists.txt | 39 - .../palsuite/c_runtime/acos/test1/test1.cpp | 129 - .../palsuite/c_runtime/acosf/test1/test1.cpp | 128 - .../palsuite/c_runtime/acosh/test1/test1.cpp | 128 - .../palsuite/c_runtime/acoshf/test1/test1.cpp | 127 - .../palsuite/c_runtime/asin/test1/test1.cpp | 145 - .../palsuite/c_runtime/asinf/test1/test1.cpp | 144 - .../palsuite/c_runtime/asinh/test1/test1.cpp | 145 - .../palsuite/c_runtime/asinhf/test1/test1.cpp | 144 - .../palsuite/c_runtime/atan/test1/test1.cpp | 127 - .../palsuite/c_runtime/atan2/test1/test1.cpp | 147 - .../palsuite/c_runtime/atan2f/test1/test1.cpp | 146 - .../palsuite/c_runtime/atanf/test1/test1.cpp | 126 - .../palsuite/c_runtime/atanh/test1/test1.cpp | 129 - .../palsuite/c_runtime/atanhf/test1/test1.cpp | 128 - .../palsuite/c_runtime/ceil/test1/test1.cpp | 131 - .../palsuite/c_runtime/ceilf/test1/test1.cpp | 130 - .../palsuite/c_runtime/cos/test1/test1.cpp | 130 - .../palsuite/c_runtime/cosf/test1/test1.cpp | 129 - .../palsuite/c_runtime/cosh/test1/test1.cpp | 129 - .../palsuite/c_runtime/coshf/test1/test1.cpp | 128 - .../palsuite/c_runtime/exp/test1/test1.cpp | 137 - .../palsuite/c_runtime/expf/test1/test1.cpp | 136 - .../palsuite/c_runtime/floor/test1/test1.cpp | 131 - .../palsuite/c_runtime/floorf/test1/test1.cpp | 130 - .../palsuite/c_runtime/ilogb/test1/test1.cpp | 100 - .../palsuite/c_runtime/ilogbf/test1/test1.cpp | 100 - .../palsuite/c_runtime/logf/test1/test1.cpp | 138 - .../palsuite/c_runtime/modf/test1/test1.cpp | 135 - .../palsuite/c_runtime/modff/test1/test1.cpp | 134 - .../palsuite/c_runtime/pow/test1/test1.cpp | 229 -- .../palsuite/c_runtime/powf/test1/test1.cpp | 228 -- .../palsuite/c_runtime/sin/test1/test1.cpp | 130 - .../palsuite/c_runtime/sinf/test1/test1.cpp | 129 - .../palsuite/c_runtime/sinh/test1/test1.cpp | 129 - .../palsuite/c_runtime/sinhf/test1/test1.cpp | 128 - .../palsuite/c_runtime/tan/test1/test1.cpp | 136 - .../palsuite/c_runtime/tanf/test1/test1.cpp | 135 - .../palsuite/c_runtime/tanh/test1/test1.cpp | 129 - .../palsuite/c_runtime/tanhf/test1/test1.cpp | 128 - .../pal/tests/palsuite/compilableTests.txt | 39 - .../pal/tests/palsuite/paltestlist.txt | 39 - src/native/clrmath/CMakeLists.txt | 71 + src/native/clrmath/inc/clrmath.h | 83 +- src/native/clrmath/inc/libm/libm_constants.h | 91 + src/native/clrmath/inc/libm/libm_inlines.h | 9 + .../clrmath/inc/libm/libm_inlines_amd.h | 743 ++++ src/native/clrmath/inc/libm/libm_poly.h | 294 ++ src/native/clrmath/inc/libm/libm_special.h | 266 ++ src/native/clrmath/inc/libm/libm_typehelper.h | 101 + src/native/clrmath/inc/libm/libm_types.h | 64 + src/native/clrmath/inc/libm/libm_util.h | 74 + src/native/clrmath/inc/libm/libm_util_amd.h | 227 ++ src/native/clrmath/src/libm_special.cpp | 1247 +++++++ src/native/clrmath/src/opt/cos.cpp | 320 ++ src/native/clrmath/src/opt/cosf.cpp | 306 ++ src/native/clrmath/src/opt/coshf.cpp | 184 + .../clrmath/src/opt/data/_exp_j_by_64.cpp | 102 + .../opt/data/_exp_tbl_128_interleaved.data | 167 + .../src/opt/data/_exp_tbl_64_interleaved.data | 103 + src/native/clrmath/src/opt/data/_log_data.cpp | 292 ++ src/native/clrmath/src/opt/exp.cpp | 259 ++ src/native/clrmath/src/opt/exp_data.h | 145 + src/native/clrmath/src/opt/exp_tables.cpp | 862 +++++ src/native/clrmath/src/opt/expf.cpp | 190 + src/native/clrmath/src/opt/expf_data.h | 50 + src/native/clrmath/src/opt/log_tables.cpp | 621 ++++ src/native/clrmath/src/opt/logf.cpp | 215 ++ src/native/clrmath/src/opt/logf_data.h | 30 + src/native/clrmath/src/opt/pow.cpp | 448 +++ src/native/clrmath/src/opt/pow_data.cpp | 3122 +++++++++++++++++ src/native/clrmath/src/opt/powf.cpp | 456 +++ src/native/clrmath/src/opt/sin.cpp | 312 ++ src/native/clrmath/src/opt/sinf.cpp | 300 ++ src/native/clrmath/src/opt/tan.cpp | 410 +++ src/native/clrmath/src/opt/tanf.cpp | 301 ++ src/native/clrmath/src/opt/tanhf.cpp | 178 + src/native/clrmath/src/ref/acos.cpp | 144 + src/native/clrmath/src/ref/acosf.cpp | 144 + src/native/clrmath/src/ref/acosh.cpp | 407 +++ src/native/clrmath/src/ref/acoshf.cpp | 111 + src/native/clrmath/src/ref/asin.cpp | 164 + src/native/clrmath/src/ref/asinf.cpp | 160 + src/native/clrmath/src/ref/asinh.cpp | 315 ++ src/native/clrmath/src/ref/asinhf.cpp | 156 + src/native/clrmath/src/ref/atan.cpp | 138 + src/native/clrmath/src/ref/atan2.cpp | 748 ++++ src/native/clrmath/src/ref/atan2f.cpp | 479 +++ src/native/clrmath/src/ref/atanf.cpp | 140 + src/native/clrmath/src/ref/atanh.cpp | 150 + src/native/clrmath/src/ref/atanhf.cpp | 149 + src/native/clrmath/src/ref/ceil.cpp | 101 + src/native/clrmath/src/ref/ceilf.cpp | 93 + src/native/clrmath/src/ref/cosh.cpp | 334 ++ src/native/clrmath/src/ref/floor.cpp | 88 + src/native/clrmath/src/ref/floorf.cpp | 83 + src/native/clrmath/src/ref/ilogb.cpp | 101 + src/native/clrmath/src/ref/ilogbf.cpp | 102 + src/native/clrmath/src/ref/modf.cpp | 87 + src/native/clrmath/src/ref/modff.cpp | 81 + src/native/clrmath/src/ref/sinh.cpp | 337 ++ src/native/clrmath/src/ref/sinhf.cpp | 246 ++ src/native/clrmath/src/ref/tanh.cpp | 139 + 109 files changed, 17850 insertions(+), 6228 deletions(-) delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/acos/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/acosf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/acosh/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/acoshf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/asin/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/asinf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/asinh/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/asinhf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/atan/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/atan2/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/atan2f/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/atanf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/atanh/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/atanhf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/ceil/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/ceilf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/cos/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/cosf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/cosh/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/coshf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/exp/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/expf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/floor/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/floorf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/ilogb/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/ilogbf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/logf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/modf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/modff/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/powf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/sin/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/sinf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/sinh/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/sinhf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/tan/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/tanf/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/tanh/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/tanhf/test1/test1.cpp create mode 100644 src/native/clrmath/inc/libm/libm_constants.h create mode 100644 src/native/clrmath/inc/libm/libm_inlines.h create mode 100644 src/native/clrmath/inc/libm/libm_inlines_amd.h create mode 100644 src/native/clrmath/inc/libm/libm_poly.h create mode 100644 src/native/clrmath/inc/libm/libm_special.h create mode 100644 src/native/clrmath/inc/libm/libm_typehelper.h create mode 100644 src/native/clrmath/inc/libm/libm_types.h create mode 100644 src/native/clrmath/inc/libm/libm_util.h create mode 100644 src/native/clrmath/inc/libm/libm_util_amd.h create mode 100644 src/native/clrmath/src/libm_special.cpp create mode 100644 src/native/clrmath/src/opt/cos.cpp create mode 100644 src/native/clrmath/src/opt/cosf.cpp create mode 100644 src/native/clrmath/src/opt/coshf.cpp create mode 100644 src/native/clrmath/src/opt/data/_exp_j_by_64.cpp create mode 100644 src/native/clrmath/src/opt/data/_exp_tbl_128_interleaved.data create mode 100644 src/native/clrmath/src/opt/data/_exp_tbl_64_interleaved.data create mode 100644 src/native/clrmath/src/opt/data/_log_data.cpp create mode 100644 src/native/clrmath/src/opt/exp.cpp create mode 100644 src/native/clrmath/src/opt/exp_data.h create mode 100644 src/native/clrmath/src/opt/exp_tables.cpp create mode 100644 src/native/clrmath/src/opt/expf.cpp create mode 100644 src/native/clrmath/src/opt/expf_data.h create mode 100644 src/native/clrmath/src/opt/log_tables.cpp create mode 100644 src/native/clrmath/src/opt/logf.cpp create mode 100644 src/native/clrmath/src/opt/logf_data.h create mode 100644 src/native/clrmath/src/opt/pow.cpp create mode 100644 src/native/clrmath/src/opt/pow_data.cpp create mode 100644 src/native/clrmath/src/opt/powf.cpp create mode 100644 src/native/clrmath/src/opt/sin.cpp create mode 100644 src/native/clrmath/src/opt/sinf.cpp create mode 100644 src/native/clrmath/src/opt/tan.cpp create mode 100644 src/native/clrmath/src/opt/tanf.cpp create mode 100644 src/native/clrmath/src/opt/tanhf.cpp create mode 100644 src/native/clrmath/src/ref/acos.cpp create mode 100644 src/native/clrmath/src/ref/acosf.cpp create mode 100644 src/native/clrmath/src/ref/acosh.cpp create mode 100644 src/native/clrmath/src/ref/acoshf.cpp create mode 100644 src/native/clrmath/src/ref/asin.cpp create mode 100644 src/native/clrmath/src/ref/asinf.cpp create mode 100644 src/native/clrmath/src/ref/asinh.cpp create mode 100644 src/native/clrmath/src/ref/asinhf.cpp create mode 100644 src/native/clrmath/src/ref/atan.cpp create mode 100644 src/native/clrmath/src/ref/atan2.cpp create mode 100644 src/native/clrmath/src/ref/atan2f.cpp create mode 100644 src/native/clrmath/src/ref/atanf.cpp create mode 100644 src/native/clrmath/src/ref/atanh.cpp create mode 100644 src/native/clrmath/src/ref/atanhf.cpp create mode 100644 src/native/clrmath/src/ref/ceil.cpp create mode 100644 src/native/clrmath/src/ref/ceilf.cpp create mode 100644 src/native/clrmath/src/ref/cosh.cpp create mode 100644 src/native/clrmath/src/ref/floor.cpp create mode 100644 src/native/clrmath/src/ref/floorf.cpp create mode 100644 src/native/clrmath/src/ref/ilogb.cpp create mode 100644 src/native/clrmath/src/ref/ilogbf.cpp create mode 100644 src/native/clrmath/src/ref/modf.cpp create mode 100644 src/native/clrmath/src/ref/modff.cpp create mode 100644 src/native/clrmath/src/ref/sinh.cpp create mode 100644 src/native/clrmath/src/ref/sinhf.cpp create mode 100644 src/native/clrmath/src/ref/tanh.cpp diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT index b5571e67209f7a..bb2cdb5208ad69 100644 --- a/THIRD-PARTY-NOTICES.TXT +++ b/THIRD-PARTY-NOTICES.TXT @@ -948,3 +948,30 @@ OF SUCH DAMAGES. You acknowledge that this software is not designed, licensed or intended for use in the design, construction, operation or maintenance of any nuclear facility. + +License notice for aocl-libm-ose +----------------------------------- + + Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 2f42a2c4fdaf06..c322daf638668b 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -3797,23 +3797,10 @@ PAL_GetCurrentThreadAffinitySet(SIZE_T size, UINT_PTR* data); #define fgetpos PAL_fgetpos #define fsetpos PAL_fsetpos #define setvbuf PAL_setvbuf -#define acos PAL_acos -#define asin PAL_asin -#define atan2 PAL_atan2 -#define exp PAL_exp -#define ilogb PAL_ilogb #define log PAL_log #define log10 PAL_log10 -#define pow PAL_pow #define sincos PAL_sincos -#define acosf PAL_acosf -#define asinf PAL_asinf -#define atan2f PAL_atan2f -#define expf PAL_expf -#define ilogbf PAL_ilogbf -#define logf PAL_logf #define log10f PAL_log10f -#define powf PAL_powf #define sincosf PAL_sincosf #define malloc PAL_malloc #define free PAL_free @@ -4049,28 +4036,29 @@ PALIMPORT long long __cdecl llabs(long long); PALIMPORT int __cdecl _finite(double); PALIMPORT int __cdecl _isnan(double); PALIMPORT double __cdecl _copysign(double, double); -PALIMPORT double __cdecl acos(double); +PALIMPORT double __cdecl acos(double) MATH_THROW_DECL; PALIMPORT double __cdecl acosh(double) MATH_THROW_DECL; -PALIMPORT double __cdecl asin(double); +PALIMPORT double __cdecl asin(double) MATH_THROW_DECL; PALIMPORT double __cdecl asinh(double) MATH_THROW_DECL; PALIMPORT double __cdecl atan(double) MATH_THROW_DECL; PALIMPORT double __cdecl atanh(double) MATH_THROW_DECL; -PALIMPORT double __cdecl atan2(double, double); +PALIMPORT double __cdecl atan2(double, double) MATH_THROW_DECL; PALIMPORT double __cdecl cbrt(double) MATH_THROW_DECL; PALIMPORT double __cdecl ceil(double); PALIMPORT double __cdecl cos(double); PALIMPORT double __cdecl cosh(double); -PALIMPORT double __cdecl exp(double); +PALIMPORT double __cdecl exp(double) MATH_THROW_DECL; PALIMPORT double __cdecl fabs(double); PALIMPORT double __cdecl floor(double); PALIMPORT double __cdecl fmod(double, double); PALIMPORT double __cdecl fma(double, double, double) MATH_THROW_DECL; -PALIMPORT int __cdecl ilogb(double); +PALIMPORT int __cdecl ilogb(double) MATH_THROW_DECL; PALIMPORT double __cdecl log(double); +PALIMPORT double __cdecl log1p(double) MATH_THROW_DECL; PALIMPORT double __cdecl log2(double) MATH_THROW_DECL; PALIMPORT double __cdecl log10(double); PALIMPORT double __cdecl modf(double, double*); -PALIMPORT double __cdecl pow(double, double); +PALIMPORT double __cdecl pow(double, double) MATH_THROW_DECL; PALIMPORT double __cdecl sin(double); PALIMPORT void __cdecl sincos(double, double*, double*); PALIMPORT double __cdecl sinh(double); @@ -4081,34 +4069,36 @@ PALIMPORT double __cdecl tanh(double); PALIMPORT int __cdecl _finitef(float); PALIMPORT int __cdecl _isnanf(float); PALIMPORT float __cdecl _copysignf(float, float); -PALIMPORT float __cdecl acosf(float); +PALIMPORT float __cdecl acosf(float) MATH_THROW_DECL; PALIMPORT float __cdecl acoshf(float) MATH_THROW_DECL; -PALIMPORT float __cdecl asinf(float); +PALIMPORT float __cdecl asinf(float) MATH_THROW_DECL; PALIMPORT float __cdecl asinhf(float) MATH_THROW_DECL; PALIMPORT float __cdecl atanf(float) MATH_THROW_DECL; PALIMPORT float __cdecl atanhf(float) MATH_THROW_DECL; -PALIMPORT float __cdecl atan2f(float, float); +PALIMPORT float __cdecl atan2f(float, float) MATH_THROW_DECL; PALIMPORT float __cdecl cbrtf(float) MATH_THROW_DECL; PALIMPORT float __cdecl ceilf(float); PALIMPORT float __cdecl cosf(float); PALIMPORT float __cdecl coshf(float); -PALIMPORT float __cdecl expf(float); +PALIMPORT float __cdecl expf(float) MATH_THROW_DECL; PALIMPORT float __cdecl fabsf(float); PALIMPORT float __cdecl floorf(float); PALIMPORT float __cdecl fmodf(float, float); PALIMPORT float __cdecl fmaf(float, float, float) MATH_THROW_DECL; -PALIMPORT int __cdecl ilogbf(float); -PALIMPORT float __cdecl logf(float); +PALIMPORT int __cdecl ilogbf(float) MATH_THROW_DECL; +PALIMPORT float __cdecl logf(float) MATH_THROW_DECL; +PALIMPORT float __cdecl log1pf(float) MATH_THROW_DECL; PALIMPORT float __cdecl log2f(float) MATH_THROW_DECL; PALIMPORT float __cdecl log10f(float); PALIMPORT float __cdecl modff(float, float*); -PALIMPORT float __cdecl powf(float, float); +PALIMPORT float __cdecl powf(float, float) MATH_THROW_DECL; PALIMPORT float __cdecl sinf(float); PALIMPORT void __cdecl sincosf(float, float*, float*); PALIMPORT float __cdecl sinhf(float); PALIMPORT float __cdecl sqrtf(float); PALIMPORT float __cdecl tanf(float); PALIMPORT float __cdecl tanhf(float); + #endif // !PAL_STDCPP_COMPAT #ifndef PAL_STDCPP_COMPAT diff --git a/src/coreclr/pal/src/config.h.in b/src/coreclr/pal/src/config.h.in index c68421302e1153..314da4b476a9c3 100644 --- a/src/coreclr/pal/src/config.h.in +++ b/src/coreclr/pal/src/config.h.in @@ -124,15 +124,6 @@ #cmakedefine01 HAVE_PROCFS_MAPS #cmakedefine01 HAVE_PROCFS_STAT #cmakedefine01 HAVE_PROCFS_STATUS -#cmakedefine01 HAVE_COMPATIBLE_ACOS -#cmakedefine01 HAVE_COMPATIBLE_ASIN -#cmakedefine01 HAVE_COMPATIBLE_POW -#cmakedefine01 HAVE_VALID_NEGATIVE_INF_POW -#cmakedefine01 HAVE_VALID_POSITIVE_INF_POW -#cmakedefine01 HAVE_COMPATIBLE_ATAN2 -#cmakedefine01 HAVE_COMPATIBLE_EXP -#cmakedefine01 HAVE_COMPATIBLE_ILOGB0 -#cmakedefine01 HAVE_COMPATIBLE_ILOGBNAN #cmakedefine01 HAVE_COMPATIBLE_LOG #cmakedefine01 HAVE_COMPATIBLE_LOG10 #cmakedefine01 UNGETC_NOT_RETURN_EOF diff --git a/src/coreclr/pal/src/configure.cmake b/src/coreclr/pal/src/configure.cmake index ee4a3241196eaa..5e31b08845c11a 100644 --- a/src/coreclr/pal/src/configure.cmake +++ b/src/coreclr/pal/src/configure.cmake @@ -713,187 +713,6 @@ int main(void) { } exit(0); }" HAVE_PROCFS_STATUS) -set(CMAKE_REQUIRED_LIBRARIES m) -check_cxx_source_runs(" -#include -#include - -int main(void) { - volatile double x = 10; - if (!isnan(acos(x))) { - exit(1); - } - exit(0); -}" HAVE_COMPATIBLE_ACOS) -set(CMAKE_REQUIRED_LIBRARIES) -set(CMAKE_REQUIRED_LIBRARIES m) -check_cxx_source_runs(" -#include -#include - -int main(void) { - volatile double arg = 10; - if (!isnan(asin(arg))) { - exit(1); - } - exit(0); -}" HAVE_COMPATIBLE_ASIN) -set(CMAKE_REQUIRED_LIBRARIES) -set(CMAKE_REQUIRED_LIBRARIES m) -check_cxx_source_runs(" -#include -#include - -int main(void) { - volatile double base = 1.0; - volatile double infinity = 1.0 / 0.0; - if (pow(base, infinity) != 1.0 || pow(base, -infinity) != 1.0) { - exit(1); - } - if (pow(-base, infinity) != 1.0 || pow(-base, -infinity) != 1.0) { - exit(1); - } - - base = 0.0; - if (pow(base, infinity) != 0.0) { - exit(1); - } - if (pow(base, -infinity) != infinity) { - exit(1); - } - - base = 1.1; - if (pow(-base, infinity) != infinity || pow(base, infinity) != infinity) { - exit(1); - } - if (pow(-base, -infinity) != 0.0 || pow(base, -infinity) != 0.0) { - exit(1); - } - - base = 0.0; - volatile int iexp = 1; - if (pow(-base, -iexp) != -infinity) { - exit(1); - } - if (pow(base, -iexp) != infinity) { - exit(1); - } - exit(0); -}" HAVE_COMPATIBLE_POW) -set(CMAKE_REQUIRED_LIBRARIES) -set(CMAKE_REQUIRED_LIBRARIES m) -check_cxx_source_runs(" -#include -#include - -int main(int argc, char **argv) { - double result; - volatile double base = 3.2e-10; - volatile double exp = 1 - 5e14; - - result = pow(-base, exp); - if (result != -1.0 / 0.0) { - exit(1); - } - exit(0); -}" HAVE_VALID_NEGATIVE_INF_POW) -set(CMAKE_REQUIRED_LIBRARIES) -set(CMAKE_REQUIRED_LIBRARIES m) -check_cxx_source_runs(" -#include -#include - -int main(int argc, char **argv) { - double result; - volatile double base = 3.5; - volatile double exp = 3e100; - - result = pow(-base, exp); - if (result != 1.0 / 0.0) { - exit(1); - } - exit(0); -}" HAVE_VALID_POSITIVE_INF_POW) -set(CMAKE_REQUIRED_LIBRARIES) -set(CMAKE_REQUIRED_LIBRARIES m) -check_cxx_source_runs(" -#include -#include - -int main(void) { - double pi = 3.14159265358979323846; - double result; - volatile double y = 0.0; - volatile double x = 0.0; - - result = atan2(y, -x); - if (fabs(pi - result) > 0.0000001) { - exit(1); - } - - result = atan2(-y, -x); - if (fabs(-pi - result) > 0.0000001) { - exit(1); - } - - result = atan2 (-y, x); - if (result != 0.0 || copysign (1.0, result) > 0) { - exit(1); - } - - result = atan2 (y, x); - if (result != 0.0 || copysign (1.0, result) < 0) { - exit(1); - } - - exit (0); -}" HAVE_COMPATIBLE_ATAN2) -set(CMAKE_REQUIRED_LIBRARIES) -set(CMAKE_REQUIRED_LIBRARIES m) -check_cxx_source_runs(" -#include -#include - -int main(void) { - double d = exp(1.0), e = M_E; - - /* Used memcmp rather than == to test that the doubles are equal to - prevent gcc's optimizer from using its 80 bit internal long - doubles. If you use ==, then on BSD you get a false negative since - exp(1.0) == M_E to 64 bits, but not 80. - */ - - if (memcmp (&d, &e, sizeof (double)) == 0) { - exit(0); - } - exit(1); -}" HAVE_COMPATIBLE_EXP) -set(CMAKE_REQUIRED_LIBRARIES) -set(CMAKE_REQUIRED_LIBRARIES m) -check_cxx_source_runs(" -#include -#include - -int main(void) { - if (FP_ILOGB0 != -2147483648) { - exit(1); - } - - exit(0); -}" HAVE_COMPATIBLE_ILOGB0) -set(CMAKE_REQUIRED_LIBRARIES) -set(CMAKE_REQUIRED_LIBRARIES m) -check_cxx_source_runs(" -#include -#include - -int main(void) { - if (FP_ILOGBNAN != 2147483647) { - exit(1); - } - - exit(0); -}" HAVE_COMPATIBLE_ILOGBNAN) set(CMAKE_REQUIRED_LIBRARIES) set(CMAKE_REQUIRED_LIBRARIES m) check_cxx_source_runs(" diff --git a/src/coreclr/pal/src/cruntime/math.cpp b/src/coreclr/pal/src/cruntime/math.cpp index 14243f43a79c24..beb27c5c3f821d 100644 --- a/src/coreclr/pal/src/cruntime/math.cpp +++ b/src/coreclr/pal/src/cruntime/math.cpp @@ -110,175 +110,6 @@ double __cdecl _copysign(double x, double y) return ret; } -/*++ -Function: - acos - -See MSDN. ---*/ -PALIMPORT double __cdecl PAL_acos(double x) -{ - double ret; - PERF_ENTRY(acos); - ENTRY("acos (x=%f)\n", x); - -#if !HAVE_COMPATIBLE_ACOS - errno = 0; -#endif // HAVE_COMPATIBLE_ACOS - - ret = acos(x); - -#if !HAVE_COMPATIBLE_ACOS - if (errno == EDOM) - { - ret = PAL_NAN_DBL; // NaN - } -#endif // HAVE_COMPATIBLE_ACOS - - LOGEXIT("acos returns double %f\n", ret); - PERF_EXIT(acos); - return ret; -} - -/*++ -Function: - asin - -See MSDN. ---*/ -PALIMPORT double __cdecl PAL_asin(double x) -{ - double ret; - PERF_ENTRY(asin); - ENTRY("asin (x=%f)\n", x); - -#if !HAVE_COMPATIBLE_ASIN - errno = 0; -#endif // HAVE_COMPATIBLE_ASIN - - ret = asin(x); - -#if !HAVE_COMPATIBLE_ASIN - if (errno == EDOM) - { - ret = PAL_NAN_DBL; // NaN - } -#endif // HAVE_COMPATIBLE_ASIN - - LOGEXIT("asin returns double %f\n", ret); - PERF_EXIT(asin); - return ret; -} - -/*++ -Function: - atan2 - -See MSDN. ---*/ -PALIMPORT double __cdecl PAL_atan2(double y, double x) -{ - double ret; - PERF_ENTRY(atan2); - ENTRY("atan2 (y=%f, x=%f)\n", y, x); - -#if !HAVE_COMPATIBLE_ATAN2 - errno = 0; -#endif // !HAVE_COMPATIBLE_ATAN2 - - ret = atan2(y, x); - -#if !HAVE_COMPATIBLE_ATAN2 - if ((errno == EDOM) && (x == 0.0) && (y == 0.0)) - { - const double sign_x = copysign(1.0, x); - const double sign_y = copysign(1.0, y); - - if (sign_x > 0) - { - ret = copysign(0.0, sign_y); - } - else - { - ret = copysign(atan2(0.0, -1.0), sign_y); - } - } -#endif // !HAVE_COMPATIBLE_ATAN2 - - LOGEXIT("atan2 returns double %f\n", ret); - PERF_EXIT(atan2); - return ret; -} - -/*++ -Function: - exp - -See MSDN. ---*/ -PALIMPORT double __cdecl PAL_exp(double x) -{ - double ret; - PERF_ENTRY(exp); - ENTRY("exp (x=%f)\n", x); - -#if !HAVE_COMPATIBLE_EXP - if (x == 1.0) - { - ret = M_E; - } - else - { -#endif // HAVE_COMPATIBLE_EXP - - ret = exp(x); - -#if !HAVE_COMPATIBLE_EXP - } -#endif // HAVE_COMPATIBLE_EXP - - LOGEXIT("exp returns double %f\n", ret); - PERF_EXIT(exp); - return ret; -} - -/*++ -Function: - ilogb - -See MSDN. ---*/ -PALIMPORT int __cdecl PAL_ilogb(double x) -{ - int ret; - PERF_ENTRY(ilogb); - ENTRY("ilogb (x=%f)\n", x); - -#if !HAVE_COMPATIBLE_ILOGB0 - if (x == 0.0) - { - ret = -2147483648; - } - else -#endif // !HAVE_COMPATIBLE_ILOGB0 - -#if !HAVE_COMPATIBLE_ILOGBNAN - if (isnan(x)) - { - ret = 2147483647; - } - else -#endif // !HAVE_COMPATIBLE_ILOGBNAN - - { - ret = ilogb(x); - } - - LOGEXIT("ilogb returns int %d\n", ret); - PERF_EXIT(ilogb); - return ret; -} - /*++ Function: log @@ -339,99 +170,6 @@ PALIMPORT double __cdecl PAL_log10(double x) return ret; } -/*++ -Function: - pow - -See MSDN. ---*/ -PALIMPORT double __cdecl PAL_pow(double x, double y) -{ - double ret; - PERF_ENTRY(pow); - ENTRY("pow (x=%f, y=%f)\n", x, y); - -#if !HAVE_COMPATIBLE_POW - if ((y == PAL_POSINF_DBL) && !isnan(x)) // +Inf - { - if (x == 1.0) - { - ret = x; - } - else if (x == -1.0) - { - ret = 1.0; - } - else if ((x > -1.0) && (x < 1.0)) - { - ret = 0.0; - } - else - { - ret = PAL_POSINF_DBL; // +Inf - } - } - else if ((y == PAL_NEGINF_DBL) && !isnan(x)) // -Inf - { - if (x == 1.0) - { - ret = x; - } - else if (x == -1.0) - { - ret = 1.0; - } - else if ((x > -1.0) && (x < 1.0)) - { - ret = PAL_POSINF_DBL; // +Inf - } - else - { - ret = 0.0; - } - } - else if (IS_DBL_NEGZERO(x) && (y == -1.0)) - { - ret = PAL_NEGINF_DBL; // -Inf - } - else if ((x == 0.0) && (y < 0.0)) - { - ret = PAL_POSINF_DBL; // +Inf - } - else -#endif // !HAVE_COMPATIBLE_POW - - ret = pow(x, y); - -#if !HAVE_VALID_NEGATIVE_INF_POW - if ((ret == PAL_POSINF_DBL) && (x < 0) && isfinite(x) && (ceil(y / 2) != floor(y / 2))) - { - ret = PAL_NEGINF_DBL; // -Inf - } -#endif // !HAVE_VALID_NEGATIVE_INF_POW - -#if !HAVE_VALID_POSITIVE_INF_POW - /* - * The even/odd test in the if (this one and the one above) used to be ((long long) y % 2 == 0) - * on SPARC (long long) y for large y (>2**63) is always 0x7fffffff7fffffff, which - * is an odd number, so the test ((long long) y % 2 == 0) will always fail for - * large y. Since large double numbers are always even (e.g., the representation of - * 1E20+1 is the same as that of 1E20, the last .+1. is too insignificant to be part - * of the representation), this test will always return the wrong result for large y. - * - * The (ceil(y/2) == floor(y/2)) test is slower, but more robust. - */ - if ((ret == PAL_NEGINF_DBL) && (x < 0) && isfinite(x) && (ceil(y / 2) == floor(y / 2))) - { - ret = PAL_POSINF_DBL; // +Inf - } -#endif // !HAVE_VALID_POSITIVE_INF_POW - - LOGEXIT("pow returns double %f\n", ret); - PERF_EXIT(pow); - return ret; -} - /*++ Function: sincos @@ -521,205 +259,6 @@ float __cdecl _copysignf(float x, float y) return ret; } -/*++ -Function: - acosf - -See MSDN. ---*/ -PALIMPORT float __cdecl PAL_acosf(float x) -{ - float ret; - PERF_ENTRY(acosf); - ENTRY("acosf (x=%f)\n", x); - -#if !HAVE_COMPATIBLE_ACOS - errno = 0; -#endif // HAVE_COMPATIBLE_ACOS - - ret = acosf(x); - -#if !HAVE_COMPATIBLE_ACOS - if (errno == EDOM) - { - ret = PAL_NAN_FLT; // NaN - } -#endif // HAVE_COMPATIBLE_ACOS - - LOGEXIT("acosf returns float %f\n", ret); - PERF_EXIT(acosf); - return ret; -} - -/*++ -Function: - asinf - -See MSDN. ---*/ -PALIMPORT float __cdecl PAL_asinf(float x) -{ - float ret; - PERF_ENTRY(asinf); - ENTRY("asinf (x=%f)\n", x); - -#if !HAVE_COMPATIBLE_ASIN - errno = 0; -#endif // HAVE_COMPATIBLE_ASIN - - ret = asinf(x); - -#if !HAVE_COMPATIBLE_ASIN - if (errno == EDOM) - { - ret = PAL_NAN_FLT; // NaN - } -#endif // HAVE_COMPATIBLE_ASIN - - LOGEXIT("asinf returns float %f\n", ret); - PERF_EXIT(asinf); - return ret; -} - -/*++ -Function: - atan2f - -See MSDN. ---*/ -PALIMPORT float __cdecl PAL_atan2f(float y, float x) -{ - float ret; - PERF_ENTRY(atan2f); - ENTRY("atan2f (y=%f, x=%f)\n", y, x); - -#if !HAVE_COMPATIBLE_ATAN2 - errno = 0; -#endif // !HAVE_COMPATIBLE_ATAN2 - - ret = atan2f(y, x); - -#if !HAVE_COMPATIBLE_ATAN2 - if ((errno == EDOM) && (x == 0.0f) && (y == 0.0f)) - { - const float sign_x = copysign(1.0f, x); - const float sign_y = copysign(1.0f, y); - - if (sign_x > 0) - { - ret = copysign(0.0f, sign_y); - } - else - { - ret = copysign(atan2f(0.0f, -1.0f), sign_y); - } - } -#endif // !HAVE_COMPATIBLE_ATAN2 - - LOGEXIT("atan2f returns float %f\n", ret); - PERF_EXIT(atan2f); - return ret; -} - -/*++ -Function: - expf - -See MSDN. ---*/ -PALIMPORT float __cdecl PAL_expf(float x) -{ - float ret; - PERF_ENTRY(expf); - ENTRY("expf (x=%f)\n", x); - -#if !HAVE_COMPATIBLE_EXP - if (x == 1.0f) - { - ret = M_E; - } - else - { -#endif // HAVE_COMPATIBLE_EXP - - ret = expf(x); - -#if !HAVE_COMPATIBLE_EXP - } -#endif // HAVE_COMPATIBLE_EXP - - LOGEXIT("expf returns float %f\n", ret); - PERF_EXIT(expf); - return ret; -} - -/*++ -Function: - ilogbf - -See MSDN. ---*/ -PALIMPORT int __cdecl PAL_ilogbf(float x) -{ - int ret; - PERF_ENTRY(ilogbf); - ENTRY("ilogbf (x=%f)\n", x); - -#if !HAVE_COMPATIBLE_ILOGB0 - if (x == 0.0f) - { - ret = -2147483648; - } - else -#endif // !HAVE_COMPATIBLE_ILOGB0 - -#if !HAVE_COMPATIBLE_ILOGBNAN - if (isnan(x)) - { - ret = 2147483647; - } - else -#endif // !HAVE_COMPATIBLE_ILOGBNAN - - { - ret = ilogbf(x); - } - - LOGEXIT("ilogbf returns int %d\n", ret); - PERF_EXIT(ilogbf); - return ret; -} - -/*++ -Function: - logf - -See MSDN. ---*/ -PALIMPORT float __cdecl PAL_logf(float x) -{ - float ret; - PERF_ENTRY(logf); - ENTRY("logf (x=%f)\n", x); - -#if !HAVE_COMPATIBLE_LOG - errno = 0; -#endif // !HAVE_COMPATIBLE_LOG - - ret = logf(x); - -#if !HAVE_COMPATIBLE_LOG - if ((errno == EDOM) && (x < 0)) - { - ret = PAL_NAN_FLT; // NaN - } -#endif // !HAVE_COMPATIBLE_LOG - - LOGEXIT("logf returns float %f\n", ret); - PERF_EXIT(logf); - return ret; -} - /*++ Function: log10f @@ -750,93 +289,6 @@ PALIMPORT float __cdecl PAL_log10f(float x) return ret; } -/*++ -Function: - powf - -See MSDN. ---*/ -PALIMPORT float __cdecl PAL_powf(float x, float y) -{ - float ret; - PERF_ENTRY(powf); - ENTRY("powf (x=%f, y=%f)\n", x, y); - -#if !HAVE_COMPATIBLE_POW - if ((y == PAL_POSINF_FLT) && !isnan(x)) // +Inf - { - if (x == 1.0f) - { - ret = x; - } - else if (x == -1.0f) - { - ret = 1.0f; - } - else if ((x > -1.0f) && (x < 1.0f)) - { - ret = 0.0f; - } - else - { - ret = PAL_POSINF_FLT; // +Inf - } - } - else if ((y == PAL_NEGINF_FLT) && !isnan(x)) // -Inf - { - if (x == 1.0f) - { - ret = x; - } - else if (x == -1.0f) - { - ret = 1.0f; - } - else if ((x > -1.0f) && (x < 1.0f)) - { - ret = PAL_POSINF_FLT; // +Inf - } - else - { - ret = 0.0f; - } - } - else if (IS_FLT_NEGZERO(x) && (y == -1.0f)) - { - ret = PAL_NEGINF_FLT; // -Inf - } - else if ((x == 0.0f) && (y < 0.0f)) - { - ret = PAL_POSINF_FLT; // +Inf - } - else -#endif // !HAVE_COMPATIBLE_POW - - ret = powf(x, y); - -#if !HAVE_VALID_NEGATIVE_INF_POW - if ((ret == PAL_POSINF_FLT) && (x < 0) && isfinite(x) && (ceilf(y / 2) != floorf(y / 2))) - { - ret = PAL_NEGINF_FLT; // -Inf - } -#endif // !HAVE_VALID_NEGATIVE_INF_POW - -#if !HAVE_VALID_POSITIVE_INF_POW - /* - * The (ceil(y/2) == floor(y/2)) test is slower, but more robust for platforms where large y - * will return the wrong result for ((long) y % 2 == 0). See PAL_pow(double) above for more details. - */ - if ((ret == PAL_NEGINF_FLT) && (x < 0) && isfinite(x) && (ceilf(y / 2) == floorf(y / 2))) - { - ret = PAL_POSINF_FLT; // +Inf - } -#endif // !HAVE_VALID_POSITIVE_INF_POW - - LOGEXIT("powf returns float %f\n", ret); - PERF_EXIT(powf); - return ret; -} - /*++ Function: sincosf diff --git a/src/coreclr/pal/src/include/pal/palinternal.h b/src/coreclr/pal/src/include/pal/palinternal.h index b0abe2aa9be0ac..c5e2f40fbde0cb 100644 --- a/src/coreclr/pal/src/include/pal/palinternal.h +++ b/src/coreclr/pal/src/include/pal/palinternal.h @@ -454,6 +454,7 @@ function_name() to call the system's implementation #undef fma #undef ilogb #undef log +#undef log1p #undef log2 #undef log10 #undef modf @@ -482,6 +483,7 @@ function_name() to call the system's implementation #undef fmaf #undef ilogbf #undef logf +#undef log1pf #undef log2f #undef log10f #undef modff diff --git a/src/coreclr/pal/tests/palsuite/CMakeLists.txt b/src/coreclr/pal/tests/palsuite/CMakeLists.txt index f58757a1f6d5fc..2a1432d817b0c4 100644 --- a/src/coreclr/pal/tests/palsuite/CMakeLists.txt +++ b/src/coreclr/pal/tests/palsuite/CMakeLists.txt @@ -64,38 +64,16 @@ add_executable_clr(paltests #composite/wfmo/main.cpp #composite/wfmo/mutex.cpp c_runtime/abs/test1/abs.cpp - c_runtime/acos/test1/test1.cpp - c_runtime/acosf/test1/test1.cpp - c_runtime/acosh/test1/test1.cpp - c_runtime/acoshf/test1/test1.cpp - c_runtime/asin/test1/test1.cpp - c_runtime/asinf/test1/test1.cpp - c_runtime/asinh/test1/test1.cpp - c_runtime/asinhf/test1/test1.cpp - c_runtime/atan/test1/test1.cpp - c_runtime/atan2/test1/test1.cpp - c_runtime/atan2f/test1/test1.cpp - c_runtime/atanf/test1/test1.cpp - c_runtime/atanh/test1/test1.cpp - c_runtime/atanhf/test1/test1.cpp c_runtime/atof/test1/test1.cpp c_runtime/atoi/test1/test1.cpp c_runtime/bsearch/test1/test1.cpp c_runtime/bsearch/test2/test2.cpp c_runtime/cbrt/test1/test1.cpp c_runtime/cbrtf/test1/test1.cpp - c_runtime/ceil/test1/test1.cpp - c_runtime/ceilf/test1/test1.cpp - c_runtime/cos/test1/test1.cpp - c_runtime/cosf/test1/test1.cpp - c_runtime/cosh/test1/test1.cpp - c_runtime/coshf/test1/test1.cpp c_runtime/errno/test1/test1.cpp c_runtime/errno/test2/test2.cpp c_runtime/exit/test1/test1.cpp c_runtime/exit/test2/test2.cpp - c_runtime/exp/test1/test1.cpp - c_runtime/expf/test1/test1.cpp c_runtime/fabs/test1/test1.cpp c_runtime/fabsf/test1/test1.cpp c_runtime/fclose/test1/test1.cpp @@ -106,8 +84,6 @@ add_executable_clr(paltests c_runtime/fgets/test1/test1.cpp c_runtime/fgets/test2/test2.cpp c_runtime/fgets/test3/test3.cpp - c_runtime/floor/test1/test1.cpp - c_runtime/floorf/test1/test1.cpp c_runtime/fma/test1/test1.cpp c_runtime/fmaf/test1/test1.cpp c_runtime/fmod/test1/test1.cpp @@ -169,8 +145,6 @@ add_executable_clr(paltests c_runtime/getenv/test1/test1.cpp c_runtime/getenv/test2/test2.cpp c_runtime/getenv/test3/test3.cpp - c_runtime/ilogb/test1/test1.cpp - c_runtime/ilogbf/test1/test1.cpp c_runtime/isalnum/test1/test1.cpp c_runtime/isalpha/test1/test1.cpp c_runtime/isdigit/test1/test1.cpp @@ -190,7 +164,6 @@ add_executable_clr(paltests c_runtime/log10f/test1/test1.cpp c_runtime/log2/test1/test1.cpp c_runtime/log2f/test1/test1.cpp - c_runtime/logf/test1/test1.cpp c_runtime/malloc/test1/test1.cpp c_runtime/malloc/test2/test2.cpp c_runtime/memchr/test1/test1.cpp @@ -198,10 +171,6 @@ add_executable_clr(paltests c_runtime/memcpy/test1/test1.cpp c_runtime/memmove/test1/test1.cpp c_runtime/memset/test1/test1.cpp - c_runtime/modf/test1/test1.cpp - c_runtime/modff/test1/test1.cpp - c_runtime/pow/test1/test1.cpp - c_runtime/powf/test1/test1.cpp c_runtime/printf/test1/test1.cpp c_runtime/printf/test10/test10.cpp c_runtime/printf/test11/test11.cpp @@ -225,12 +194,8 @@ add_executable_clr(paltests c_runtime/qsort/test2/test2.cpp c_runtime/rand_srand/test1/test1.cpp c_runtime/realloc/test1/test1.cpp - c_runtime/sin/test1/test1.cpp c_runtime/sincos/test1/test1.cpp c_runtime/sincosf/test1/test1.cpp - c_runtime/sinf/test1/test1.cpp - c_runtime/sinh/test1/test1.cpp - c_runtime/sinhf/test1/test1.cpp c_runtime/sprintf_s/test1/test1.cpp c_runtime/sprintf_s/test10/test10.cpp c_runtime/sprintf_s/test11/test11.cpp @@ -320,10 +285,6 @@ add_executable_clr(paltests c_runtime/swscanf/test7/test7.cpp c_runtime/swscanf/test8/test8.cpp c_runtime/swscanf/test9/test9.cpp - c_runtime/tan/test1/test1.cpp - c_runtime/tanf/test1/test1.cpp - c_runtime/tanh/test1/test1.cpp - c_runtime/tanhf/test1/test1.cpp c_runtime/time/test1/test1.cpp c_runtime/tolower/test1/test1.cpp c_runtime/toupper/test1/test1.cpp diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/acos/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/acos/test1/test1.cpp deleted file mode 100644 index 5de46458e50515..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/acos/test1/test1.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that acos return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * acos_test1_validate - * - * test validation function - */ -void __cdecl acos_test1_validate(double value, double expected, double variance) -{ - double result = acos(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("acos(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * acos_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl acos_test1_validate_isnan(double value) -{ - double result = acos(value); - - if (!_isnan(result)) - { - Fail("acos(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_acos_test1_paltest_acos_test1, "c_runtime/acos/test1/paltest_acos_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { -1, 3.1415926535897932, PAL_EPSILON * 10 }, // expected: pi - { -0.91173391478696510, 2.7182818284590452, PAL_EPSILON * 10 }, // expected: e - { -0.66820151019031295, 2.3025850929940457, PAL_EPSILON * 10 }, // expected: ln(10) - { 0, 1.5707963267948966, PAL_EPSILON * 10 }, // expected: pi / 2 - { 0.12775121753523991, 1.4426950408889634, PAL_EPSILON * 10 }, // expected: log2(e) - { 0.15594369476537447, 1.4142135623730950, PAL_EPSILON * 10 }, // expected: sqrt(2) - { 0.42812514788535792, 1.1283791670955126, PAL_EPSILON * 10 }, // expected: 2 / sqrt(pi) - { 0.54030230586813972, 1, PAL_EPSILON * 10 }, - { 0.70710678118654752, 0.78539816339744831, PAL_EPSILON }, // expected: pi / 4, value: 1 / sqrt(2) - { 0.76024459707563015, 0.70710678118654752, PAL_EPSILON }, // expected: 1 / sqrt(2) - { 0.76923890136397213, 0.69314718055994531, PAL_EPSILON }, // expected: ln(2) - { 0.80410982822879171, 0.63661977236758134, PAL_EPSILON }, // expected: 2 / pi - { 0.90716712923909839, 0.43429448190325183, PAL_EPSILON }, // expected: log10(e) - { 0.94976571538163866, 0.31830988618379067, PAL_EPSILON }, // expected: 1 / pi - { 1, 0, PAL_EPSILON }, - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - acos_test1_validate(tests[i].value, tests[i].expected, tests[i].variance); - } - - acos_test1_validate_isnan(PAL_NEGINF); - acos_test1_validate_isnan(PAL_NAN); - acos_test1_validate_isnan(PAL_POSINF); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/acosf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/acosf/test1/test1.cpp deleted file mode 100644 index 909d43cab78a98..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/acosf/test1/test1.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that acosf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * acosf_test1_validate - * - * test validation function - */ -void __cdecl acosf_test1_validate(float value, float expected, float variance) -{ - float result = acosf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("acosf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * acosf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl acosf_test1_validate_isnan(float value) -{ - float result = acosf(value); - - if (!_isnanf(result)) - { - Fail("acosf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_acosf_test1_paltest_acosf_test1, "c_runtime/acosf/test1/paltest_acosf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { -1, 3.14159265f, PAL_EPSILON * 10 }, // expected: pi - { -0.911733915f, 2.71828183f, PAL_EPSILON * 10 }, // expected: e - { -0.668201510f, 2.30258509f, PAL_EPSILON * 10 }, // expected: ln(10) - { 0, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2 - { 0.127751218f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e) - { 0.155943695f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2) - { 0.428125148f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi) - { 0.540302306f, 1, PAL_EPSILON * 10 }, - { 0.707106781f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4, value: 1 / sqrtf(2) - { 0.760244597f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2) - { 0.769238901f, 0.693147181f, PAL_EPSILON }, // expected: ln(2) - { 0.804109828f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi - { 0.907167129f, 0.434294482f, PAL_EPSILON }, // expected: logf10f(e) - { 0.949765715f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi - { 1, 0, PAL_EPSILON }, - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - acosf_test1_validate(tests[i].value, tests[i].expected, tests[i].variance); - } - - acosf_test1_validate_isnan(PAL_NEGINF); - acosf_test1_validate_isnan(PAL_NAN); - acosf_test1_validate_isnan(PAL_POSINF); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/acosh/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/acosh/test1/test1.cpp deleted file mode 100644 index 3d9368fcd94f7b..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/acosh/test1/test1.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that acosh return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * acosh_test1_validate - * - * test validation function - */ -void __cdecl acosh_test1_validate(double value, double expected, double variance) -{ - double result = acosh(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("acosh(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * acosh_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl acosh_test1_validate_isnan(double value) -{ - double result = acosh(value); - - if (!_isnan(result)) - { - Fail("acosh(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_acosh_test1_paltest_acosh_test1, "c_runtime/acosh/test1/paltest_acosh_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 1, 0, PAL_EPSILON }, - { 1.0510897883672876, 0.31830988618379067, PAL_EPSILON }, // expected: 1 / pi - { 1.0957974645564909, 0.43429448190325183, PAL_EPSILON }, // expected: log10(e) - { 1.2095794864199787, 0.63661977236758134, PAL_EPSILON }, // expected: 2 / pi - { 1.25, 0.69314718055994531, PAL_EPSILON }, // expected: ln(2) - { 1.2605918365213561, 0.70710678118654752, PAL_EPSILON }, // expected: 1 / sqrt(2) - { 1.3246090892520058, 0.78539816339744831, PAL_EPSILON }, // expected: pi / 4 - { 1.5430806348152438, 1, PAL_EPSILON * 10 }, - { 1.7071001431069344, 1.1283791670955126, PAL_EPSILON * 10 }, // expected: 2 / sqrt(pi) - { 2.1781835566085709, 1.4142135623730950, PAL_EPSILON * 10 }, // expected: sqrt(2) - { 2.2341880974508023, 1.4426950408889634, PAL_EPSILON * 10 }, // expected: log2(e) - { 2.5091784786580568, 1.5707963267948966, PAL_EPSILON * 10 }, // expected: pi / 2 - { 5.05, 2.3025850929940457, PAL_EPSILON * 10 }, // expected: ln(10) - { 7.6101251386622884, 2.7182818284590452, PAL_EPSILON * 10 }, // expected: e - { 11.591953275521521, 3.1415926535897932, PAL_EPSILON * 10 }, // expected: pi - { PAL_POSINF, PAL_POSINF, 0 }, - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - acosh_test1_validate(tests[i].value, tests[i].expected, tests[i].variance); - } - - acosh_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/acoshf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/acoshf/test1/test1.cpp deleted file mode 100644 index 78bab37dbf37d0..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/acoshf/test1/test1.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that acoshf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * acoshf_test1_validate - * - * test validation function - */ -void __cdecl acoshf_test1_validate(float value, float expected, float variance) -{ - float result = acoshf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("acoshf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * acoshf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl acoshf_test1_validate_isnan(float value) -{ - float result = acoshf(value); - - if (!_isnanf(result)) - { - Fail("acoshf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_acoshf_test1_paltest_acoshf_test1, "c_runtime/acoshf/test1/paltest_acoshf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 1, 0, PAL_EPSILON }, - { 1.05108979f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi - { 1.09579746f, 0.434294482f, PAL_EPSILON }, // expected: log10f(e) - { 1.20957949f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi - { 1.25f, 0.693147181f, PAL_EPSILON }, // expected: ln(2) - { 1.26059184f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2) - { 1.32460909f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4 - { 1.54308063f, 1, PAL_EPSILON * 10 }, - { 1.70710014f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi) - { 2.17818356f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2) - { 2.23418810f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e) - { 2.50917848f, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2 - { 5.05f, 2.30258509f, PAL_EPSILON * 10 }, // expected: ln(10) - { 7.61012514f, 2.71828183f, PAL_EPSILON * 10 }, // expected: e - { 11.5919533f, 3.14159265f, PAL_EPSILON * 100 }, // expected: pi - { PAL_POSINF, PAL_POSINF, 0 }, - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - acoshf_test1_validate(tests[i].value, tests[i].expected, tests[i].variance); - } - - acoshf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/asin/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/asin/test1/test1.cpp deleted file mode 100644 index b72599ad33d35a..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/asin/test1/test1.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that asin return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * asin_test1_validate - * - * test validation function - */ -void __cdecl asin_test1_validate(double value, double expected, double variance) -{ - double result = asin(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("asin(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * asin_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl asin_test1_validate_isnan(double value) -{ - double result = asin(value); - - if (!_isnan(result)) - { - Fail("asin(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * asin_test1_validate - * - * test validation function for values returning +INF - */ -void __cdecl asin_test1_validate_isinf_positive(double value) -{ - double result = asin(value); - - if (result != PAL_POSINF) - { - Fail("asin(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_POSINF); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_asin_test1_paltest_asin_test1, "c_runtime/asin/test1/paltest_asin_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.31296179620778659, 0.31830988618379067, PAL_EPSILON }, // expected: 1 / pi - { 0.41078129050290870, 0.42331082513074800, PAL_EPSILON }, // expected: pi - e - { 0.42077048331375735, 0.43429448190325183, PAL_EPSILON }, // expected: log10(e) - { 0.59448076852482208, 0.63661977236758134, PAL_EPSILON }, // expected: 2 / pi - { 0.63896127631363480, 0.69314718055994531, PAL_EPSILON }, // expected: ln(2) - { 0.64963693908006244, 0.70710678118654752, PAL_EPSILON }, // expected: 1 / sqrt(2) - { 0.70710678118654752, 0.78539816339744831, PAL_EPSILON }, // expected: pi / 4, value: 1 / sqrt(2) - { 0.74398033695749319, 0.83900756059574755, PAL_EPSILON }, // expected: pi - ln(10) - { 0.84147098480789651, 1, PAL_EPSILON * 10 }, - { 0.90371945743584630, 1.1283791670955126, PAL_EPSILON * 10 }, // expected: 2 / sqrt(pi) - { 0.98776594599273553, 1.4142135623730950, PAL_EPSILON * 10 }, // expected: sqrt(2) - { 0.99180624439366372, 1.4426950408889634, PAL_EPSILON * 10 }, // expected: log2(e) - { 1, 1.5707963267948966, PAL_EPSILON * 10 }, // expected: pi / 2 - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - asin_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - asin_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - asin_test1_validate_isnan(PAL_NEGINF); - asin_test1_validate_isnan(PAL_NAN); - asin_test1_validate_isnan(PAL_POSINF); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/asinf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/asinf/test1/test1.cpp deleted file mode 100644 index abf35c2618519f..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/asinf/test1/test1.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that asinf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * asinf_test1_validate - * - * test validation function - */ -void __cdecl asinf_test1_validate(float value, float expected, float variance) -{ - float result = asinf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("asinf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * asinf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl asinf_test1_validate_isnan(float value) -{ - float result = asinf(value); - - if (!_isnanf(result)) - { - Fail("asinf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * asinf_test1_validate - * - * test validation function for values returning +INF - */ -void __cdecl asinf_test1_validate_isinf_positive(float value) -{ - float result = asinf(value); - - if (result != PAL_POSINF) - { - Fail("asinf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_POSINF); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_asinf_test1_paltest_asinf_test1, "c_runtime/asinf/test1/paltest_asinf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.312961796f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi - { 0.410781291f, 0.423310825f, PAL_EPSILON }, // expected: pi - e - { 0.420770483f, 0.434294482f, PAL_EPSILON }, // expected: logf10f(e) - { 0.594480769f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi - { 0.638961276f, 0.693147181f, PAL_EPSILON }, // expected: ln(2) - { 0.649636939f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2) - { 0.707106781f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4, value: 1 / sqrtf(2) - { 0.743980337f, 0.839007561f, PAL_EPSILON }, // expected: pi - ln(10) - { 0.841470985f, 1, PAL_EPSILON * 10 }, - { 0.903719457f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi) - { 0.987765946f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2) - { 0.991806244f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e) - { 1, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2 - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - asinf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - asinf_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - asinf_test1_validate_isnan(PAL_NEGINF); - asinf_test1_validate_isnan(PAL_NAN); - asinf_test1_validate_isnan(PAL_POSINF); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/asinh/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/asinh/test1/test1.cpp deleted file mode 100644 index a0ed7953d2edfc..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/asinh/test1/test1.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that asinh return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * asinh_test1_validate - * - * test validation function - */ -void __cdecl asinh_test1_validate(double value, double expected, double variance) -{ - double result = asinh(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("asinh(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * asinh_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl asinh_test1_validate_isnan(double value) -{ - double result = asinh(value); - - if (!_isnan(result)) - { - Fail("asinh(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * asinh_test1_validate - * - * test validation function for values returning +INF - */ -void __cdecl asinh_test1_validate_isinf_positive(double value) -{ - double result = asinh(value); - - if (result != PAL_POSINF) - { - Fail("asinh(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_POSINF); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_asinh_test1_paltest_asinh_test1, "c_runtime/asinh/test1/paltest_asinh_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.32371243907207108, 0.31830988618379067, PAL_EPSILON }, // expected: 1 / pi - { 0.44807597941469025, 0.43429448190325183, PAL_EPSILON }, // expected: log10(e) - { 0.68050167815224332, 0.63661977236758134, PAL_EPSILON }, // expected: 2 / pi - { 0.75, 0.69314718055994531, PAL_EPSILON }, // expected: ln(2) - { 0.76752314512611633, 0.70710678118654752, PAL_EPSILON }, // expected: 1 / sqrt(2) - { 0.86867096148600961, 0.78539816339744831, PAL_EPSILON }, // expected: pi / 4 - { 1.1752011936438015, 1, PAL_EPSILON * 10 }, - { 1.3835428792038633, 1.1283791670955126, PAL_EPSILON * 10 }, // expected: 2 / sqrt(pi) - { 1.9350668221743567, 1.4142135623730950, PAL_EPSILON * 10 }, // expected: sqrt(2) - { 1.9978980091062796, 1.4426950408889634, PAL_EPSILON * 10 }, // expected: log2(e) - { 2.3012989023072949, 1.5707963267948966, PAL_EPSILON * 10 }, // expected: pi / 2 - { 4.95, 2.3025850929940457, PAL_EPSILON * 10 }, // expected: ln(10) - { 7.5441371028169758, 2.7182818284590452, PAL_EPSILON * 10 }, // expected: e - { 11.548739357257748, 3.1415926535897932, PAL_EPSILON * 10 }, // expected: pi - { PAL_POSINF, PAL_POSINF, 0 }, - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - asinh_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - asinh_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - asinh_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/asinhf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/asinhf/test1/test1.cpp deleted file mode 100644 index eb2af42b98c7c1..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/asinhf/test1/test1.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that asinhf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * asinhf_test1_validate - * - * test validation function - */ -void __cdecl asinhf_test1_validate(float value, float expected, float variance) -{ - float result = asinhf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("asinhf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * asinhf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl asinhf_test1_validate_isnan(float value) -{ - float result = asinhf(value); - - if (!_isnanf(result)) - { - Fail("asinhf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * asinhf_test1_validate - * - * test validation function for values returning +INF - */ -void __cdecl asinhf_test1_validate_isinf_positive(float value) -{ - float result = asinhf(value); - - if (result != PAL_POSINF) - { - Fail("asinhf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_POSINF); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_asinhf_test1_paltest_asinhf_test1, "c_runtime/asinhf/test1/paltest_asinhf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.323712439f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi - { 0.448075979f, 0.434294482f, PAL_EPSILON }, // expected: log10f(e) - { 0.680501678f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi - { 0.75, 0.693147181f, PAL_EPSILON }, // expected: ln(2) - { 0.767523145f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2) - { 0.868670961f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4 - { 1.17520119f, 1, PAL_EPSILON * 10 }, - { 1.38354288f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi) - { 1.93506682f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2) - { 1.99789801f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e) - { 2.30129890f, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2 - { 4.95f, 2.30258509f, PAL_EPSILON * 10 }, // expected: ln(10) - { 7.54413710f, 2.71828183f, PAL_EPSILON * 10 }, // expected: e - { 11.5487394f, 3.14159265f, PAL_EPSILON * 10 }, // expected: pi - { PAL_POSINF, PAL_POSINF, 0 }, - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - asinhf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - asinhf_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - asinhf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/atan/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/atan/test1/test1.cpp deleted file mode 100644 index 0e65933bc894f3..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/atan/test1/test1.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that atan return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * atan_test1_validate - * - * test validation function - */ -void __cdecl atan_test1_validate(double value, double expected, double variance) -{ - double result = atan(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("atan(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * atan_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl atan_test1_validate_isnan(double value) -{ - double result = atan(value); - - if (!_isnan(result)) - { - Fail("atan(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_atan_test1_paltest_atan_test1, "c_runtime/atan/test1/paltest_atan_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.32951473309607836, 0.31830988618379067, PAL_EPSILON }, // expected: 1 / pi - { 0.45054953406980750, 0.42331082513074800, PAL_EPSILON }, // expected: pi - e - { 0.46382906716062964, 0.43429448190325183, PAL_EPSILON }, // expected: log10(e) - { 0.73930295048660405, 0.63661977236758134, PAL_EPSILON }, // expected: 2 / pi - { 0.83064087786078395, 0.69314718055994531, PAL_EPSILON }, // expected: ln(2) - { 0.85451043200960189, 0.70710678118654752, PAL_EPSILON }, // expected: 1 / sqrt(2) - { 1, 0.78539816339744831, PAL_EPSILON }, // expected: pi / 4 - { 1.1134071468135374, 0.83900756059574755, PAL_EPSILON }, // expected: pi - ln(10) - { 1.5574077246549022, 1, PAL_EPSILON * 10 }, - { 2.1108768356626451, 1.1283791670955126, PAL_EPSILON * 10 }, // expected: 2 / sqrt(pi) - { 6.3341191670421916, 1.4142135623730950, PAL_EPSILON * 10 }, // expected: sqrt(2) - { 7.7635756709721848, 1.4426950408889634, PAL_EPSILON * 10 }, // expected: log2(e) - { PAL_POSINF, 1.5707963267948966, PAL_EPSILON * 10 }, // expected: pi / 2 - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - atan_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - atan_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - atan_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/atan2/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/atan2/test1/test1.cpp deleted file mode 100644 index 6298487994d5dc..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/atan2/test1/test1.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests that atan2 returns correct values for a subset of values. -** Tests with positive and negative values of x and y to ensure -** atan2 is returning results from the correct quadrant. -** -**===================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -struct test -{ - double y; /* second component of the value to test the function with */ - double x; /* first component of the value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * atan2_test1_validate - * - * test validation function - */ -void __cdecl atan2_test1_validate(double y, double x, double expected, double variance) -{ - double result = atan2(y, x); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("atan2(%g, %g) returned %20.17g when it should have returned %20.17g", - y, x, result, expected); - } -} - -/** - * atan2_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl atan2_test1_validate_isnan(double y, double x) -{ - double result = atan2(y, x); - - if (!_isnan(result)) - { - Fail("atan2(%g, %g) returned %20.17g when it should have returned %20.17g", - y, x, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_atan2_test1_paltest_atan2_test1, "c_runtime/atan2/test1/paltest_atan2_test1") -{ - struct test tests[] = - { - /* y x expected variance */ - { 0, PAL_POSINF, 0, PAL_EPSILON }, - { 0, 0, 0, PAL_EPSILON }, - { 0.31296179620778659, 0.94976571538163866, 0.31830988618379067, PAL_EPSILON }, // expected: 1 / pi - { 0.42077048331375735, 0.90716712923909839, 0.43429448190325183, PAL_EPSILON }, // expected: log10(e) - { 0.59448076852482208, 0.80410982822879171, 0.63661977236758134, PAL_EPSILON }, // expected: 2 / pi - { 0.63896127631363480, 0.76923890136397213, 0.69314718055994531, PAL_EPSILON }, // expected: ln(2) - { 0.64963693908006244, 0.76024459707563015, 0.70710678118654752, PAL_EPSILON }, // expected: 1 / sqrt(2) - { 0.70710678118654752, 0.70710678118654752, 0.78539816339744831, PAL_EPSILON }, // expected: pi / 4, value: 1 / sqrt(2) - { 1, 1, 0.78539816339744831, PAL_EPSILON }, // expected: pi / 4 - { PAL_POSINF, PAL_POSINF, 0.78539816339744831, PAL_EPSILON }, // expected: pi / 4 - { 0.84147098480789651, 0.54030230586813972, 1, PAL_EPSILON * 10 }, - { 0.90371945743584630, 0.42812514788535792, 1.1283791670955126, PAL_EPSILON * 10 }, // expected: 2 / sqrt(pi) - { 0.98776594599273553, 0.15594369476537447, 1.4142135623730950, PAL_EPSILON * 10 }, // expected: sqrt(2) - { 0.99180624439366372, 0.12775121753523991, 1.4426950408889634, PAL_EPSILON * 10 }, // expected: log2(e) - { 1, 0, 1.5707963267948966, PAL_EPSILON * 10 }, // expected: pi / 2 - { PAL_POSINF, 0, 1.5707963267948966, PAL_EPSILON * 10 }, // expected: pi / 2 - { PAL_POSINF, 1, 1.5707963267948966, PAL_EPSILON * 10 }, // expected: pi / 2 - { 0.74398033695749319, -0.66820151019031295, 2.3025850929940457, PAL_EPSILON * 10 }, // expected: ln(10) - { 0.41078129050290870, -0.91173391478696510, 2.7182818284590452, PAL_EPSILON * 10 }, // expected: e - { 0, -1, 3.1415926535897932, PAL_EPSILON * 10 }, // expected: pi - { 1, PAL_POSINF, 0, PAL_EPSILON }, - }; - - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - const double pi = 3.1415926535897932; - - atan2_test1_validate( tests[i].y, tests[i].x, tests[i].expected, tests[i].variance); - atan2_test1_validate(-tests[i].y, tests[i].x, -tests[i].expected, tests[i].variance); - atan2_test1_validate( tests[i].y, -tests[i].x, pi - tests[i].expected, tests[i].variance); - atan2_test1_validate(-tests[i].y, -tests[i].x, tests[i].expected - pi, tests[i].variance); - } - - atan2_test1_validate_isnan(PAL_NEGINF, PAL_NAN); - atan2_test1_validate_isnan(PAL_NAN, PAL_NEGINF); - atan2_test1_validate_isnan(PAL_NAN, PAL_POSINF); - atan2_test1_validate_isnan(PAL_POSINF, PAL_NAN); - - atan2_test1_validate_isnan(PAL_NAN, -1); - atan2_test1_validate_isnan(PAL_NAN, -0.0); - atan2_test1_validate_isnan(PAL_NAN, 0); - atan2_test1_validate_isnan(PAL_NAN, 1); - - atan2_test1_validate_isnan(-1, PAL_NAN); - atan2_test1_validate_isnan(-0.0, PAL_NAN); - atan2_test1_validate_isnan( 0, PAL_NAN); - atan2_test1_validate_isnan( 1, PAL_NAN); - - atan2_test1_validate_isnan(PAL_NAN, PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/atan2f/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/atan2f/test1/test1.cpp deleted file mode 100644 index f5915b3a0e1c25..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/atan2f/test1/test1.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests that atan2f returns correct values for a subset of values. -** Tests with positive and negative values of x and y to ensure -** atan2f is returning results from the correct quadrant. -** -**===================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -struct test -{ - float y; /* second component of the value to test the function with */ - float x; /* first component of the value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * atan2f_test1_validate - * - * test validation function - */ -void __cdecl atan2f_test1_validate(float y, float x, float expected, float variance) -{ - float result = atan2f(y, x); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("atan2f(%g, %g) returned %10.9g when it should have returned %10.9g", - y, x, result, expected); - } -} - -/** - * atan2f_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl atan2f_test1_validate_isnan(float y, float x) -{ - float result = atan2f(y, x); - - if (!_isnanf(result)) - { - Fail("atan2f(%g, %g) returned %10.9g when it should have returned %10.9g", - y, x, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_atan2f_test1_paltest_atan2f_test1, "c_runtime/atan2f/test1/paltest_atan2f_test1") -{ - struct test tests[] = - { - /* y x expected variance */ - { 0, PAL_POSINF, 0, PAL_EPSILON }, - { 0, 0, 0, PAL_EPSILON }, - { 0.312961796f, 0.949765715f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi - { 0.420770483f, 0.907167129f, 0.434294482f, PAL_EPSILON }, // expected: logf10f(e) - { 0.594480769f, 0.804109828f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi - { 0.638961276f, 0.769238901f, 0.693147181f, PAL_EPSILON }, // expected: ln(2) - { 0.649636939f, 0.760244597f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2) - { 0.707106781f, 0.707106781f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4, value: 1 / sqrtf(2) - { 1, 1, 0.785398163f, PAL_EPSILON }, // expected: pi / 4 - { PAL_POSINF, PAL_POSINF, 0.785398163f, PAL_EPSILON }, // expected: pi / 4 - { 0.841470985f, 0.540302306f, 1, PAL_EPSILON * 10 }, - { 0.903719457f, 0.428125148f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi) - { 0.987765946f, 0.155943695f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2) - { 0.991806244f, 0.127751218f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e) - { 1, 0, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2 - { PAL_POSINF, 0, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2 - { PAL_POSINF, 1, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2 - { 0.743980337f, -0.668201510f, 2.30258509f, PAL_EPSILON * 10 }, // expected: ln(10) - { 0.410781291f, -0.911733915f, 2.71828183f, PAL_EPSILON * 10 }, // expected: e - { 0, -1, 3.14159265f, PAL_EPSILON * 10 }, // expected: pi - { 1, PAL_POSINF, 0, PAL_EPSILON }, - }; - - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - const float pi = 3.14159265f; - - atan2f_test1_validate( tests[i].y, tests[i].x, tests[i].expected, tests[i].variance); - atan2f_test1_validate(-tests[i].y, tests[i].x, -tests[i].expected, tests[i].variance); - atan2f_test1_validate( tests[i].y, -tests[i].x, pi - tests[i].expected, tests[i].variance); - atan2f_test1_validate(-tests[i].y, -tests[i].x, tests[i].expected - pi, tests[i].variance); - } - - atan2f_test1_validate_isnan(PAL_NEGINF, PAL_NAN); - atan2f_test1_validate_isnan(PAL_NAN, PAL_NEGINF); - atan2f_test1_validate_isnan(PAL_NAN, PAL_POSINF); - atan2f_test1_validate_isnan(PAL_POSINF, PAL_NAN); - - atan2f_test1_validate_isnan(PAL_NAN, -1); - atan2f_test1_validate_isnan(PAL_NAN, -0.0f); - atan2f_test1_validate_isnan(PAL_NAN, 0); - atan2f_test1_validate_isnan(PAL_NAN, 1); - - atan2f_test1_validate_isnan(-1, PAL_NAN); - atan2f_test1_validate_isnan(-0.0f, PAL_NAN); - atan2f_test1_validate_isnan( 0, PAL_NAN); - atan2f_test1_validate_isnan( 1, PAL_NAN); - - atan2f_test1_validate_isnan(PAL_NAN, PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/atanf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/atanf/test1/test1.cpp deleted file mode 100644 index 518775f1f9c3e6..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/atanf/test1/test1.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that atanf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * atanf_test1_validate - * - * test validation function - */ -void __cdecl atanf_test1_validate(float value, float expected, float variance) -{ - float result = atanf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("atanf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * atanf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl atanf_test1_validate_isnan(float value) -{ - float result = atanf(value); - - if (!_isnanf(result)) - { - Fail("atanf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_atanf_test1_paltest_atanf_test1, "c_runtime/atanf/test1/paltest_atanf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.329514733f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi - { 0.450549534f, 0.423310825f, PAL_EPSILON }, // expected: pi - e - { 0.463829067f, 0.434294482f, PAL_EPSILON }, // expected: logf10f(e) - { 0.739302950f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi - { 0.830640878f, 0.693147181f, PAL_EPSILON }, // expected: ln(2) - { 0.854510432f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2) - { 1, 0.785398163f, PAL_EPSILON }, // expected: pi / 4 - { 1.11340715f, 0.839007561f, PAL_EPSILON }, // expected: pi - ln(10) - { 1.55740772f, 1, PAL_EPSILON * 10 }, - { 2.11087684f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi) - { 6.33411917f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2) - { 7.76357567f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e) - { PAL_POSINF, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2 - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - atanf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - atanf_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - atanf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/atanh/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/atanh/test1/test1.cpp deleted file mode 100644 index 24a042826e0917..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/atanh/test1/test1.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that atanh return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * atanh_test1_validate - * - * test validation function - */ -void __cdecl atanh_test1_validate(double value, double expected, double variance) -{ - double result = atanh(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("atanh(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * atanh_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl atanh_test1_validate_isnan(double value) -{ - double result = atanh(value); - - if (!_isnan(result)) - { - Fail("atanh(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_atanh_test1_paltest_atanh_test1, "c_runtime/atanh/test1/paltest_atanh_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.30797791269089433, 0.31830988618379067, PAL_EPSILON }, // expected: 1 / pi - { 0.40890401183401433, 0.43429448190325183, PAL_EPSILON }, // expected: log10(e) - { 0.56259360033158334, 0.63661977236758134, PAL_EPSILON }, // expected: 2 / pi - { 0.6, 0.69314718055994531, PAL_EPSILON }, // expected: ln(2) - { 0.60885936501391381, 0.70710678118654752, PAL_EPSILON }, // expected: 1 / sqrt(2) - { 0.65579420263267244, 0.78539816339744831, PAL_EPSILON }, // expected: pi / 4 - { 0.76159415595576489, 1, PAL_EPSILON * 10 }, - { 0.81046380599898809, 1.1283791670955126, PAL_EPSILON * 10 }, // expected: 2 / sqrt(pi) - { 0.88838556158566054, 1.4142135623730950, PAL_EPSILON * 10 }, // expected: sqrt(2) - { 0.89423894585503855, 1.4426950408889634, PAL_EPSILON * 10 }, // expected: log2(e) - { 0.91715233566727435, 1.5707963267948966, PAL_EPSILON * 10 }, // expected: pi / 2 - { 0.98019801980198020, 2.3025850929940457, PAL_EPSILON * 10 }, // expected: ln(10) - { 0.99132891580059984, 2.7182818284590452, PAL_EPSILON * 10 }, // expected: e - { 0.99627207622074994, 3.1415926535897932, PAL_EPSILON * 10 }, // expected: pi - { 1, PAL_POSINF, PAL_EPSILON * 10 } - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - atanh_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - atanh_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - atanh_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/atanhf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/atanhf/test1/test1.cpp deleted file mode 100644 index d8d184f905fbed..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/atanhf/test1/test1.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that atanhf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * atanhf_test1_validate - * - * test validation function - */ -void __cdecl atanhf_test1_validate(float value, float expected, float variance) -{ - float result = atanhf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("atanhf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * atanhf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl atanhf_test1_validate_isnan(float value) -{ - float result = atanhf(value); - - if (!_isnanf(result)) - { - Fail("atanhf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_atanhf_test1_paltest_atanhf_test1, "c_runtime/atanhf/test1/paltest_atanhf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.307977913f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi - { 0.408904012f, 0.434294482f, PAL_EPSILON }, // expected: log10f(e) - { 0.562593600f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi - { 0.6f, 0.693147181f, PAL_EPSILON }, // expected: ln(2) - { 0.608859365f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2) - { 0.655794203f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4 - { 0.761594156f, 1, PAL_EPSILON * 10 }, - { 0.810463806f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi) - { 0.888385562f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2) - { 0.894238946f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e) - { 0.917152336f, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2 - { 0.980198020f, 2.30258509f, PAL_EPSILON * 10 }, // expected: ln(10) - { 0.991328916f, 2.71828183f, PAL_EPSILON * 10 }, // expected: e - { 0.996272076f, 3.14159265f, PAL_EPSILON * 10 }, // expected: pi - { 1, PAL_POSINF, PAL_EPSILON * 10 } - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - atanhf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - atanhf_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - atanhf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/ceil/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/ceil/test1/test1.cpp deleted file mode 100644 index 3f1d71e625c7d6..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/ceil/test1/test1.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Tests ceil with simple positive and negative values. Also tests -** extreme cases like extremely small values and positive and -** negative infinity. Makes sure that calling ceil on NaN returns -** NaN -** -**==========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * ceil_test1_validate - * - * test validation function - */ -void __cdecl ceil_test1_validate(double value, double expected, double variance) -{ - double result = ceil(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("ceil(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * ceil_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl ceil_test1_validate_isnan(double value) -{ - double result = ceil(value); - - if (!_isnan(result)) - { - Fail("ceil(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_ceil_test1_paltest_ceil_test1, "c_runtime/ceil/test1/paltest_ceil_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0.31830988618379067, 1, PAL_EPSILON * 10 }, // value: 1 / pi - { 0.43429448190325183, 1, PAL_EPSILON * 10 }, // value: log10(e) - { 0.63661977236758134, 1, PAL_EPSILON * 10 }, // value: 2 / pi - { 0.69314718055994531, 1, PAL_EPSILON * 10 }, // value: ln(2) - { 0.70710678118654752, 1, PAL_EPSILON * 10 }, // value: 1 / sqrt(2) - { 0.78539816339744831, 1, PAL_EPSILON * 10 }, // value: pi / 4 - { 1.1283791670955126, 2, PAL_EPSILON * 10 }, // value: 2 / sqrt(pi) - { 1.4142135623730950, 2, PAL_EPSILON * 10 }, // value: sqrt(2) - { 1.4426950408889634, 2, PAL_EPSILON * 10 }, // value: log2(e) - { 1.5707963267948966, 2, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.3025850929940457, 3, PAL_EPSILON * 10 }, // value: ln(10) - { 2.7182818284590452, 3, PAL_EPSILON * 10 }, // value: e - { 3.1415926535897932, 4, PAL_EPSILON * 10 }, // value: pi - { PAL_POSINF, PAL_POSINF, 0 } - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - ceil_test1_validate( 0, 0, PAL_EPSILON); - ceil_test1_validate(-0.0, 0, PAL_EPSILON); - - ceil_test1_validate( 1, 1, PAL_EPSILON * 10); - ceil_test1_validate(-1.0, -1, PAL_EPSILON * 10); - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - ceil_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - ceil_test1_validate(-tests[i].value, 1 - tests[i].expected, tests[i].variance); - } - - ceil_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/ceilf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/ceilf/test1/test1.cpp deleted file mode 100644 index cf237ea8eb95bc..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/ceilf/test1/test1.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Tests ceilf with simple positive and negative values. Also tests -** extreme cases like extremely small values and positive and -** negative infinity. Makes sure that calling ceilf on NaN returns -** NaN -** -**==========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * ceilf_test1_validate - * - * test validation function - */ -void __cdecl ceilf_test1_validate(float value, float expected, float variance) -{ - float result = ceilf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("ceilf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * ceilf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl ceilf_test1_validate_isnan(float value) -{ - float result = ceilf(value); - - if (!_isnanf(result)) - { - Fail("ceilf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_ceilf_test1_paltest_ceilf_test1, "c_runtime/ceilf/test1/paltest_ceilf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0.318309886f, 1, PAL_EPSILON * 10 }, // value: 1 / pi - { 0.434294482f, 1, PAL_EPSILON * 10 }, // value: log10f(e) - { 0.636619772f, 1, PAL_EPSILON * 10 }, // value: 2 / pi - { 0.693147181f, 1, PAL_EPSILON * 10 }, // value: ln(2) - { 0.707106781f, 1, PAL_EPSILON * 10 }, // value: 1 / sqrtf(2) - { 0.785398163f, 1, PAL_EPSILON * 10 }, // value: pi / 4 - { 1.12837917f, 2, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi) - { 1.41421356f, 2, PAL_EPSILON * 10 }, // value: sqrtf(2) - { 1.44269504f, 2, PAL_EPSILON * 10 }, // value: logf2(e) - { 1.57079633f, 2, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.30258509f, 3, PAL_EPSILON * 10 }, // value: ln(10) - { 2.71828183f, 3, PAL_EPSILON * 10 }, // value: e - { 3.14159265f, 4, PAL_EPSILON * 10 }, // value: pi - { PAL_POSINF, PAL_POSINF, 0 } - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - ceilf_test1_validate( 0, 0, PAL_EPSILON); - ceilf_test1_validate(-0.0f, 0, PAL_EPSILON); - - ceilf_test1_validate( 1, 1, PAL_EPSILON * 10); - ceilf_test1_validate(-1.0f, -1, PAL_EPSILON * 10); - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - ceilf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - ceilf_test1_validate(-tests[i].value, 1 - tests[i].expected, tests[i].variance); - } - - ceilf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/cos/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/cos/test1/test1.cpp deleted file mode 100644 index d574895731d52d..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/cos/test1/test1.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that cos return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * cos_test1_validate - * - * test validation function - */ -void __cdecl cos_test1_validate(double value, double expected, double variance) -{ - double result = cos(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("cos(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * cos_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl cos_test1_validate_isnan(double value) -{ - double result = cos(value); - - if (!_isnan(result)) - { - Fail("cos(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_cos_test1_paltest_cos_test1, "c_runtime/cos/test1/paltest_cos_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 1, PAL_EPSILON * 10 }, - { 0.31830988618379067, 0.94976571538163866, PAL_EPSILON }, // value: 1 / pi - { 0.43429448190325183, 0.90716712923909839, PAL_EPSILON }, // value: log10(e) - { 0.63661977236758134, 0.80410982822879171, PAL_EPSILON }, // value: 2 / pi - { 0.69314718055994531, 0.76923890136397213, PAL_EPSILON }, // value: ln(2) - { 0.70710678118654752, 0.76024459707563015, PAL_EPSILON }, // value: 1 / sqrt(2) - { 0.78539816339744831, 0.70710678118654752, PAL_EPSILON }, // value: pi / 4, expected: 1 / sqrt(2) - { 1, 0.54030230586813972, PAL_EPSILON }, - { 1.1283791670955126, 0.42812514788535792, PAL_EPSILON }, // value: 2 / sqrt(pi) - { 1.4142135623730950, 0.15594369476537447, PAL_EPSILON }, // value: sqrt(2) - { 1.4426950408889634, 0.12775121753523991, PAL_EPSILON }, // value: log2(e) - { 1.5707963267948966, 0, PAL_EPSILON }, // value: pi / 2 - { 2.3025850929940457, -0.66820151019031295, PAL_EPSILON }, // value: ln(10) - { 2.7182818284590452, -0.91173391478696510, PAL_EPSILON }, // value: e - { 3.1415926535897932, -1, PAL_EPSILON * 10 }, // value: pi - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - cos_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - cos_test1_validate(-tests[i].value, tests[i].expected, tests[i].variance); - } - - cos_test1_validate_isnan(PAL_NEGINF); - cos_test1_validate_isnan(PAL_NAN); - cos_test1_validate_isnan(PAL_POSINF); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/cosf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/cosf/test1/test1.cpp deleted file mode 100644 index ed3a4512b7fe7e..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/cosf/test1/test1.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that cosf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * cosf_test1_validate - * - * test validation function - */ -void __cdecl cosf_test1_validate(float value, float expected, float variance) -{ - float result = cosf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("cosf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * cosf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl cosf_test1_validate_isnan(float value) -{ - float result = cosf(value); - - if (!_isnanf(result)) - { - Fail("cosf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_cosf_test1_paltest_cosf_test1, "c_runtime/cosf/test1/paltest_cosf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 1, PAL_EPSILON * 10 }, - { 0.318309886f, 0.949765715f, PAL_EPSILON }, // value: 1 / pi - { 0.434294482f, 0.907167129f, PAL_EPSILON }, // value: log10f(e) - { 0.636619772f, 0.804109828f, PAL_EPSILON }, // value: 2 / pi - { 0.693147181f, 0.769238901f, PAL_EPSILON }, // value: ln(2) - { 0.707106781f, 0.760244597f, PAL_EPSILON }, // value: 1 / sqrtf(2) - { 0.785398163f, 0.707106781f, PAL_EPSILON }, // value: pi / 4, expected: 1 / sqrtf(2) - { 1, 0.540302306f, PAL_EPSILON }, - { 1.12837917f, 0.428125148f, PAL_EPSILON }, // value: 2 / sqrtf(pi) - { 1.41421356f, 0.155943695f, PAL_EPSILON }, // value: sqrtf(2) - { 1.44269504f, 0.127751218f, PAL_EPSILON }, // value: logf2(e) - { 1.57079633f, 0, PAL_EPSILON }, // value: pi / 2 - { 2.30258509f, -0.668201510f, PAL_EPSILON }, // value: ln(10) - { 2.71828183f, -0.911733918f, PAL_EPSILON }, // value: e - { 3.14159265f, -1, PAL_EPSILON * 10 }, // value: pi - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - cosf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - cosf_test1_validate(-tests[i].value, tests[i].expected, tests[i].variance); - } - - cosf_test1_validate_isnan(PAL_NEGINF); - cosf_test1_validate_isnan(PAL_NAN); - cosf_test1_validate_isnan(PAL_POSINF); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/cosh/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/cosh/test1/test1.cpp deleted file mode 100644 index 78518b78e0e45f..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/cosh/test1/test1.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that cosh return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * cosh_test1_validate - * - * test validation function - */ -void __cdecl cosh_test1_validate(double value, double expected, double variance) -{ - double result = cosh(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("cosh(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * cosh_test1_validate - * - * test validation function for values returning PAL_NAN - */ -void __cdecl cosh_test1_validate_isnan(double value) -{ - double result = cosh(value); - - if (!_isnan(result)) - { - Fail("cosh(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_cosh_test1_paltest_cosh_test1, "c_runtime/cosh/test1/paltest_cosh_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 1, PAL_EPSILON * 10 }, - { 0.31830988618379067, 1.0510897883672876, PAL_EPSILON * 10 }, // value: 1 / pi - { 0.43429448190325183, 1.0957974645564909, PAL_EPSILON * 10 }, // value: log10(e) - { 0.63661977236758134, 1.2095794864199787, PAL_EPSILON * 10 }, // value: 2 / pi - { 0.69314718055994531, 1.25, PAL_EPSILON * 10 }, // value: ln(2) - { 0.70710678118654752, 1.2605918365213561, PAL_EPSILON * 10 }, // value: 1 / sqrt(2) - { 0.78539816339744831, 1.3246090892520058, PAL_EPSILON * 10 }, // value: pi / 4 - { 1, 1.5430806348152438, PAL_EPSILON * 10 }, - { 1.1283791670955126, 1.7071001431069344, PAL_EPSILON * 10 }, // value: 2 / sqrt(pi) - { 1.4142135623730950, 2.1781835566085709, PAL_EPSILON * 10 }, // value: sqrt(2) - { 1.4426950408889634, 2.2341880974508023, PAL_EPSILON * 10 }, // value: log2(e) - { 1.5707963267948966, 2.5091784786580568, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.3025850929940457, 5.05, PAL_EPSILON * 10 }, // value: ln(10) - { 2.7182818284590452, 7.6101251386622884, PAL_EPSILON * 10 }, // value: e - { 3.1415926535897932, 11.591953275521521, PAL_EPSILON * 100 }, // value: pi - { PAL_POSINF, PAL_POSINF, 0 }, - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - cosh_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - cosh_test1_validate(-tests[i].value, tests[i].expected, tests[i].variance); - } - - cosh_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/coshf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/coshf/test1/test1.cpp deleted file mode 100644 index 27ba18c080f433..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/coshf/test1/test1.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that coshf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * coshf_test1_validate - * - * test validation function - */ -void __cdecl coshf_test1_validate(float value, float expected, float variance) -{ - float result = coshf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("coshf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * coshf_test1_validate - * - * test validation function for values returning PAL_NAN - */ -void __cdecl coshf_test1_validate_isnan(float value) -{ - float result = coshf(value); - - if (!_isnanf(result)) - { - Fail("coshf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_coshf_test1_paltest_coshf_test1, "c_runtime/coshf/test1/paltest_coshf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 1, PAL_EPSILON * 10 }, - { 0.318309886f, 1.05108979f, PAL_EPSILON * 10 }, // value: 1 / pi - { 0.434294482f, 1.09579746f, PAL_EPSILON * 10 }, // value: log10f(e) - { 0.636619772f, 1.20957949f, PAL_EPSILON * 10 }, // value: 2 / pi - { 0.693147181f, 1.25f, PAL_EPSILON * 10 }, // value: ln(2) - { 0.707106781f, 1.26059184f, PAL_EPSILON * 10 }, // value: 1 / sqrtf(2) - { 0.785398163f, 1.32460909f, PAL_EPSILON * 10 }, // value: pi / 4 - { 1, 1.54308063f, PAL_EPSILON * 10 }, - { 1.12837917f, 1.70710014f, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi) - { 1.41421356f, 2.17818356f, PAL_EPSILON * 10 }, // value: sqrtf(2) - { 1.44269504f, 2.23418810f, PAL_EPSILON * 10 }, // value: logf2(e) - { 1.57079633f, 2.50917848f, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.30258509f, 5.05f, PAL_EPSILON * 10 }, // value: ln(10) - { 2.71828183f, 7.61012514f, PAL_EPSILON * 10 }, // value: e - { 3.14159265f, 11.5919533f, PAL_EPSILON * 100 }, // value: pi - { PAL_POSINF, PAL_POSINF, 0 }, - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - coshf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - coshf_test1_validate(-tests[i].value, tests[i].expected, tests[i].variance); - } - - coshf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/exp/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/exp/test1/test1.cpp deleted file mode 100644 index b3c8bb9307e07a..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/exp/test1/test1.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests exp with a normal set of values. -** -**===================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * exp_test1_validate - * - * test validation function - */ -void __cdecl exp_test1_validate(double value, double expected, double variance) -{ - double result = exp(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("exp(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * exp_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl exp_test1_validate_isnan(double value) -{ - double result = exp(value); - - if (!_isnan(result)) - { - Fail("exp(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_exp_test1_paltest_exp_test1, "c_runtime/exp/test1/paltest_exp_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { PAL_NEGINF, 0, PAL_EPSILON }, - { -3.1415926535897932, 0.043213918263772250, PAL_EPSILON / 10 }, // value: -(pi) - { -2.7182818284590452, 0.065988035845312537, PAL_EPSILON / 10 }, // value: -(e) - { -2.3025850929940457, 0.1, PAL_EPSILON }, // value: -(ln(10)) - { -1.5707963267948966, 0.20787957635076191, PAL_EPSILON }, // value: -(pi / 2) - { -1.4426950408889634, 0.23629008834452270, PAL_EPSILON }, // value: -(log2(e)) - { -1.4142135623730950, 0.24311673443421421, PAL_EPSILON }, // value: -(sqrt(2)) - { -1.1283791670955126, 0.32355726390307110, PAL_EPSILON }, // value: -(2 / sqrt(pi)) - { -1, 0.36787944117144232, PAL_EPSILON }, // value: -(1) - { -0.78539816339744831, 0.45593812776599624, PAL_EPSILON }, // value: -(pi / 4) - { -0.70710678118654752, 0.49306869139523979, PAL_EPSILON }, // value: -(1 / sqrt(2)) - { -0.69314718055994531, 0.5, PAL_EPSILON }, // value: -(ln(2)) - { -0.63661977236758134, 0.52907780826773535, PAL_EPSILON }, // value: -(2 / pi) - { -0.43429448190325183, 0.64772148514180065, PAL_EPSILON }, // value: -(log10(e)) - { -0.31830988618379067, 0.72737734929521647, PAL_EPSILON }, // value: -(1 / pi) - { 0, 1, PAL_EPSILON * 10 }, - { 0.31830988618379067, 1.3748022274393586, PAL_EPSILON * 10 }, // value: 1 / pi - { 0.43429448190325183, 1.5438734439711811, PAL_EPSILON * 10 }, // value: log10(e) - { 0.63661977236758134, 1.8900811645722220, PAL_EPSILON * 10 }, // value: 2 / pi - { 0.69314718055994531, 2, PAL_EPSILON * 10 }, // value: ln(2) - { 0.70710678118654752, 2.0281149816474725, PAL_EPSILON * 10 }, // value: 1 / sqrt(2) - { 0.78539816339744831, 2.1932800507380155, PAL_EPSILON * 10 }, // value: pi / 4 - { 1, 2.7182818284590452, PAL_EPSILON * 10 }, // expected: e - { 1.1283791670955126, 3.0906430223107976, PAL_EPSILON * 10 }, // value: 2 / sqrt(pi) - { 1.4142135623730950, 4.1132503787829275, PAL_EPSILON * 10 }, // value: sqrt(2) - { 1.4426950408889634, 4.2320861065570819, PAL_EPSILON * 10 }, // value: log2(e) - { 1.5707963267948966, 4.8104773809653517, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.3025850929940457, 10, PAL_EPSILON * 100 }, // value: ln(10) - { 2.7182818284590452, 15.154262241479264, PAL_EPSILON * 100 }, // value: e - { 3.1415926535897932, 23.140692632779269, PAL_EPSILON * 100 }, // value: pi - { PAL_POSINF, PAL_POSINF, 0 }, - }; - - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - exp_test1_validate(tests[i].value, tests[i].expected, tests[i].variance); - } - - exp_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/expf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/expf/test1/test1.cpp deleted file mode 100644 index 72d417ff180a92..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/expf/test1/test1.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests expf with a normal set of values. -** -**===================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * expf_test1_validate - * - * test validation function - */ -void __cdecl expf_test1_validate(float value, float expected, float variance) -{ - float result = expf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("expf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * expf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl expf_test1_validate_isnan(float value) -{ - float result = expf(value); - - if (!_isnanf(result)) - { - Fail("expf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_expf_test1_paltest_expf_test1, "c_runtime/expf/test1/paltest_expf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { PAL_NEGINF, 0, PAL_EPSILON }, - { -3.14159265f, 0.0432139183f, PAL_EPSILON / 10 }, // value: -(pi) - { -2.71828183f, 0.0659880358f, PAL_EPSILON / 10 }, // value: -(e) - { -2.30258509f, 0.1f, PAL_EPSILON }, // value: -(ln(10)) - { -1.57079633f, 0.207879576f, PAL_EPSILON }, // value: -(pi / 2) - { -1.44269504f, 0.236290088f, PAL_EPSILON }, // value: -(logf2(e)) - { -1.41421356f, 0.243116734f, PAL_EPSILON }, // value: -(sqrtf(2)) - { -1.12837917f, 0.323557264f, PAL_EPSILON }, // value: -(2 / sqrtf(pi)) - { -1, 0.367879441f, PAL_EPSILON }, // value: -(1) - { -0.785398163f, 0.455938128f, PAL_EPSILON }, // value: -(pi / 4) - { -0.707106781f, 0.493068691f, PAL_EPSILON }, // value: -(1 / sqrtf(2)) - { -0.693147181f, 0.5f, PAL_EPSILON }, // value: -(ln(2)) - { -0.636619772f, 0.529077808f, PAL_EPSILON }, // value: -(2 / pi) - { -0.434294482f, 0.647721485f, PAL_EPSILON }, // value: -(log10f(e)) - { -0.318309886f, 0.727377349f, PAL_EPSILON }, // value: -(1 / pi) - { 0, 1, PAL_EPSILON * 10 }, - { 0.318309886f, 1.37480223f, PAL_EPSILON * 10 }, // value: 1 / pi - { 0.434294482f, 1.54387344f, PAL_EPSILON * 10 }, // value: log10f(e) - { 0.636619772f, 1.89008116f, PAL_EPSILON * 10 }, // value: 2 / pi - { 0.693147181f, 2, PAL_EPSILON * 10 }, // value: ln(2) - { 0.707106781f, 2.02811498f, PAL_EPSILON * 10 }, // value: 1 / sqrtf(2) - { 0.785398163f, 2.19328005f, PAL_EPSILON * 10 }, // value: pi / 4 - { 1, 2.71828183f, PAL_EPSILON * 10 }, // expected: e - { 1.12837917f, 3.09064302f, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi) - { 1.41421356f, 4.11325038f, PAL_EPSILON * 10 }, // value: sqrtf(2) - { 1.44269504f, 4.23208611f, PAL_EPSILON * 10 }, // value: logf2(e) - { 1.57079633f, 4.81047738f, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.30258509f, 10, PAL_EPSILON * 100 }, // value: ln(10) - { 2.71828183f, 15.1542622f, PAL_EPSILON * 100 }, // value: e - { 3.14159265f, 23.1406926f, PAL_EPSILON * 100 }, // value: pi - { PAL_POSINF, PAL_POSINF, 0 }, - }; - - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - expf_test1_validate(tests[i].value, tests[i].expected, tests[i].variance); - } - - expf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/floor/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/floor/test1/test1.cpp deleted file mode 100644 index 549a2d83a0de56..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/floor/test1/test1.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Tests floor with simple positive and negative values. Also tests -** extreme cases like extremely small values and positive and -** negative infinity. Makes sure that calling floor on NaN returns -** NaN -** -**==========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * floor_test1_validate - * - * test validation function - */ -void __cdecl floor_test1_validate(double value, double expected, double variance) -{ - double result = floor(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("floor(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * floor_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl floor_test1_validate_isnan(double value) -{ - double result = floor(value); - - if (!_isnan(result)) - { - Fail("floor(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_floor_test1_paltest_floor_test1, "c_runtime/floor/test1/paltest_floor_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0.31830988618379067, 0, PAL_EPSILON }, // value: 1 / pi - { 0.43429448190325183, 0, PAL_EPSILON }, // value: log10(e) - { 0.63661977236758134, 0, PAL_EPSILON }, // value: 2 / pi - { 0.69314718055994531, 0, PAL_EPSILON }, // value: ln(2) - { 0.70710678118654752, 0, PAL_EPSILON }, // value: 1 / sqrt(2) - { 0.78539816339744831, 0, PAL_EPSILON }, // value: pi / 4 - { 1.1283791670955126, 1, PAL_EPSILON * 10 }, // value: 2 / sqrt(pi) - { 1.4142135623730950, 1, PAL_EPSILON * 10 }, // value: sqrt(2) - { 1.4426950408889634, 1, PAL_EPSILON * 10 }, // value: log2(e) - { 1.5707963267948966, 1, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.3025850929940457, 2, PAL_EPSILON * 10 }, // value: ln(10) - { 2.7182818284590452, 2, PAL_EPSILON * 10 }, // value: e - { 3.1415926535897932, 3, PAL_EPSILON * 10 }, // value: pi - { PAL_POSINF, PAL_POSINF, 0 } - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - floor_test1_validate( 0, 0, PAL_EPSILON); - floor_test1_validate(-0.0, 0, PAL_EPSILON); - - floor_test1_validate( 1, 1, PAL_EPSILON * 10); - floor_test1_validate(-1.0, -1, PAL_EPSILON * 10); - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - floor_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - floor_test1_validate(-tests[i].value, -(tests[i].expected + 1), tests[i].variance); - } - - floor_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/floorf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/floorf/test1/test1.cpp deleted file mode 100644 index b80320c7de317c..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/floorf/test1/test1.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Tests floorf with simple positive and negative values. Also tests -** extreme cases like extremely small values and positive and -** negative infinity. Makes sure that calling floorf on NaN returns -** NaN -** -**==========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * floorf_test1_validate - * - * test validation function - */ -void __cdecl floorf_test1_validate(float value, float expected, float variance) -{ - float result = floorf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("floorf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * floorf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl floorf_test1_validate_isnan(float value) -{ - float result = floorf(value); - - if (!_isnanf(result)) - { - Fail("floorf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_floorf_test1_paltest_floorf_test1, "c_runtime/floorf/test1/paltest_floorf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0.318309886f, 0, PAL_EPSILON }, // value: 1 / pi - { 0.434294482f, 0, PAL_EPSILON }, // value: log10f(e) - { 0.636619772f, 0, PAL_EPSILON }, // value: 2 / pi - { 0.693147181f, 0, PAL_EPSILON }, // value: ln(2) - { 0.707106781f, 0, PAL_EPSILON }, // value: 1 / sqrtf(2) - { 0.785398163f, 0, PAL_EPSILON }, // value: pi / 4 - { 1.12837917f, 1, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi) - { 1.41421356f, 1, PAL_EPSILON * 10 }, // value: sqrtf(2) - { 1.44269504f, 1, PAL_EPSILON * 10 }, // value: logf2(e) - { 1.57079633f, 1, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.30258509f, 2, PAL_EPSILON * 10 }, // value: ln(10) - { 2.71828183f, 2, PAL_EPSILON * 10 }, // value: e - { 3.14159265f, 3, PAL_EPSILON * 10 }, // value: pi - { PAL_POSINF, PAL_POSINF, 0 } - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - floorf_test1_validate( 0, 0, PAL_EPSILON); - floorf_test1_validate(-0.0f, 0, PAL_EPSILON); - - floorf_test1_validate( 1, 1, PAL_EPSILON * 10); - floorf_test1_validate(-1.0f, -1, PAL_EPSILON * 10); - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - floorf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - floorf_test1_validate(-tests[i].value, -(tests[i].expected + 1), tests[i].variance); - } - - floorf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/ilogb/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/ilogb/test1/test1.cpp deleted file mode 100644 index 9fbd270d52579c..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/ilogb/test1/test1.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests that ilogb returns correct values. -** -**===================================================================*/ - -#include - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - int expected; /* expected result */ -}; - -/** - * ilogb_test1_validate - * - * test validation function - */ -void __cdecl ilogb_test1_validate(double value, int expected) -{ - int result = ilogb(value); - - if (result != expected) - { - Fail("ilogb(%g) returned %d when it should have returned %d", - value, result, expected); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_ilogb_test1_paltest_ilogb_test1, "c_runtime/ilogb/test1/paltest_ilogb_test1") -{ - struct test tests[] = - { - /* value expected */ - { PAL_NEGINF, 2147483647 }, - { 0, -2147483648 }, - { PAL_POSINF, 2147483647 }, - { 0.11331473229676087, -4 }, // expected: -(pi) - { 0.15195522325791297, -3 }, // expected: -(e) - { 0.20269956628651730, -3 }, // expected: -(ln(10)) - { 0.33662253682241906, -2 }, // expected: -(pi / 2) - { 0.36787944117144232, -2 }, // expected: -(log2(e)) - { 0.37521422724648177, -2 }, // expected: -(sqrt(2)) - { 0.45742934732229695, -2 }, // expected: -(2 / sqrt(pi)) - { 0.5, -1 }, // expected: -(1) - { 0.58019181037172444, -1 }, // expected: -(pi / 4) - { 0.61254732653606592, -1 }, // expected: -(1 / sqrt(2)) - { 0.61850313780157598, -1 }, // expected: -(ln(2)) - { 0.64321824193300488, -1 }, // expected: -(2 / pi) - { 0.74005557395545179, -1 }, // expected: -(log10(e)) - { 0.80200887896145195, -1 }, // expected: -(1 / pi) - { 1, 0 }, - { 1.2468689889006383, 0 }, // expected: 1 / pi - { 1.3512498725672678, 0 }, // expected: log10(e) - { 1.5546822754821001, 0 }, // expected: 2 / pi - { 1.6168066722416747, 0 }, // expected: ln(2) - { 1.6325269194381528, 0 }, // expected: 1 / sqrt(2) - { 1.7235679341273495, 0 }, // expected: pi / 4 - { 2, 1 }, - { 2.1861299583286618, 1 }, // expected: 2 / sqrt(pi) - { 2.6651441426902252, 1 }, // expected: sqrt(2) - { 2.7182818284590452, 1 }, // expected: log2(e) value: e - { 2.9706864235520193, 1 }, // expected: pi / 2 - { 4.9334096679145963, 2 }, // expected: ln(10) - { 6.5808859910179210, 2 }, // expected: e - { 8.8249778270762876, 3 }, // expected: pi - { PAL_NAN, 2147483647 }, - }; - - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - ilogb_test1_validate(tests[i].value, tests[i].expected); - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/ilogbf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/ilogbf/test1/test1.cpp deleted file mode 100644 index c5022056c97e42..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/ilogbf/test1/test1.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests that ilogbf returns correct values. -** -**===================================================================*/ - -#include - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - int expected; /* expected result */ -}; - -/** - * ilogbf_test1_validate - * - * test validation function - */ -void __cdecl ilogbf_test1_validate(float value, int expected) -{ - int result = ilogbf(value); - - if (result != expected) - { - Fail("ilogbf(%g) returned %d when it should have returned %d", - value, result, expected); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_ilogbf_test1_paltest_ilogbf_test1, "c_runtime/ilogbf/test1/paltest_ilogbf_test1") -{ - struct test tests[] = - { - /* value expected */ - { PAL_NEGINF, 2147483647 }, - { 0, -2147483648 }, - { PAL_POSINF, 2147483647 }, - { 0.113314732f, -4 }, // expected: -(pi) - { 0.151955223f, -3 }, // expected: -(e) - { 0.202699566f, -3 }, // expected: -(ln(10)) - { 0.336622537f, -2 }, // expected: -(pi / 2) - { 0.367879441f, -2 }, // expected: -(log2(e)) - { 0.375214227f, -2 }, // expected: -(sqrt(2)) - { 0.457429347f, -2 }, // expected: -(2 / sqrt(pi)) - { 0.5f, -1 }, // expected: -(1) - { 0.580191810f, -1 }, // expected: -(pi / 4) - { 0.612547327f, -1 }, // expected: -(1 / sqrt(2)) - { 0.618503138f, -1 }, // expected: -(ln(2)) - { 0.643218242f, -1 }, // expected: -(2 / pi) - { 0.740055574f, -1 }, // expected: -(log10(e)) - { 0.802008879f, -1 }, // expected: -(1 / pi) - { 1, 0 }, - { 1.24686899f, 0 }, // expected: 1 / pi - { 1.35124987f, 0 }, // expected: log10(e) - { 1.55468228f, 0 }, // expected: 2 / pi - { 1.61680667f, 0 }, // expected: ln(2) - { 1.63252692f, 0 }, // expected: 1 / sqrt(2) - { 1.72356793f, 0 }, // expected: pi / 4 - { 2, 1 }, - { 2.18612996f, 1 }, // expected: 2 / sqrt(pi) - { 2.66514414f, 1 }, // expected: sqrt(2) - { 2.71828183f, 1 }, // expected: log2(e) value: e - { 2.97068642f, 1 }, // expected: pi / 2 - { 4.93340967f, 2 }, // expected: ln(10) - { 6.58088599f, 2 }, // expected: e - { 8.82497783f, 3 }, // expected: pi - { PAL_NAN, 2147483647 }, - }; - - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - ilogbf_test1_validate(tests[i].value, tests[i].expected); - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/logf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/logf/test1/test1.cpp deleted file mode 100644 index 7980ae1b28e9e1..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/logf/test1/test1.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests logf with a normal set of values. -** -**===================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * logf_test1_validate - * - * test validation function - */ -void __cdecl logf_test1_validate(float value, float expected, float variance) -{ - float result = logf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("logf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * logf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl logf_test1_validate_isnan(float value) -{ - float result = logf(value); - - if (!_isnanf(result)) - { - Fail("logf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_logf_test1_paltest_logf_test1, "c_runtime/logf/test1/paltest_logf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, PAL_NEGINF, 0 }, - { 0.0432139183f, -3.14159265f, PAL_EPSILON * 10 }, // expected: -(pi) - { 0.0659880358f, -2.71828183f, PAL_EPSILON * 10 }, // expected: -(e) - { 0.1f, -2.30258509f, PAL_EPSILON * 10 }, // expected: -(ln(10)) - { 0.207879576f, -1.57079633f, PAL_EPSILON * 10 }, // expected: -(pi / 2) - { 0.236290088f, -1.44269504f, PAL_EPSILON * 10 }, // expected: -(logf2(e)) - { 0.243116734f, -1.41421356f, PAL_EPSILON * 10 }, // expected: -(sqrtf(2)) - { 0.323557264f, -1.12837917f, PAL_EPSILON * 10 }, // expected: -(2 / sqrtf(pi)) - { 0.367879441f, -1, PAL_EPSILON * 10 }, // expected: -(1) - { 0.455938128f, -0.785398163f, PAL_EPSILON }, // expected: -(pi / 4) - { 0.493068691f, -0.707106781f, PAL_EPSILON }, // expected: -(1 / sqrtf(2)) - { 0.5f, -0.693147181f, PAL_EPSILON }, // expected: -(ln(2)) - { 0.529077808f, -0.636619772f, PAL_EPSILON }, // expected: -(2 / pi) - { 0.647721485f, -0.434294482f, PAL_EPSILON }, // expected: -(log10f(e)) - { 0.727377349f, -0.318309886f, PAL_EPSILON }, // expected: -(1 / pi) - { 1, 0, PAL_EPSILON }, - { 1.37480223f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi - { 1.54387344f, 0.434294482f, PAL_EPSILON }, // expected: log10f(e) - { 1.89008116f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi - { 2, 0.693147181f, PAL_EPSILON }, // expected: ln(2) - { 2.02811498f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2) - { 2.19328005f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4 - { 2.71828183f, 1, PAL_EPSILON * 10 }, // value: e - { 3.09064302f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi) - { 4.11325038f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2) - { 4.23208611f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e) - { 4.81047738f, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2 - { 10, 2.30258509f, PAL_EPSILON * 10 }, // expected: ln(10) - { 15.1542622f, 2.71828183f, PAL_EPSILON * 10 }, // expected: e - { 23.1406926f, 3.14159265f, PAL_EPSILON * 10 }, // expected: pi - { PAL_POSINF, PAL_POSINF, 0 }, - }; - - - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - logf_test1_validate(tests[i].value, tests[i].expected, tests[i].variance); - } - - logf_test1_validate_isnan(PAL_NEGINF); - logf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/modf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/modf/test1/test1.cpp deleted file mode 100644 index 726e524d0a4e8e..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/modf/test1/test1.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c (modf) -** -** Purpose: Test to ensure that modf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ - double expected_intpart; /* expected result */ - double variance_intpart; /* maximum delta between the expected and actual result */ -}; - -/** - * modf_test1_validate - * - * test validation function - */ -void __cdecl modf_test1_validate(double value, double expected, double variance, double expected_intpart, double variance_intpart) -{ - double result_intpart; - double result = modf(value, &result_intpart); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - double delta_intpart = fabs(result_intpart - expected_intpart); - - if ((delta > variance) || (delta_intpart > variance_intpart)) - { - Fail("modf(%g) returned %20.17g with an intpart of %20.17g when it should have returned %20.17g with an intpart of %20.17g", - value, result, result_intpart, expected, expected_intpart); - } -} - -/** - * modf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl modf_test1_validate_isnan(double value) -{ - double result_intpart; - double result = modf(value, &result_intpart); - - if (!_isnan(result) || !_isnan(result_intpart)) - { - Fail("modf(%g) returned %20.17g with an intpart of %20.17g when it should have returned %20.17g with an intpart of %20.17g", - value, result, result_intpart, PAL_NAN, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_modf_test1_paltest_modf_test1, "c_runtime/modf/test1/paltest_modf_test1") -{ - struct test tests[] = - { - /* value expected variance expected_intpart variance_intpart */ - { 0, 0, PAL_EPSILON, 0, PAL_EPSILON }, - { 0.31830988618379067, 0.31830988618379067, PAL_EPSILON, 0, PAL_EPSILON }, // value: 1 / pi - { 0.43429448190325183, 0.43429448190325183, PAL_EPSILON, 0, PAL_EPSILON }, // value: log10(e) - { 0.63661977236758134, 0.63661977236758134, PAL_EPSILON, 0, PAL_EPSILON }, // value: 2 / pi - { 0.69314718055994531, 0.69314718055994531, PAL_EPSILON, 0, PAL_EPSILON }, // value: ln(2) - { 0.70710678118654752, 0.70710678118654752, PAL_EPSILON, 0, PAL_EPSILON }, // value: 1 / sqrt(2) - { 0.78539816339744831, 0.78539816339744831, PAL_EPSILON, 0, PAL_EPSILON }, // value: pi / 4 - { 1, 0, PAL_EPSILON, 1, PAL_EPSILON * 10 }, - { 1.1283791670955126, 0.1283791670955126, PAL_EPSILON, 1, PAL_EPSILON * 10 }, // value: 2 / sqrt(pi) - { 1.4142135623730950, 0.4142135623730950, PAL_EPSILON, 1, PAL_EPSILON * 10 }, // value: sqrt(2) - { 1.4426950408889634, 0.4426950408889634, PAL_EPSILON, 1, PAL_EPSILON * 10 }, // value: log2(e) - { 1.5707963267948966, 0.5707963267948966, PAL_EPSILON, 1, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.3025850929940457, 0.3025850929940457, PAL_EPSILON, 2, PAL_EPSILON * 10 }, // value: ln(10) - { 2.7182818284590452, 0.7182818284590452, PAL_EPSILON, 2, PAL_EPSILON * 10 }, // value: e - { 3.1415926535897932, 0.1415926535897932, PAL_EPSILON, 3, PAL_EPSILON * 10 }, // value: pi - { PAL_POSINF, 0, PAL_EPSILON, PAL_POSINF, 0 } - - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - modf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance, tests[i].expected_intpart, tests[i].variance_intpart); - modf_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance, -tests[i].expected_intpart, tests[i].variance_intpart); - } - - modf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/modff/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/modff/test1/test1.cpp deleted file mode 100644 index 898566b27398b4..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/modff/test1/test1.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c (modf) -** -** Purpose: Test to ensure that modf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ - float expected_intpart; /* expected result */ - float variance_intpart; /* maximum delta between the expected and actual result */ -}; - -/** - * modff_test1_validate - * - * test validation function - */ -void __cdecl modff_test1_validate(float value, float expected, float variance, float expected_intpart, float variance_intpart) -{ - float result_intpart; - float result = modff(value, &result_intpart); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - float delta_intpart = fabsf(result_intpart - expected_intpart); - - if ((delta > variance) || (delta_intpart > variance_intpart)) - { - Fail("modff(%g) returned %10.9g with an intpart of %10.9g when it should have returned %10.9g with an intpart of %10.9g", - value, result, result_intpart, expected, expected_intpart); - } -} - -/** - * modff_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl modff_test1_validate_isnan(float value) -{ - float result_intpart; - float result = modff(value, &result_intpart); - - if (!_isnan(result) || !_isnan(result_intpart)) - { - Fail("modff(%g) returned %10.9g with an intpart of %10.9g when it should have returned %10.9g with an intpart of %10.9g", - value, result, result_intpart, PAL_NAN, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_modff_test1_paltest_modff_test1, "c_runtime/modff/test1/paltest_modff_test1") -{ - struct test tests[] = - { - /* value expected variance expected_intpart variance_intpart */ - { 0, 0, PAL_EPSILON, 0, PAL_EPSILON }, - { 0.318309886f, 0.318309886f, PAL_EPSILON, 0, PAL_EPSILON }, // value: 1 / pi - { 0.434294482f, 0.434294482f, PAL_EPSILON, 0, PAL_EPSILON }, // value: log10(e) - { 0.636619772f, 0.636619772f, PAL_EPSILON, 0, PAL_EPSILON }, // value: 2 / pi - { 0.693147181f, 0.693147181f, PAL_EPSILON, 0, PAL_EPSILON }, // value: ln(2) - { 0.707106781f, 0.707106781f, PAL_EPSILON, 0, PAL_EPSILON }, // value: 1 / sqrt(2) - { 0.785398163f, 0.785398163f, PAL_EPSILON, 0, PAL_EPSILON }, // value: pi / 4 - { 1, 0, PAL_EPSILON, 1, PAL_EPSILON * 10 }, - { 1.12837917f, 0.128379167f, PAL_EPSILON, 1, PAL_EPSILON * 10 }, // value: 2 / sqrt(pi) - { 1.41421356f, 0.414213562f, PAL_EPSILON, 1, PAL_EPSILON * 10 }, // value: sqrt(2) - { 1.44269504f, 0.442695041f, PAL_EPSILON, 1, PAL_EPSILON * 10 }, // value: log2(e) - { 1.57079633f, 0.570796327f, PAL_EPSILON, 1, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.30258509f, 0.302585093f, PAL_EPSILON, 2, PAL_EPSILON * 10 }, // value: ln(10) - { 2.71828183f, 0.718281828f, PAL_EPSILON, 2, PAL_EPSILON * 10 }, // value: e - { 3.14159265f, 0.141592654f, PAL_EPSILON, 3, PAL_EPSILON * 10 }, // value: pi - { PAL_POSINF, 0, PAL_EPSILON, PAL_POSINF, 0 } - - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - modff_test1_validate( tests[i].value, tests[i].expected, tests[i].variance, tests[i].expected_intpart, tests[i].variance_intpart); - modff_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance, -tests[i].expected_intpart, tests[i].variance_intpart); - } - - modff_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp deleted file mode 100644 index 22f482868b3d86..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp +++ /dev/null @@ -1,229 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests that atan2 returns correct values for a subset of values. -** Tests with positive and negative values of x and y to ensure -** atan2 is returning results from the correct quadrant. -** -**===================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double x; /* first component of the value to test the function with */ - double y; /* second component of the value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * pow_test1_validate - * - * test validation function - */ -void __cdecl pow_test1_validate(double x, double y, double expected, double variance) -{ - double result = pow(x, y); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("pow(%g, %g) returned %20.17g when it should have returned %20.17g", - x, y, result, expected); - } -} - -/** - * pow_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl pow_test1_validate_isnan(double x, double y) -{ - double result = pow(x, y); - - if (!_isnan(result)) - { - Fail("pow(%g, %g) returned %20.17g when it should have returned %20.17g", - x, y, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_pow_test1_paltest_pow_test1, "c_runtime/pow/test1/paltest_pow_test1") -{ - struct test tests[] = - { - /* x y expected variance */ - { PAL_NEGINF, PAL_NEGINF, 0, PAL_EPSILON }, - { PAL_NEGINF, PAL_POSINF, PAL_POSINF, 0 }, - - { -10, PAL_NEGINF, 0, PAL_EPSILON }, - { -10, -1, -0.1, PAL_EPSILON }, - { -10, 0, 1, PAL_EPSILON * 10 }, - { -10, 1, -10, PAL_EPSILON * 100 }, - { -10, PAL_POSINF, PAL_POSINF, 0 }, - - { -2.7182818284590452, PAL_NEGINF, 0, PAL_EPSILON }, // x: -(e) - { -2.7182818284590452, -1, -0.36787944117144232, PAL_EPSILON }, // x: -(e) - { -2.7182818284590452, 0, 1, PAL_EPSILON * 10 }, // x: -(e) - { -2.7182818284590452, 1, -2.7182818284590452, PAL_EPSILON * 10 }, // x: -(e) expected: e - { -2.7182818284590452, PAL_POSINF, PAL_POSINF, 0 }, // x: -(e) - - { -1.0, PAL_NEGINF, 1.0, PAL_EPSILON * 10 }, - { -1.0, PAL_POSINF, 1.0, PAL_EPSILON * 10 }, - - { -0.0, PAL_NEGINF, PAL_POSINF, 0 }, - { -0.0, -1, PAL_NEGINF, 0 }, - { -0.0, -0.0, 1, PAL_EPSILON * 10 }, - { -0.0, 0, 1, PAL_EPSILON * 10 }, - { -0.0, 1, -0.0, PAL_EPSILON }, - { -0.0, PAL_POSINF, 0, PAL_EPSILON }, - - { PAL_NAN, -0.0, 1.0, PAL_EPSILON * 10 }, - { PAL_NAN, 0, 1.0, PAL_EPSILON * 10 }, - - { 0.0, PAL_NEGINF, PAL_POSINF, 0 }, - { 0.0, -1, PAL_POSINF, 0 }, - { 0, -0.0, 1, PAL_EPSILON * 10 }, - { 0, 0, 1, PAL_EPSILON * 10 }, - { 0.0, 1, 0, PAL_EPSILON }, - { 0.0, PAL_POSINF, 0, PAL_EPSILON }, - - { 1, PAL_NEGINF, 1, PAL_EPSILON * 10 }, - { 1, PAL_POSINF, 1, PAL_EPSILON * 10 }, - - { 2.7182818284590452, PAL_NEGINF, 0, PAL_EPSILON }, - { 2.7182818284590452, -3.1415926535897932, 0.043213918263772250, PAL_EPSILON / 10 }, // x: e y: -(pi) - { 2.7182818284590452, -2.7182818284590452, 0.065988035845312537, PAL_EPSILON / 10 }, // x: e y: -(e) - { 2.7182818284590452, -2.3025850929940457, 0.1, PAL_EPSILON }, // x: e y: -(ln(10)) - { 2.7182818284590452, -1.5707963267948966, 0.20787957635076191, PAL_EPSILON }, // x: e y: -(pi / 2) - { 2.7182818284590452, -1.4426950408889634, 0.23629008834452270, PAL_EPSILON }, // x: e y: -(log2(e)) - { 2.7182818284590452, -1.4142135623730950, 0.24311673443421421, PAL_EPSILON }, // x: e y: -(sqrt(2)) - { 2.7182818284590452, -1.1283791670955126, 0.32355726390307110, PAL_EPSILON }, // x: e y: -(2 / sqrt(pi)) - { 2.7182818284590452, -1, 0.36787944117144232, PAL_EPSILON }, // x: e y: -(1) - { 2.7182818284590452, -0.78539816339744831, 0.45593812776599624, PAL_EPSILON }, // x: e y: -(pi / 4) - { 2.7182818284590452, -0.70710678118654752, 0.49306869139523979, PAL_EPSILON }, // x: e y: -(1 / sqrt(2)) - { 2.7182818284590452, -0.69314718055994531, 0.5, PAL_EPSILON }, // x: e y: -(ln(2)) - { 2.7182818284590452, -0.63661977236758134, 0.52907780826773535, PAL_EPSILON }, // x: e y: -(2 / pi) - { 2.7182818284590452, -0.43429448190325183, 0.64772148514180065, PAL_EPSILON }, // x: e y: -(log10(e)) - { 2.7182818284590452, -0.31830988618379067, 0.72737734929521647, PAL_EPSILON }, // x: e y: -(1 / pi) - { 2.7182818284590452, 0, 1, PAL_EPSILON * 10 }, // x: e - { 2.7182818284590452, 0.31830988618379067, 1.3748022274393586, PAL_EPSILON * 10 }, // x: e y: 1 / pi - { 2.7182818284590452, 0.43429448190325183, 1.5438734439711811, PAL_EPSILON * 10 }, // x: e y: log10(e) - { 2.7182818284590452, 0.63661977236758134, 1.8900811645722220, PAL_EPSILON * 10 }, // x: e y: 2 / pi - { 2.7182818284590452, 0.69314718055994531, 2, PAL_EPSILON * 10 }, // x: e y: ln(2) - { 2.7182818284590452, 0.70710678118654752, 2.0281149816474725, PAL_EPSILON * 10 }, // x: e y: 1 / sqrt(2) - { 2.7182818284590452, 0.78539816339744831, 2.1932800507380155, PAL_EPSILON * 10 }, // x: e y: pi / 4 - { 2.7182818284590452, 1, 2.7182818284590452, PAL_EPSILON * 10 }, // x: e expected: e - { 2.7182818284590452, 1.1283791670955126, 3.0906430223107976, PAL_EPSILON * 10 }, // x: e y: 2 / sqrt(pi) - { 2.7182818284590452, 1.4142135623730950, 4.1132503787829275, PAL_EPSILON * 10 }, // x: e y: sqrt(2) - { 2.7182818284590452, 1.4426950408889634, 4.2320861065570819, PAL_EPSILON * 10 }, // x: e y: log2(e) - { 2.7182818284590452, 1.5707963267948966, 4.8104773809653517, PAL_EPSILON * 10 }, // x: e y: pi / 2 - { 2.7182818284590452, 2.3025850929940457, 10, PAL_EPSILON * 100 }, // x: e y: ln(10) - { 2.7182818284590452, 2.7182818284590452, 15.154262241479264, PAL_EPSILON * 100 }, // x: e y: e - { 2.7182818284590452, 3.1415926535897932, 23.140692632779269, PAL_EPSILON * 100 }, // x: e y: pi - { 2.7182818284590452, PAL_POSINF, PAL_POSINF, 0 }, // x: e - - { 10, PAL_NEGINF, 0, 0 }, - { 10, -3.1415926535897932, 0.00072178415907472774, PAL_EPSILON / 1000 }, // y: -(pi) - { 10, -2.7182818284590452, 0.0019130141022243176, PAL_EPSILON / 100 }, // y: -(e) - { 10, -2.3025850929940457, 0.0049821282964407206, PAL_EPSILON / 100 }, // y: -(ln(10)) - { 10, -1.5707963267948966, 0.026866041001136132, PAL_EPSILON / 10 }, // y: -(pi / 2) - { 10, -1.4426950408889634, 0.036083192820787210, PAL_EPSILON / 10 }, // y: -(log2(e)) - { 10, -1.4142135623730950, 0.038528884700322026, PAL_EPSILON / 10 }, // y: -(sqrt(2)) - { 10, -1.1283791670955126, 0.074408205860642723, PAL_EPSILON / 10 }, // y: -(2 / sqrt(pi)) - { 10, -1, 0.1, PAL_EPSILON }, // y: -(1) - { 10, -0.78539816339744831, 0.16390863613957665, PAL_EPSILON }, // y: -(pi / 4) - { 10, -0.70710678118654752, 0.19628775993505562, PAL_EPSILON }, // y: -(1 / sqrt(2)) - { 10, -0.69314718055994531, 0.20269956628651730, PAL_EPSILON }, // y: -(ln(2)) - { 10, -0.63661977236758134, 0.23087676451600055, PAL_EPSILON }, // y: -(2 / pi) - { 10, -0.43429448190325183, 0.36787944117144232, PAL_EPSILON }, // y: -(log10(e)) - { 10, -0.31830988618379067, 0.48049637305186868, PAL_EPSILON }, // y: -(1 / pi) - { 10, 0, 1, PAL_EPSILON * 10 }, - { 10, 0.31830988618379067, 2.0811811619898573, PAL_EPSILON * 10 }, // y: 1 / pi - { 10, 0.43429448190325183, 2.7182818284590452, PAL_EPSILON * 10 }, // y: log10(e) expected: e - { 10, 0.63661977236758134, 4.3313150290214525, PAL_EPSILON * 10 }, // y: 2 / pi - { 10, 0.69314718055994531, 4.9334096679145963, PAL_EPSILON * 10 }, // y: ln(2) - { 10, 0.70710678118654752, 5.0945611704512962, PAL_EPSILON * 10 }, // y: 1 / sqrt(2) - { 10, 0.78539816339744831, 6.1009598002416937, PAL_EPSILON * 10 }, // y: pi / 4 - { 10, 1, 10, PAL_EPSILON * 100 }, - { 10, 1.1283791670955126, 13.439377934644400, PAL_EPSILON * 100 }, // y: 2 / sqrt(pi) - { 10, 1.4142135623730950, 25.954553519470081, PAL_EPSILON * 100 }, // y: sqrt(2) - { 10, 1.4426950408889634, 27.713733786437790, PAL_EPSILON * 100 }, // y: log2(e) - { 10, 1.5707963267948966, 37.221710484165167, PAL_EPSILON * 100 }, // y: pi / 2 - { 10, 2.3025850929940457, 200.71743249053009, PAL_EPSILON * 1000 }, // y: ln(10) - { 10, 2.7182818284590452, 522.73529967043665, PAL_EPSILON * 1000 }, // y: e - { 10, 3.1415926535897932, 1385.4557313670111, PAL_EPSILON * 10000 }, // y: pi - { 10, PAL_POSINF, PAL_POSINF, 0 }, - - { PAL_POSINF, PAL_NEGINF, 0, PAL_EPSILON }, - { PAL_POSINF, PAL_POSINF, PAL_POSINF, 0 }, - }; - - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - pow_test1_validate(tests[i].x, tests[i].y, tests[i].expected, tests[i].variance); - } - - pow_test1_validate_isnan(-10, -1.5707963267948966); // y: -(pi / 2) - pow_test1_validate_isnan(-10, -0.78539816339744828); // y: -(pi / 4) - pow_test1_validate_isnan(-10, 0.78539816339744828); // y: pi / 4 - pow_test1_validate_isnan(-10, 1.5707963267948966); // y: pi / 2 - - pow_test1_validate_isnan(-2.7182818284590452, -1.5707963267948966); // x: -(e) y: -(pi / 2) - pow_test1_validate_isnan(-2.7182818284590452, -0.78539816339744828); // x: -(e) y: -(pi / 4) - pow_test1_validate_isnan(-2.7182818284590452, 0.78539816339744828); // x: -(e) y: pi / 4 - pow_test1_validate_isnan(-2.7182818284590452, 1.5707963267948966); // x: -(e) y: pi / 2 - - pow_test1_validate_isnan(PAL_NEGINF, PAL_NAN); - pow_test1_validate_isnan(PAL_NAN, PAL_NEGINF); - - pow_test1_validate_isnan(PAL_POSINF, PAL_NAN); - pow_test1_validate_isnan(PAL_NAN, PAL_POSINF); - - pow_test1_validate_isnan(PAL_NAN, PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/powf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/powf/test1/test1.cpp deleted file mode 100644 index 5e704f2d59b612..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/powf/test1/test1.cpp +++ /dev/null @@ -1,228 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests that atan2f returns correct values for a subset of values. -** Tests with positive and negative values of x and y to ensure -** atan2f is returning results from the correct quadrant. -** -**===================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float x; /* first component of the value to test the function with */ - float y; /* second component of the value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * powf_test1_validate - * - * test validation function - */ -void __cdecl powf_test1_validate(float x, float y, float expected, float variance) -{ - float result = powf(x, y); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("powf(%g, %g) returned %10.9g when it should have returned %10.9g", - x, y, result, expected); - } -} - -/** - * powf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl powf_test1_validate_isnan(float x, float y) -{ - float result = powf(x, y); - - if (!_isnanf(result)) - { - Fail("powf(%g, %g) returned %10.9g when it should have returned %10.9g", - x, y, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_powf_test1_paltest_powf_test1, "c_runtime/powf/test1/paltest_powf_test1") -{ - struct test tests[] = - { - /* x y expected variance */ - { PAL_NEGINF, PAL_NEGINF, 0, PAL_EPSILON }, - { PAL_NEGINF, PAL_POSINF, PAL_POSINF, 0 }, - - { -10, PAL_NEGINF, 0, PAL_EPSILON }, - { -10, -1, -0.1f, PAL_EPSILON }, - { -10, 0, 1, PAL_EPSILON * 10 }, - { -10, 1, -10, PAL_EPSILON * 100 }, - { -10, PAL_POSINF, PAL_POSINF, 0 }, - - { -2.71828183f, PAL_NEGINF, 0, PAL_EPSILON }, // x: -(e) - { -2.71828183f, -1, -0.367879441f, PAL_EPSILON }, // x: -(e) - { -2.71828183f, 0, 1, PAL_EPSILON * 10 }, // x: -(e) - { -2.71828183f, 1, -2.71828183f, PAL_EPSILON * 10 }, // x: -(e) expected: e - { -2.71828183f, PAL_POSINF, PAL_POSINF, 0 }, // x: -(e) - - { -1.0, PAL_NEGINF, 1.0, PAL_EPSILON * 10 }, - { -1.0, PAL_POSINF, 1.0, PAL_EPSILON * 10 }, - - { -0.0, PAL_NEGINF, PAL_POSINF, 0 }, - { -0.0, -1, PAL_NEGINF, 0 }, - { -0.0f, -0.0f, 1, PAL_EPSILON * 10 }, - { -0.0f, 0, 1, PAL_EPSILON * 10 }, - { -0.0, 1, -0.0, PAL_EPSILON }, - { -0.0, PAL_POSINF, 0, PAL_EPSILON }, - - { PAL_NAN, -0.0, 1.0, PAL_EPSILON * 10 }, - { PAL_NAN, 0, 1.0, PAL_EPSILON * 10 }, - - { 0.0, PAL_NEGINF, PAL_POSINF, 0 }, - { 0.0, -1, PAL_POSINF, 0 }, - { 0, -0.0f, 1, PAL_EPSILON * 10 }, - { 0, 0, 1, PAL_EPSILON * 10 }, - { 0.0, 1, 0, PAL_EPSILON }, - { 0.0, PAL_POSINF, 0, PAL_EPSILON }, - - { 1, PAL_NEGINF, 1, PAL_EPSILON * 10 }, - { 1, PAL_POSINF, 1, PAL_EPSILON * 10 }, - - { 2.71828183f, PAL_NEGINF, 0, PAL_EPSILON }, - { 2.71828183f, -3.14159265f, 0.0432139183f, PAL_EPSILON / 10 }, // x: e y: -(pi) - { 2.71828183f, -2.71828183f, 0.0659880358f, PAL_EPSILON / 10 }, // x: e y: -(e) - { 2.71828183f, -2.30258509f, 0.1f, PAL_EPSILON }, // x: e y: -(ln(10)) - { 2.71828183f, -1.57079633f, 0.207879576f, PAL_EPSILON }, // x: e y: -(pi / 2) - { 2.71828183f, -1.44269504f, 0.236290088f, PAL_EPSILON }, // x: e y: -(logf2(e)) - { 2.71828183f, -1.41421356f, 0.243116734f, PAL_EPSILON }, // x: e y: -(sqrtf(2)) - { 2.71828183f, -1.12837917f, 0.323557264f, PAL_EPSILON }, // x: e y: -(2 / sqrtf(pi)) - { 2.71828183f, -1, 0.367879441f, PAL_EPSILON }, // x: e y: -(1) - { 2.71828183f, -0.785398163f, 0.455938128f, PAL_EPSILON }, // x: e y: -(pi / 4) - { 2.71828183f, -0.707106781f, 0.493068691f, PAL_EPSILON }, // x: e y: -(1 / sqrtf(2)) - { 2.71828183f, -0.693147181f, 0.5f, PAL_EPSILON }, // x: e y: -(ln(2)) - { 2.71828183f, -0.636619772f, 0.529077808f, PAL_EPSILON }, // x: e y: -(2 / pi) - { 2.71828183f, -0.434294482f, 0.647721485f, PAL_EPSILON }, // x: e y: -(log10f(e)) - { 2.71828183f, -0.318309886f, 0.727377349f, PAL_EPSILON }, // x: e y: -(1 / pi) - { 2.71828183f, 0, 1, PAL_EPSILON * 10 }, // x: e - { 2.71828183f, 0.318309886f, 1.37480223f, PAL_EPSILON * 10 }, // x: e y: 1 / pi - { 2.71828183f, 0.434294482f, 1.54387344f, PAL_EPSILON * 10 }, // x: e y: log10f(e) - { 2.71828183f, 0.636619772f, 1.89008116f, PAL_EPSILON * 10 }, // x: e y: 2 / pi - { 2.71828183f, 0.693147181f, 2, PAL_EPSILON * 10 }, // x: e y: ln(2) - { 2.71828183f, 0.707106781f, 2.02811498f, PAL_EPSILON * 10 }, // x: e y: 1 / sqrtf(2) - { 2.71828183f, 0.785398163f, 2.19328005f, PAL_EPSILON * 10 }, // x: e y: pi / 4 - { 2.71828183f, 1, 2.71828183f, PAL_EPSILON * 10 }, // x: e expected: e - { 2.71828183f, 1.12837917f, 3.09064302f, PAL_EPSILON * 10 }, // x: e y: 2 / sqrtf(pi) - { 2.71828183f, 1.41421356f, 4.11325038f, PAL_EPSILON * 10 }, // x: e y: sqrtf(2) - { 2.71828183f, 1.44269504f, 4.23208611f, PAL_EPSILON * 10 }, // x: e y: logf2(e) - { 2.71828183f, 1.57079633f, 4.81047738f, PAL_EPSILON * 10 }, // x: e y: pi / 2 - { 2.71828183f, 2.30258509f, 10, PAL_EPSILON * 100 }, // x: e y: ln(10) - { 2.71828183f, 2.71828183f, 15.1542622f, PAL_EPSILON * 100 }, // x: e y: e - { 2.71828183f, 3.14159265f, 23.1406926f, PAL_EPSILON * 100 }, // x: e y: pi - { 2.71828183f, PAL_POSINF, PAL_POSINF, 0 }, // x: e - - { 10, PAL_NEGINF, 0, 0 }, - { 10, -3.14159265f, 0.000721784159f, PAL_EPSILON / 1000 }, // y: -(pi) - { 10, -2.71828183f, 0.00191301410f, PAL_EPSILON / 100 }, // y: -(e) - { 10, -2.30258509f, 0.00498212830f, PAL_EPSILON / 100 }, // y: -(ln(10)) - { 10, -1.57079633f, 0.0268660410f, PAL_EPSILON / 10 }, // y: -(pi / 2) - { 10, -1.44269504f, 0.0360831928f, PAL_EPSILON / 10 }, // y: -(logf2(e)) - { 10, -1.41421356f, 0.0385288847f, PAL_EPSILON / 10 }, // y: -(sqrtf(2)) - { 10, -1.12837917f, 0.0744082059f, PAL_EPSILON / 10 }, // y: -(2 / sqrtf(pi)) - { 10, -1, 0.1f, PAL_EPSILON }, // y: -(1) - { 10, -0.785398163f, 0.163908636f, PAL_EPSILON }, // y: -(pi / 4) - { 10, -0.707106781f, 0.196287760f, PAL_EPSILON }, // y: -(1 / sqrtf(2)) - { 10, -0.693147181f, 0.202699566f, PAL_EPSILON }, // y: -(ln(2)) - { 10, -0.636619772f, 0.230876765f, PAL_EPSILON }, // y: -(2 / pi) - { 10, -0.434294482f, 0.367879441f, PAL_EPSILON }, // y: -(log10f(e)) - { 10, -0.318309886f, 0.480496373f, PAL_EPSILON }, // y: -(1 / pi) - { 10, 0, 1, PAL_EPSILON * 10 }, - { 10, 0.318309886f, 2.08118116f, PAL_EPSILON * 10 }, // y: 1 / pi - { 10, 0.434294482f, 2.71828183f, PAL_EPSILON * 10 }, // y: log10f(e) expected: e - { 10, 0.636619772f, 4.33131503f, PAL_EPSILON * 10 }, // y: 2 / pi - { 10, 0.693147181f, 4.93340967f, PAL_EPSILON * 10 }, // y: ln(2) - { 10, 0.707106781f, 5.09456117f, PAL_EPSILON * 10 }, // y: 1 / sqrtf(2) - { 10, 0.785398163f, 6.10095980f, PAL_EPSILON * 10 }, // y: pi / 4 - { 10, 1, 10, PAL_EPSILON * 100 }, - { 10, 1.12837917f, 13.4393779f, PAL_EPSILON * 100 }, // y: 2 / sqrtf(pi) - { 10, 1.41421356f, 25.9545535f, PAL_EPSILON * 100 }, // y: sqrtf(2) - { 10, 1.44269504f, 27.7137338f, PAL_EPSILON * 100 }, // y: logf2(e) - { 10, 1.57079633f, 37.2217105f, PAL_EPSILON * 100 }, // y: pi / 2 - { 10, 2.30258509f, 200.717432f, PAL_EPSILON * 1000 }, // y: ln(10) - { 10, 2.71828183f, 522.735300f, PAL_EPSILON * 1000 }, // y: e - { 10, 3.14159265f, 1385.45573f, PAL_EPSILON * 10000 }, // y: pi - { 10, PAL_POSINF, PAL_POSINF, 0 }, - - { PAL_POSINF, PAL_NEGINF, 0, PAL_EPSILON }, - { PAL_POSINF, PAL_POSINF, PAL_POSINF, 0 }, - }; - - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - powf_test1_validate(tests[i].x, tests[i].y, tests[i].expected, tests[i].variance); - } - - powf_test1_validate_isnan(-10, -1.57079633f); // y: -(pi / 2) - powf_test1_validate_isnan(-10, -0.785398163f); // y: -(pi / 4) - powf_test1_validate_isnan(-10, 0.785398163f); // y: pi / 4 - powf_test1_validate_isnan(-10, 1.57079633f); // y: pi / 2 - - powf_test1_validate_isnan(-2.71828183f, -1.57079633f); // x: -(e) y: -(pi / 2) - powf_test1_validate_isnan(-2.71828183f, -0.785398163f); // x: -(e) y: -(pi / 4) - powf_test1_validate_isnan(-2.71828183f, 0.785398163f); // x: -(e) y: pi / 4 - powf_test1_validate_isnan(-2.71828183f, 1.57079633f); // x: -(e) y: pi / 2 - - powf_test1_validate_isnan(PAL_NEGINF, PAL_NAN); - powf_test1_validate_isnan(PAL_NAN, PAL_NEGINF); - - powf_test1_validate_isnan(PAL_POSINF, PAL_NAN); - powf_test1_validate_isnan(PAL_NAN, PAL_POSINF); - - powf_test1_validate_isnan(PAL_NAN, PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/sin/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/sin/test1/test1.cpp deleted file mode 100644 index bcfeb4baa05158..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/sin/test1/test1.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that sin return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * sin_test1_validate - * - * test validation function - */ -void __cdecl sin_test1_validate(double value, double expected, double variance) -{ - double result = sin(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("sin(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * sin_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl sin_test1_validate_isnan(double value) -{ - double result = sin(value); - - if (!_isnan(result)) - { - Fail("sin(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_sin_test1_paltest_sin_test1, "c_runtime/sin/test1/paltest_sin_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.31830988618379067, 0.31296179620778659, PAL_EPSILON }, // value: 1 / pi - { 0.43429448190325183, 0.42077048331375735, PAL_EPSILON }, // value: log10(e) - { 0.63661977236758134, 0.59448076852482208, PAL_EPSILON }, // value: 2 / pi - { 0.69314718055994531, 0.63896127631363480, PAL_EPSILON }, // value: ln(2) - { 0.70710678118654752, 0.64963693908006244, PAL_EPSILON }, // value: 1 / sqrt(2) - { 0.78539816339744831, 0.70710678118654752, PAL_EPSILON }, // value: pi / 4, expected: 1 / sqrt(2) - { 1, 0.84147098480789651, PAL_EPSILON }, - { 1.1283791670955126, 0.90371945743584630, PAL_EPSILON }, // value: 2 / sqrt(pi) - { 1.4142135623730950, 0.98776594599273553, PAL_EPSILON }, // value: sqrt(2) - { 1.4426950408889634, 0.99180624439366372, PAL_EPSILON }, // value: log2(e) - { 1.5707963267948966, 1, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.3025850929940457, 0.74398033695749319, PAL_EPSILON }, // value: ln(10) - { 2.7182818284590452, 0.41078129050290870, PAL_EPSILON }, // value: e - { 3.1415926535897932, 0, PAL_EPSILON }, // value: pi - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - sin_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - sin_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - sin_test1_validate_isnan(PAL_NEGINF); - sin_test1_validate_isnan(PAL_NAN); - sin_test1_validate_isnan(PAL_POSINF); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/sinf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/sinf/test1/test1.cpp deleted file mode 100644 index 1481843fed4735..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/sinf/test1/test1.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that sinf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * sinf_test1_validate - * - * test validation function - */ -void __cdecl sinf_test1_validate(float value, float expected, float variance) -{ - float result = sinf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("sinf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * sinf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl sinf_test1_validate_isnan(float value) -{ - float result = sinf(value); - - if (!_isnanf(result)) - { - Fail("sinf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_sinf_test1_paltest_sinf_test1, "c_runtime/sinf/test1/paltest_sinf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.318309886f, 0.312961796f, PAL_EPSILON }, // value: 1 / pi - { 0.434294482f, 0.420770483f, PAL_EPSILON }, // value: log10f(e) - { 0.636619772f, 0.594480769f, PAL_EPSILON }, // value: 2 / pi - { 0.693147181f, 0.638961276f, PAL_EPSILON }, // value: ln(2) - { 0.707106781f, 0.649636939f, PAL_EPSILON }, // value: 1 / sqrtf(2) - { 0.785398163f, 0.707106781f, PAL_EPSILON }, // value: pi / 4, expected: 1 / sqrtf(2) - { 1, 0.841470985f, PAL_EPSILON }, - { 1.12837917f, 0.903719457f, PAL_EPSILON }, // value: 2 / sqrtf(pi) - { 1.41421356f, 0.987765946f, PAL_EPSILON }, // value: sqrtf(2) - { 1.44269504f, 0.991806244f, PAL_EPSILON }, // value: logf2(e) - { 1.57079633f, 1, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.30258509f, 0.743980337f, PAL_EPSILON }, // value: ln(10) - { 2.71828183f, 0.410781291f, PAL_EPSILON }, // value: e - { 3.14159265f, 0, PAL_EPSILON }, // value: pi - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - sinf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - sinf_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - sinf_test1_validate_isnan(PAL_NEGINF); - sinf_test1_validate_isnan(PAL_NAN); - sinf_test1_validate_isnan(PAL_POSINF); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/sinh/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/sinh/test1/test1.cpp deleted file mode 100644 index 2879bf16aea92e..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/sinh/test1/test1.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that sinh return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * sinh_test1_validate - * - * test validation function - */ -void __cdecl sinh_test1_validate(double value, double expected, double variance) -{ - double result = sinh(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("sinh(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * sinh_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl sinh_test1_validate_isnan(double value) -{ - double result = sinh(value); - - if (!_isnan(result)) - { - Fail("sinh(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_sinh_test1_paltest_sinh_test1, "c_runtime/sinh/test1/paltest_sinh_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.31830988618379067, 0.32371243907207108, PAL_EPSILON }, // value: 1 / pi - { 0.43429448190325183, 0.44807597941469025, PAL_EPSILON }, // value: log10(e) - { 0.63661977236758134, 0.68050167815224332, PAL_EPSILON }, // value: 2 / pi - { 0.69314718055994531, 0.75, PAL_EPSILON }, // value: ln(2) - { 0.70710678118654752, 0.76752314512611633, PAL_EPSILON }, // value: 1 / sqrt(2) - { 0.78539816339744831, 0.86867096148600961, PAL_EPSILON }, // value: pi / 4 - { 1, 1.1752011936438015, PAL_EPSILON * 10 }, - { 1.1283791670955126, 1.3835428792038633, PAL_EPSILON * 10 }, // value: 2 / sqrt(pi) - { 1.4142135623730950, 1.9350668221743567, PAL_EPSILON * 10 }, // value: sqrt(2) - { 1.4426950408889634, 1.9978980091062796, PAL_EPSILON * 10 }, // value: log2(e) - { 1.5707963267948966, 2.3012989023072949, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.3025850929940457, 4.95, PAL_EPSILON * 10 }, // value: ln(10) - { 2.7182818284590452, 7.5441371028169758, PAL_EPSILON * 10 }, // value: e - { 3.1415926535897932, 11.548739357257748, PAL_EPSILON * 100 }, // value: pi - { PAL_POSINF, PAL_POSINF, 0 }, - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - sinh_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - sinh_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - sinh_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/sinhf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/sinhf/test1/test1.cpp deleted file mode 100644 index a67ab96a4101e6..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/sinhf/test1/test1.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that sinhf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * sinhf_test1_validate - * - * test validation function - */ -void __cdecl sinhf_test1_validate(float value, float expected, float variance) -{ - float result = sinhf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("sinhf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * sinhf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl sinhf_test1_validate_isnan(float value) -{ - float result = sinhf(value); - - if (!_isnanf(result)) - { - Fail("sinhf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_sinhf_test1_paltest_sinhf_test1, "c_runtime/sinhf/test1/paltest_sinhf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.318309886f, 0.323712439f, PAL_EPSILON }, // value: 1 / pi - { 0.434294482f, 0.448075979f, PAL_EPSILON }, // value: log10f(e) - { 0.636619772f, 0.680501678f, PAL_EPSILON }, // value: 2 / pi - { 0.693147181f, 0.75, PAL_EPSILON }, // value: ln(2) - { 0.707106781f, 0.767523145f, PAL_EPSILON }, // value: 1 / sqrtf(2) - { 0.785398163f, 0.868670961f, PAL_EPSILON }, // value: pi / 4 - { 1, 1.17520119f, PAL_EPSILON * 10 }, - { 1.12837917f, 1.38354288f, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi) - { 1.41421356f, 1.93506682f, PAL_EPSILON * 10 }, // value: sqrtf(2) - { 1.44269504f, 1.99789801f, PAL_EPSILON * 10 }, // value: logf2(e) - { 1.57079633f, 2.30129890f, PAL_EPSILON * 10 }, // value: pi / 2 - { 2.30258509f, 4.95f, PAL_EPSILON * 10 }, // value: ln(10) - { 2.71828183f, 7.54413710f, PAL_EPSILON * 10 }, // value: e - { 3.14159265f, 11.5487394f, PAL_EPSILON * 100 }, // value: pi - { PAL_POSINF, PAL_POSINF, 0 }, - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - sinhf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - sinhf_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - sinhf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/tan/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/tan/test1/test1.cpp deleted file mode 100644 index 11f9123354ea24..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/tan/test1/test1.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that tan return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * tan_test1_validate - * - * test validation function - */ -void __cdecl tan_test1_validate(double value, double expected, double variance) -{ - double result = tan(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("tan(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * tan_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl tan_test1_validate_isnan(double value) -{ - double result = tan(value); - - if (!_isnan(result)) - { - Fail("tan(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_tan_test1_paltest_tan_test1, "c_runtime/tan/test1/paltest_tan_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.31830988618379067, 0.32951473309607836, PAL_EPSILON }, // value: 1 / pi - { 0.43429448190325183, 0.46382906716062964, PAL_EPSILON }, // value: log10(e) - { 0.63661977236758134, 0.73930295048660405, PAL_EPSILON }, // value: 2 / pi - { 0.69314718055994531, 0.83064087786078395, PAL_EPSILON }, // value: ln(2) - { 0.70710678118654752, 0.85451043200960189, PAL_EPSILON }, // value: 1 / sqrt(2) - { 0.78539816339744831, 1, PAL_EPSILON * 10 }, // value: pi / 4 - { 1, 1.5574077246549022, PAL_EPSILON * 10 }, - { 1.1283791670955126, 2.1108768356626451, PAL_EPSILON * 10 }, // value: 2 / sqrt(pi) - { 1.4142135623730950, 6.3341191670421916, PAL_EPSILON * 10 }, // value: sqrt(2) - { 1.4426950408889634, 7.7635756709721848, PAL_EPSILON * 10 }, // value: log2(e) - // SEE BELOW -- { 1.5707963267948966, PAL_POSINF, 0 }, // value: pi / 2 - { 2.3025850929940457, -1.1134071468135374, PAL_EPSILON * 10 }, // value: ln(10) - { 2.7182818284590452, -0.45054953406980750, PAL_EPSILON }, // value: e - { 3.1415926535897932, 0, PAL_EPSILON }, // value: pi - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - tan_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - tan_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - // -- SPECIAL CASE -- - // Normally, tan(pi / 2) would return PAL_POSINF (atan2(PAL_POSINF) does return (pi / 2)). - // However, it seems instead (on all supported systems), we get a different number entirely. - tan_test1_validate( 1.5707963267948966, 16331239353195370.0, 0); - tan_test1_validate(-1.5707963267948966, -16331239353195370.0, 0); - - tan_test1_validate_isnan(PAL_NEGINF); - tan_test1_validate_isnan(PAL_NAN); - tan_test1_validate_isnan(PAL_POSINF); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/tanf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/tanf/test1/test1.cpp deleted file mode 100644 index 2f7358cc2774dc..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/tanf/test1/test1.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that tanf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * tanf_test1_validate - * - * test validation function - */ -void __cdecl tanf_test1_validate(float value, float expected, float variance) -{ - float result = tanf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("tanf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * tanf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl tanf_test1_validate_isnan(float value) -{ - float result = tanf(value); - - if (!_isnanf(result)) - { - Fail("tanf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_tanf_test1_paltest_tanf_test1, "c_runtime/tanf/test1/paltest_tanf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.318309886f, 0.329514733f, PAL_EPSILON }, // value: 1 / pi - { 0.434294482f, 0.463829067f, PAL_EPSILON }, // value: log10f(e) - { 0.636619772f, 0.739302950f, PAL_EPSILON }, // value: 2 / pi - { 0.693147181f, 0.830640878f, PAL_EPSILON }, // value: ln(2) - { 0.707106781f, 0.854510432f, PAL_EPSILON }, // value: 1 / sqrtf(2) - { 0.785398163f, 1, PAL_EPSILON * 10 }, // value: pi / 4 - { 1, 1.55740772f, PAL_EPSILON * 10 }, - { 1.12837917f, 2.11087684f, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi) - { 1.41421356f, 6.33411917f, PAL_EPSILON * 10 }, // value: sqrtf(2) - { 1.44269504f, 7.76357567f, PAL_EPSILON * 10 }, // value: logf2(e) - // SEE BELOW -- { 1.57079633f, PAL_POSINF, 0 }, // value: pi / 2 - { 2.30258509f, -1.11340715f, PAL_EPSILON * 10 }, // value: ln(10) - { 2.71828183f, -0.450549534f, PAL_EPSILON }, // value: e - { 3.14159265f, 0, PAL_EPSILON }, // value: pi - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - tanf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - tanf_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - // -- SPECIAL CASE -- - // Normally, tanf(pi / 2) would return PAL_POSINF (atan2f(PAL_POSINF) does return (pi / 2)). - // However, it seems instead (on all supported systems), we get a different number entirely. - tanf_test1_validate( 1.57079633f, -22877332.0, PAL_EPSILON * 100000000); - tanf_test1_validate(-1.57079633f, 22877332.0, PAL_EPSILON * 100000000); - - tanf_test1_validate_isnan(PAL_NEGINF); - tanf_test1_validate_isnan(PAL_NAN); - tanf_test1_validate_isnan(PAL_POSINF); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/tanh/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/tanh/test1/test1.cpp deleted file mode 100644 index a2df3885803c04..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/tanh/test1/test1.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that tanh return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (15-17 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use -// PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx -// will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will -// use PAL_EPSILON * 10. -#define PAL_EPSILON 8.8817841970012523e-16 - -#define PAL_NAN sqrt(-1.0) -#define PAL_POSINF -log(0.0) -#define PAL_NEGINF log(0.0) - -/** - * Helper test structure - */ -struct test -{ - double value; /* value to test the function with */ - double expected; /* expected result */ - double variance; /* maximum delta between the expected and actual result */ -}; - -/** - * tanh_test1_validate - * - * test validation function - */ -void __cdecl tanh_test1_validate(double value, double expected, double variance) -{ - double result = tanh(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - double delta = fabs(result - expected); - - if (delta > variance) - { - Fail("tanh(%g) returned %20.17g when it should have returned %20.17g", - value, result, expected); - } -} - -/** - * tanh_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl tanh_test1_validate_isnan(double value) -{ - double result = tanh(value); - - if (!_isnan(result)) - { - Fail("tanh(%g) returned %20.17g when it should have returned %20.17g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_tanh_test1_paltest_tanh_test1, "c_runtime/tanh/test1/paltest_tanh_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.31830988618379067, 0.30797791269089433, PAL_EPSILON }, // value: 1 / pi - { 0.43429448190325183, 0.40890401183401433, PAL_EPSILON }, // value: log10(e) - { 0.63661977236758134, 0.56259360033158334, PAL_EPSILON }, // value: 2 / pi - { 0.69314718055994531, 0.6, PAL_EPSILON }, // value: ln(2) - { 0.70710678118654752, 0.60885936501391381, PAL_EPSILON }, // value: 1 / sqrt(2) - { 0.78539816339744831, 0.65579420263267244, PAL_EPSILON }, // value: pi / 4 - { 1, 0.76159415595576489, PAL_EPSILON }, - { 1.1283791670955126, 0.81046380599898809, PAL_EPSILON }, // value: 2 / sqrt(pi) - { 1.4142135623730950, 0.88838556158566054, PAL_EPSILON }, // value: sqrt(2) - { 1.4426950408889634, 0.89423894585503855, PAL_EPSILON }, // value: log2(e) - { 1.5707963267948966, 0.91715233566727435, PAL_EPSILON }, // value: pi / 2 - { 2.3025850929940457, 0.98019801980198020, PAL_EPSILON }, // value: ln(10) - { 2.7182818284590452, 0.99132891580059984, PAL_EPSILON }, // value: e - { 3.1415926535897932, 0.99627207622074994, PAL_EPSILON }, // value: pi - { PAL_POSINF, 1, PAL_EPSILON * 10 } - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - tanh_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - tanh_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - tanh_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/tanhf/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/tanhf/test1/test1.cpp deleted file mode 100644 index 646e743fa418bf..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/tanhf/test1/test1.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that tanhf return the correct values -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** fabs -** -**===========================================================================*/ - -#include - -// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this -// is slightly too accurate when writing tests meant to run against libm implementations -// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. -// -// The tests themselves will take PAL_EPSILON and adjust it according to the expected result -// so that the delta used for comparison will compare the most significant digits and ignore -// any digits that are outside the double precision range (6-9 digits). - -// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON -// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use -// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10. -#define PAL_EPSILON 4.76837158e-07 - -#define PAL_NAN sqrtf(-1.0f) -#define PAL_POSINF -logf(0.0f) -#define PAL_NEGINF logf(0.0f) - -/** - * Helper test structure - */ -struct test -{ - float value; /* value to test the function with */ - float expected; /* expected result */ - float variance; /* maximum delta between the expected and actual result */ -}; - -/** - * tanhf_test1_validate - * - * test validation function - */ -void __cdecl tanhf_test1_validate(float value, float expected, float variance) -{ - float result = tanhf(value); - - /* - * The test is valid when the difference between result - * and expected is less than or equal to variance - */ - float delta = fabsf(result - expected); - - if (delta > variance) - { - Fail("tanhf(%g) returned %10.9g when it should have returned %10.9g", - value, result, expected); - } -} - -/** - * tanhf_test1_validate - * - * test validation function for values returning NaN - */ -void __cdecl tanhf_test1_validate_isnan(float value) -{ - float result = tanhf(value); - - if (!_isnanf(result)) - { - Fail("tanhf(%g) returned %10.9g when it should have returned %10.9g", - value, result, PAL_NAN); - } -} - -/** - * main - * - * executable entry point - */ -PALTEST(c_runtime_tanhf_test1_paltest_tanhf_test1, "c_runtime/tanhf/test1/paltest_tanhf_test1") -{ - struct test tests[] = - { - /* value expected variance */ - { 0, 0, PAL_EPSILON }, - { 0.318309886f, 0.307977913f, PAL_EPSILON }, // value: 1 / pi - { 0.434294482f, 0.408904012f, PAL_EPSILON }, // value: log10f(e) - { 0.636619772f, 0.562593600f, PAL_EPSILON }, // value: 2 / pi - { 0.693147181f, 0.6f, PAL_EPSILON }, // value: ln(2) - { 0.707106781f, 0.608859365f, PAL_EPSILON }, // value: 1 / sqrtf(2) - { 0.785398163f, 0.655794203f, PAL_EPSILON }, // value: pi / 4 - { 1, 0.761594156f, PAL_EPSILON }, - { 1.12837917f, 0.810463806f, PAL_EPSILON }, // value: 2 / sqrtf(pi) - { 1.41421356f, 0.888385562f, PAL_EPSILON }, // value: sqrtf(2) - { 1.44269504f, 0.894238946f, PAL_EPSILON }, // value: logf2(e) - { 1.57079633f, 0.917152336f, PAL_EPSILON }, // value: pi / 2 - { 2.30258509f, 0.980198020f, PAL_EPSILON }, // value: ln(10) - { 2.71828183f, 0.991328916f, PAL_EPSILON }, // value: e - { 3.14159265f, 0.996272076f, PAL_EPSILON }, // value: pi - { PAL_POSINF, 1, PAL_EPSILON * 10 } - }; - - /* PAL initialization */ - if (PAL_Initialize(argc, argv) != 0) - { - return FAIL; - } - - for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) - { - tanhf_test1_validate( tests[i].value, tests[i].expected, tests[i].variance); - tanhf_test1_validate(-tests[i].value, -tests[i].expected, tests[i].variance); - } - - tanhf_test1_validate_isnan(PAL_NAN); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/compilableTests.txt b/src/coreclr/pal/tests/palsuite/compilableTests.txt index c674de294db452..18880bdea6a186 100644 --- a/src/coreclr/pal/tests/palsuite/compilableTests.txt +++ b/src/coreclr/pal/tests/palsuite/compilableTests.txt @@ -1,36 +1,14 @@ c_runtime/abs/test1/paltest_abs_test1 -c_runtime/acos/test1/paltest_acos_test1 -c_runtime/acosf/test1/paltest_acosf_test1 -c_runtime/acosh/test1/paltest_acosh_test1 -c_runtime/acoshf/test1/paltest_acoshf_test1 -c_runtime/asin/test1/paltest_asin_test1 -c_runtime/asinf/test1/paltest_asinf_test1 -c_runtime/asinh/test1/paltest_asinh_test1 -c_runtime/asinhf/test1/paltest_asinhf_test1 -c_runtime/atan/test1/paltest_atan_test1 -c_runtime/atan2/test1/paltest_atan2_test1 -c_runtime/atan2f/test1/paltest_atan2f_test1 -c_runtime/atanf/test1/paltest_atanf_test1 -c_runtime/atanh/test1/paltest_atanh_test1 -c_runtime/atanhf/test1/paltest_atanhf_test1 c_runtime/atof/test1/paltest_atof_test1 c_runtime/atoi/test1/paltest_atoi_test1 c_runtime/bsearch/test1/paltest_bsearch_test1 c_runtime/bsearch/test2/paltest_bsearch_test2 c_runtime/cbrt/test1/paltest_cbrt_test1 c_runtime/cbrtf/test1/paltest_cbrtf_test1 -c_runtime/ceil/test1/paltest_ceil_test1 -c_runtime/ceilf/test1/paltest_ceilf_test1 -c_runtime/cos/test1/paltest_cos_test1 -c_runtime/cosf/test1/paltest_cosf_test1 -c_runtime/cosh/test1/paltest_cosh_test1 -c_runtime/coshf/test1/paltest_coshf_test1 c_runtime/errno/test1/paltest_errno_test1 c_runtime/errno/test2/paltest_errno_test2 c_runtime/exit/test1/paltest_exit_test1 c_runtime/exit/test2/paltest_exit_test2 -c_runtime/exp/test1/paltest_exp_test1 -c_runtime/expf/test1/paltest_expf_test1 c_runtime/fabs/test1/paltest_fabs_test1 c_runtime/fabsf/test1/paltest_fabsf_test1 c_runtime/fclose/test1/paltest_fclose_test1 @@ -41,8 +19,6 @@ c_runtime/fflush/test1/paltest_fflush_test1 c_runtime/fgets/test1/paltest_fgets_test1 c_runtime/fgets/test2/paltest_fgets_test2 c_runtime/fgets/test3/paltest_fgets_test3 -c_runtime/floor/test1/paltest_floor_test1 -c_runtime/floorf/test1/paltest_floorf_test1 c_runtime/fma/test1/paltest_fma_test1 c_runtime/fmaf/test1/paltest_fmaf_test1 c_runtime/fmod/test1/paltest_fmod_test1 @@ -104,8 +80,6 @@ c_runtime/fwrite/test1/paltest_fwrite_test1 c_runtime/getenv/test1/paltest_getenv_test1 c_runtime/getenv/test2/paltest_getenv_test2 c_runtime/getenv/test3/paltest_getenv_test3 -c_runtime/ilogb/test1/paltest_ilogb_test1 -c_runtime/ilogbf/test1/paltest_ilogbf_test1 c_runtime/isalnum/test1/paltest_isalnum_test1 c_runtime/isalpha/test1/paltest_isalpha_test1 c_runtime/isdigit/test1/paltest_isdigit_test1 @@ -124,7 +98,6 @@ c_runtime/log10/test1/paltest_log10_test1 c_runtime/log10f/test1/paltest_log10f_test1 c_runtime/log2/test1/paltest_log2_test1 c_runtime/log2f/test1/paltest_log2f_test1 -c_runtime/logf/test1/paltest_logf_test1 c_runtime/malloc/test1/paltest_malloc_test1 c_runtime/malloc/test2/paltest_malloc_test2 c_runtime/memchr/test1/paltest_memchr_test1 @@ -132,10 +105,6 @@ c_runtime/memcmp/test1/paltest_memcmp_test1 c_runtime/memcpy/test1/paltest_memcpy_test1 c_runtime/memmove/test1/paltest_memmove_test1 c_runtime/memset/test1/paltest_memset_test1 -c_runtime/modf/test1/paltest_modf_test1 -c_runtime/modff/test1/paltest_modff_test1 -c_runtime/pow/test1/paltest_pow_test1 -c_runtime/powf/test1/paltest_powf_test1 c_runtime/printf/test1/paltest_printf_test1 c_runtime/printf/test10/paltest_printf_test10 c_runtime/printf/test11/paltest_printf_test11 @@ -159,12 +128,8 @@ c_runtime/qsort/test1/paltest_qsort_test1 c_runtime/qsort/test2/paltest_qsort_test2 c_runtime/rand_srand/test1/paltest_rand_srand_test1 c_runtime/realloc/test1/paltest_realloc_test1 -c_runtime/sin/test1/paltest_sin_test1 c_runtime/sincos/test1/paltest_sincos_test1 c_runtime/sincosf/test1/paltest_sincosf_test1 -c_runtime/sinf/test1/paltest_sinf_test1 -c_runtime/sinh/test1/paltest_sinh_test1 -c_runtime/sinhf/test1/paltest_sinhf_test1 c_runtime/sprintf_s/test1/paltest_sprintf_test1 c_runtime/sprintf_s/test10/paltest_sprintf_test10 c_runtime/sprintf_s/test11/paltest_sprintf_test11 @@ -254,10 +219,6 @@ c_runtime/swscanf/test6/paltest_swscanf_test6 c_runtime/swscanf/test7/paltest_swscanf_test7 c_runtime/swscanf/test8/paltest_swscanf_test8 c_runtime/swscanf/test9/paltest_swscanf_test9 -c_runtime/tan/test1/paltest_tan_test1 -c_runtime/tanf/test1/paltest_tanf_test1 -c_runtime/tanh/test1/paltest_tanh_test1 -c_runtime/tanhf/test1/paltest_tanhf_test1 c_runtime/time/test1/paltest_time_test1 c_runtime/tolower/test1/paltest_tolower_test1 c_runtime/toupper/test1/paltest_toupper_test1 diff --git a/src/coreclr/pal/tests/palsuite/paltestlist.txt b/src/coreclr/pal/tests/palsuite/paltestlist.txt index 2b9ac7ccd4eb1e..fafa3672ca14f1 100644 --- a/src/coreclr/pal/tests/palsuite/paltestlist.txt +++ b/src/coreclr/pal/tests/palsuite/paltestlist.txt @@ -1,35 +1,13 @@ c_runtime/abs/test1/paltest_abs_test1 -c_runtime/acos/test1/paltest_acos_test1 -c_runtime/acosf/test1/paltest_acosf_test1 -c_runtime/acosh/test1/paltest_acosh_test1 -c_runtime/acoshf/test1/paltest_acoshf_test1 -c_runtime/asin/test1/paltest_asin_test1 -c_runtime/asinf/test1/paltest_asinf_test1 -c_runtime/asinh/test1/paltest_asinh_test1 -c_runtime/asinhf/test1/paltest_asinhf_test1 -c_runtime/atan/test1/paltest_atan_test1 -c_runtime/atan2/test1/paltest_atan2_test1 -c_runtime/atan2f/test1/paltest_atan2f_test1 -c_runtime/atanf/test1/paltest_atanf_test1 -c_runtime/atanh/test1/paltest_atanh_test1 -c_runtime/atanhf/test1/paltest_atanhf_test1 c_runtime/atof/test1/paltest_atof_test1 c_runtime/atoi/test1/paltest_atoi_test1 c_runtime/bsearch/test1/paltest_bsearch_test1 c_runtime/bsearch/test2/paltest_bsearch_test2 c_runtime/cbrt/test1/paltest_cbrt_test1 c_runtime/cbrtf/test1/paltest_cbrtf_test1 -c_runtime/ceil/test1/paltest_ceil_test1 -c_runtime/ceilf/test1/paltest_ceilf_test1 -c_runtime/cos/test1/paltest_cos_test1 -c_runtime/cosf/test1/paltest_cosf_test1 -c_runtime/cosh/test1/paltest_cosh_test1 -c_runtime/coshf/test1/paltest_coshf_test1 c_runtime/errno/test1/paltest_errno_test1 c_runtime/errno/test2/paltest_errno_test2 c_runtime/exit/test1/paltest_exit_test1 -c_runtime/exp/test1/paltest_exp_test1 -c_runtime/expf/test1/paltest_expf_test1 c_runtime/fabs/test1/paltest_fabs_test1 c_runtime/fabsf/test1/paltest_fabsf_test1 c_runtime/fclose/test1/paltest_fclose_test1 @@ -38,8 +16,6 @@ c_runtime/fflush/test1/paltest_fflush_test1 c_runtime/fgets/test1/paltest_fgets_test1 c_runtime/fgets/test2/paltest_fgets_test2 c_runtime/fgets/test3/paltest_fgets_test3 -c_runtime/floor/test1/paltest_floor_test1 -c_runtime/floorf/test1/paltest_floorf_test1 c_runtime/fma/test1/paltest_fma_test1 c_runtime/fmaf/test1/paltest_fmaf_test1 c_runtime/fmod/test1/paltest_fmod_test1 @@ -93,8 +69,6 @@ c_runtime/fwrite/test1/paltest_fwrite_test1 c_runtime/getenv/test1/paltest_getenv_test1 c_runtime/getenv/test2/paltest_getenv_test2 c_runtime/getenv/test3/paltest_getenv_test3 -c_runtime/ilogb/test1/paltest_ilogb_test1 -c_runtime/ilogbf/test1/paltest_ilogbf_test1 c_runtime/isalnum/test1/paltest_isalnum_test1 c_runtime/isalpha/test1/paltest_isalpha_test1 c_runtime/isdigit/test1/paltest_isdigit_test1 @@ -113,7 +87,6 @@ c_runtime/log2/test1/paltest_log2_test1 c_runtime/log2f/test1/paltest_log2f_test1 c_runtime/log10/test1/paltest_log10_test1 c_runtime/log10f/test1/paltest_log10f_test1 -c_runtime/logf/test1/paltest_logf_test1 c_runtime/malloc/test1/paltest_malloc_test1 c_runtime/malloc/test2/paltest_malloc_test2 c_runtime/memchr/test1/paltest_memchr_test1 @@ -121,10 +94,6 @@ c_runtime/memcmp/test1/paltest_memcmp_test1 c_runtime/memcpy/test1/paltest_memcpy_test1 c_runtime/memmove/test1/paltest_memmove_test1 c_runtime/memset/test1/paltest_memset_test1 -c_runtime/modf/test1/paltest_modf_test1 -c_runtime/modff/test1/paltest_modff_test1 -c_runtime/pow/test1/paltest_pow_test1 -c_runtime/powf/test1/paltest_powf_test1 c_runtime/printf/test1/paltest_printf_test1 c_runtime/printf/test10/paltest_printf_test10 c_runtime/printf/test11/paltest_printf_test11 @@ -148,12 +117,8 @@ c_runtime/qsort/test1/paltest_qsort_test1 c_runtime/qsort/test2/paltest_qsort_test2 c_runtime/rand_srand/test1/paltest_rand_srand_test1 c_runtime/realloc/test1/paltest_realloc_test1 -c_runtime/sin/test1/paltest_sin_test1 c_runtime/sincos/test1/paltest_sincos_test1 c_runtime/sincosf/test1/paltest_sincosf_test1 -c_runtime/sinf/test1/paltest_sinf_test1 -c_runtime/sinh/test1/paltest_sinh_test1 -c_runtime/sinhf/test1/paltest_sinhf_test1 c_runtime/sprintf_s/test1/paltest_sprintf_test1 c_runtime/sprintf_s/test10/paltest_sprintf_test10 c_runtime/sprintf_s/test11/paltest_sprintf_test11 @@ -241,10 +206,6 @@ c_runtime/swscanf/test6/paltest_swscanf_test6 c_runtime/swscanf/test7/paltest_swscanf_test7 c_runtime/swscanf/test8/paltest_swscanf_test8 c_runtime/swscanf/test9/paltest_swscanf_test9 -c_runtime/tan/test1/paltest_tan_test1 -c_runtime/tanf/test1/paltest_tanf_test1 -c_runtime/tanh/test1/paltest_tanh_test1 -c_runtime/tanhf/test1/paltest_tanhf_test1 c_runtime/time/test1/paltest_time_test1 c_runtime/tolower/test1/paltest_tolower_test1 c_runtime/toupper/test1/paltest_toupper_test1 diff --git a/src/native/clrmath/CMakeLists.txt b/src/native/clrmath/CMakeLists.txt index 521eb2c3b179fc..7c6149d8a0f079 100644 --- a/src/native/clrmath/CMakeLists.txt +++ b/src/native/clrmath/CMakeLists.txt @@ -6,3 +6,74 @@ set(SHARED_CLRMATH_SOURCE_DIR ${SHARED_CLRMATH_BASE_DIR}/src) set(SHARED_CLRMATH_SOURCES "") include_directories("${SHARED_CLRMATH_INCLUDE_DIR}") + +list(APPEND SHARED_CLRMATH_SOURCES + ${SHARED_CLRMATH_SOURCE_DIR}/libm_special.cpp + + # ${SHARED_CLRMATH_SOURCE_DIR}/opt/cos.cpp + # ${SHARED_CLRMATH_SOURCE_DIR}/opt/cosf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/opt/coshf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/opt/exp.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/opt/expf.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/opt/exp_tables.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/opt/logf.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/opt/log_tables.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/opt/pow.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/opt/powf.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/opt/pow_data.cpp + + # ${SHARED_CLRMATH_SOURCE_DIR}/opt/sin.cpp + # ${SHARED_CLRMATH_SOURCE_DIR}/opt/sinf.cpp + + # ${SHARED_CLRMATH_SOURCE_DIR}/opt/tan.cpp + # ${SHARED_CLRMATH_SOURCE_DIR}/opt/tanf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/opt/tanhf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/opt/data/_exp_j_by_64.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/opt/data/_log_data.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/acos.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/acosf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/acosh.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/acoshf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/asin.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/asinf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/asinh.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/asinhf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/atan.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/atanf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/atanh.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/atanhf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/atan2.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/atan2f.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/ceil.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/ceilf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/cosh.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/floor.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/floorf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/ilogb.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/ilogbf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/modf.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/modff.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/sinh.cpp + ${SHARED_CLRMATH_SOURCE_DIR}/ref/sinhf.cpp + + ${SHARED_CLRMATH_SOURCE_DIR}/ref/tanh.cpp +) diff --git a/src/native/clrmath/inc/clrmath.h b/src/native/clrmath/inc/clrmath.h index 07a3aca8ad0ade..0e80ec265513c3 100644 --- a/src/native/clrmath/inc/clrmath.h +++ b/src/native/clrmath/inc/clrmath.h @@ -4,6 +4,10 @@ #ifndef _CLRMATH_H_ #define _CLRMATH_H_ +#include +#include +#include + #ifdef __cplusplus extern "C" { #endif @@ -23,17 +27,17 @@ extern "C" { /* 7.12.4 Trigonometric functions */ /**********************************/ - #define clrmath_acos acos - #define clrmath_acosf acosf + extern double clrmath_acos (double x); + extern float clrmath_acosf(float x); - #define clrmath_asin asin - #define clrmath_asinf asinf + extern double clrmath_asin (double x); + extern float clrmath_asinf(float x); - #define clrmath_atan atan - #define clrmath_atanf atanf + extern double clrmath_atan (double x); + extern float clrmath_atanf(float x); - #define clrmath_atan2 atan2 - #define clrmath_atan2f atan2f + extern double clrmath_atan2 (double y, double x); + extern float clrmath_atan2f(float y, float x); #define clrmath_cos cos #define clrmath_cosf cosf @@ -44,34 +48,43 @@ extern "C" { #define clrmath_tan tan #define clrmath_tanf tanf + // extern double clrmath_cos (double x); + // extern float clrmath_cosf(float x); + + // extern double clrmath_sin (double x); + // extern float clrmath_sinf(float x); + + // extern double clrmath_tan (double x); + // extern float clrmath_tanf(float x); + /*******************************/ /* 7.12.5 Hyperbolic functions */ /*******************************/ - #define clrmath_acosh acosh - #define clrmath_acoshf acoshf + extern double clrmath_acosh (double x); + extern float clrmath_acoshf(float x); - #define clrmath_asinh asinh - #define clrmath_asinhf asinhf + extern double clrmath_asinh (double x); + extern float clrmath_asinhf(float x); - #define clrmath_atanh atan - #define clrmath_atanhf atanhf + extern double clrmath_atanh (double x); + extern float clrmath_atanhf(float x); - #define clrmath_cosh cosh - #define clrmath_coshf coshf + extern double clrmath_cosh (double x); + extern float clrmath_coshf(float x); - #define clrmath_sinh sinh - #define clrmath_sinhf sinhf + extern double clrmath_sinh (double x); + extern float clrmath_sinhf(float x); - #define clrmath_tanh tanh - #define clrmath_tanhf tanhf + extern double clrmath_tanh (double x); + extern float clrmath_tanhf(float x); /************************************************/ /* 7.12.6 Exponential and logarithmic functions */ /************************************************/ - #define clrmath_exp exp - #define clrmath_expf expf + extern double clrmath_exp (double x); + extern float clrmath_expf(float x); #define clrmath_exp2 exp2 #define clrmath_exp2f exp2f @@ -82,14 +95,14 @@ extern "C" { #define clrmath_frexp frexp #define clrmath_frexpf frexpf - #define clrmath_ilogb ilogb - #define clrmath_ilogbf ilogbf + extern int clrmath_ilogb (double x); + extern int clrmath_ilogbf(float x); #define clrmath_ldexp ldexp #define clrmath_ldexpf ldexpf #define clrmath_log log - #define clrmath_logf logf + extern float clrmath_logf(float x); #define clrmath_log10 log10 #define clrmath_log10f log10f @@ -106,8 +119,8 @@ extern "C" { #define clrmath_logb logb #define clrmath_logbf logbf - #define clrmath_modf modf - #define clrmath_modff modff + extern double clrmath_modf (double x, double* iptr); + extern float clrmath_modff(float x, float* iptr); #define clrmath_scalbn scalbn #define clrmath_scalbnf scalbnf @@ -128,8 +141,8 @@ extern "C" { #define clrmath_hypot hypot #define clrmath_hypotf hypot - #define clrmath_pow pow - #define clrmath_powf powf + extern double clrmath_pow (double x, double y); + extern float clrmath_powf(float x, float y); #define clrmath_sqrt sqrt #define clrmath_sqrtf sqrtf @@ -154,11 +167,11 @@ extern "C" { /* 7.12.9 Nearest integer functions */ /************************************/ - #define clrmath_ceil ceil - #define clrmath_ceilf ceilf + extern double clrmath_ceil (double x); + extern float clrmath_ceilf(float x); - #define clrmath_floor floor - #define clrmath_floorf floorf + extern double clrmath_floor (double x); + extern float clrmath_floorf(float x); #define clrmath_nearbyint nearbyint #define clrmath_nearbyintf nearbyintf @@ -201,8 +214,8 @@ extern "C" { /* 7.12.11 Manipulation functions */ /**********************************/ - #define clrmath_copysign copysign - #define clrmath_copysignf copysignf + #define clrmath_copysign _copysign + #define clrmath_copysignf _copysignf #define clrmath_nan nan #define clrmath_nanf nanf diff --git a/src/native/clrmath/inc/libm/libm_constants.h b/src/native/clrmath/inc/libm/libm_constants.h new file mode 100644 index 00000000000000..41c8d867bd3f85 --- /dev/null +++ b/src/native/clrmath/inc/libm/libm_constants.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2018-2020, Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __LIBM_CONSTANTS_H__ +#define __LIBM_CONSTANTS_H__ + + /* + * Double precision - alias bin64,flt64 + */ + +#define ALM_F64_SIGN_SIZE 1 +#define ALM_F64_SIGN_SHIFT 63 +#define ALM_F64_SIGN_MASK (1ULL << ALM_F64_SIGN_SHIFT) + +#define ALM_F64_EXPO_SIZE 11 +#define ALM_F64_EXPO_SHIFT 52 +#define ALM_F64_EXPO_MASK (((1ULL << ALM_F64_EXPO_SIZE) - 1) << ALM_F64_EXPO_SHIFT) + +#define ALM_F64_MANT_SIZE (52) +#define ALM_F64_MANT_SHIFT 0 +#define ALM_F64_MANT_MASK (((1ULL << ALM_F64_MANT_SIZE) - 1) << ALM_F64_MANT_SHFIT) + +#define ALM_F64_EXP_MIN -1022 +#define ALM_F64_EXP_MAX 1023 +#define ALM_F64_EXP_BIASMAX 2046 +#define ALM_F64_EXP_BIASMIN 1 + +#define ALM_F64_INF 0x7FF0000000000000ULL +#define ALM_F64_NINF 0xFFF0000000000000ULL +#define ALM_F64_NAN 0x7FF8000000000000ULL + +#define ALM_F64_MIN 0x1.0000000000000p-1022 +#define ALM_F64_MAX 0x1.fffffffffffffp+1023 + + + /* + * Single precision - alias bin32,flt32 + */ + +#define ALM_F32_SIGN_SIZE 1 +#define ALM_F32_SIGN_SHIFT 31 +#define ALM_F32_SIGN_MASK (1ULL << ALM_F32_SIGN_SHIFT) + +#define ALM_F32_EXPO_SIZE 8 +#define ALM_F32_EXPO_SHIFT 23 +#define ALM_F32_EXPO_MASK (((1ULL << ALM_F32_EXPO_SIZE) - 1) << ALM_F32_EXPO_SHIFT) + +#define ALM_F32_MANT_SIZE 23 +#define ALM_F32_MANT_SHIFT 0 +#define ALM_F32_MANT_MASK (((1ULL << ALM_F32_MANT_SIZE) - 1) << ALM_F32_MANT_SHFIT) + + +#define ALM_F32_EXP_MIN -128 +#define ALM_F32_EXP_MAX 127 +#define ALM_F32_EXP_BIASMAX 256 +#define ALM_F32_EXP_BIASMIN 1 + +#define ALM_F32_INF 0x7FF00000 +#define ALM_F32_INF_MASK 0x7F800000 +#define ALM_F32_NINF 0xFFF00000 +#define ALM_F32_NAN 0x7FF80000 + +#define ALM_F32_MIN 0x1.0p-126f +#define ALM_F32_MAX 0x1.fffffep127f + + +#endif /* LIBM_CONSTANTS_H */ diff --git a/src/native/clrmath/inc/libm/libm_inlines.h b/src/native/clrmath/inc/libm/libm_inlines.h new file mode 100644 index 00000000000000..56556077be4d3c --- /dev/null +++ b/src/native/clrmath/inc/libm/libm_inlines.h @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef _LIBM_INLINES_H_ +#define _LIBM_INLINES_H_ + +#include "libm/libm_inlines_amd.h" + +#endif // _LIBM_INLINES_H_ diff --git a/src/native/clrmath/inc/libm/libm_inlines_amd.h b/src/native/clrmath/inc/libm/libm_inlines_amd.h new file mode 100644 index 00000000000000..dad54fea93e66b --- /dev/null +++ b/src/native/clrmath/inc/libm/libm_inlines_amd.h @@ -0,0 +1,743 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef LIBM_INLINES_AMD_H_INCLUDED +#define LIBM_INLINES_AMD_H_INCLUDED 1 + + /* Scales the double x by 2.0**n. + Assumes EMIN <= n <= EMAX, though this condition is not checked. */ +static inline double scaleDouble_1(double x, int n) +{ + double t; + /* Construct the number t = 2.0**n */ + PUT_BITS_DP64(((long long)n + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t); + return x * t; +} + + +/* Scales the double x by 2.0**n. + Assumes 2*EMIN <= n <= 2*EMAX, though this condition is not checked. */ +static inline double scaleDouble_2(double x, int n) +{ + double t1, t2; + int n1, n2; + n1 = n / 2; + n2 = n - n1; + /* Construct the numbers t1 = 2.0**n1 and t2 = 2.0**n2 */ + PUT_BITS_DP64(((long long)n1 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t1); + PUT_BITS_DP64(((long long)n2 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t2); + return (x * t1) * t2; +} + + + + +/* Scales the double x by 2.0**n. + Assumes 3*EMIN <= n <= 3*EMAX, though this condition is not checked. */ +static inline double scaleDouble_3(double x, int n) +{ + double t1, t2, t3; + int n1, n2, n3; + n1 = n / 3; + n2 = (n - n1) / 2; + n3 = n - n1 - n2; + /* Construct the numbers t1 = 2.0**n1, t2 = 2.0**n2 and t3 = 2.0**n3 */ + PUT_BITS_DP64(((long long)n1 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t1); + PUT_BITS_DP64(((long long)n2 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t2); + PUT_BITS_DP64(((long long)n3 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t3); + return ((x * t1) * t2) * t3; +} + + +/* Scales the float x by 2.0**n. + Assumes 2*EMIN <= n <= 2*EMAX, though this condition is not checked. */ +static inline float scaleFloat_2(float x, int n) +{ + float t1, t2; + int n1, n2; + n1 = n / 2; + n2 = n - n1; + /* Construct the numbers t1 = 2.0**n1 and t2 = 2.0**n2 */ + PUT_BITS_SP32((n1 + EXPBIAS_SP32) << EXPSHIFTBITS_SP32, t1); + PUT_BITS_SP32((n2 + EXPBIAS_SP32) << EXPSHIFTBITS_SP32, t2); + return (x * t1) * t2; +} + + + +/* Compute the values m, z1, and z2 such that base**x = 2**m * (z1 + z2). + Small arguments abs(x) < 1/(16*ln(base)) and extreme arguments + abs(x) > large/(ln(base)) (where large is the largest representable + floating point number) should be handled separately instead of calling + this function. This function is called by exp_amd, exp2_amd, exp10_amd, + cosh_amd and sinh_amd. */ +static inline void splitexp(double x, double logbase, + double thirtytwo_by_logbaseof2, + double logbaseof2_by_32_lead, + double logbaseof2_by_32_trail, + int* m, double* z1, double* z2) +{ + double q, r, r1, r2, f1, f2; + int n, j; + + /* Arrays two_to_jby32_lead_table and two_to_jby32_trail_table contain + leading and trailing parts respectively of precomputed + values of pow(2.0,j/32.0), for j = 0, 1, ..., 31. + two_to_jby32_lead_table contains the first 25 bits of precision, + and two_to_jby32_trail_table contains a further 53 bits precision. */ + + static const double two_to_jby32_lead_table[32] = { + 1.00000000000000000000e+00, /* 0x3ff0000000000000 */ + 1.02189713716506958008e+00, /* 0x3ff059b0d0000000 */ + 1.04427373409271240234e+00, /* 0x3ff0b55860000000 */ + 1.06714040040969848633e+00, /* 0x3ff11301d0000000 */ + 1.09050768613815307617e+00, /* 0x3ff172b830000000 */ + 1.11438673734664916992e+00, /* 0x3ff1d48730000000 */ + 1.13878858089447021484e+00, /* 0x3ff2387a60000000 */ + 1.16372483968734741211e+00, /* 0x3ff29e9df0000000 */ + 1.18920707702636718750e+00, /* 0x3ff306fe00000000 */ + 1.21524733304977416992e+00, /* 0x3ff371a730000000 */ + 1.24185776710510253906e+00, /* 0x3ff3dea640000000 */ + 1.26905095577239990234e+00, /* 0x3ff44e0860000000 */ + 1.29683953523635864258e+00, /* 0x3ff4bfdad0000000 */ + 1.32523661851882934570e+00, /* 0x3ff5342b50000000 */ + 1.35425549745559692383e+00, /* 0x3ff5ab07d0000000 */ + 1.38390988111495971680e+00, /* 0x3ff6247eb0000000 */ + 1.41421353816986083984e+00, /* 0x3ff6a09e60000000 */ + 1.44518077373504638672e+00, /* 0x3ff71f75e0000000 */ + 1.47682613134384155273e+00, /* 0x3ff7a11470000000 */ + 1.50916439294815063477e+00, /* 0x3ff8258990000000 */ + 1.54221081733703613281e+00, /* 0x3ff8ace540000000 */ + 1.57598084211349487305e+00, /* 0x3ff93737b0000000 */ + 1.61049032211303710938e+00, /* 0x3ff9c49180000000 */ + 1.64575546979904174805e+00, /* 0x3ffa5503b0000000 */ + 1.68179279565811157227e+00, /* 0x3ffae89f90000000 */ + 1.71861928701400756836e+00, /* 0x3ffb7f76f0000000 */ + 1.75625211000442504883e+00, /* 0x3ffc199bd0000000 */ + 1.79470902681350708008e+00, /* 0x3ffcb720d0000000 */ + 1.83400803804397583008e+00, /* 0x3ffd5818d0000000 */ + 1.87416762113571166992e+00, /* 0x3ffdfc9730000000 */ + 1.91520655155181884766e+00, /* 0x3ffea4afa0000000 */ + 1.95714408159255981445e+00 }; /* 0x3fff507650000000 */ + + static const double two_to_jby32_trail_table[32] = { + 0.00000000000000000000e+00, /* 0x0000000000000000 */ + 1.14890470981563546737e-08, /* 0x3e48ac2ba1d73e2a */ + 4.83347014379782142328e-08, /* 0x3e69f3121ec53172 */ + 2.67125131841396124714e-10, /* 0x3df25b50a4ebbf1b */ + 4.65271045830351350190e-08, /* 0x3e68faa2f5b9bef9 */ + 5.24924336638693782574e-09, /* 0x3e368b9aa7805b80 */ + 5.38622214388600821910e-08, /* 0x3e6ceac470cd83f6 */ + 1.90902301017041969782e-08, /* 0x3e547f7b84b09745 */ + 3.79763538792174980894e-08, /* 0x3e64636e2a5bd1ab */ + 2.69306947081946450986e-08, /* 0x3e5ceaa72a9c5154 */ + 4.49683815095311756138e-08, /* 0x3e682468446b6824 */ + 1.41933332021066904914e-09, /* 0x3e18624b40c4dbd0 */ + 1.94146510233556266402e-08, /* 0x3e54d8a89c750e5e */ + 2.46409119489264118569e-08, /* 0x3e5a753e077c2a0f */ + 4.94812958044698886494e-08, /* 0x3e6a90a852b19260 */ + 8.48872238075784476136e-10, /* 0x3e0d2ac258f87d03 */ + 2.42032342089579394887e-08, /* 0x3e59fcef32422cbf */ + 3.32420002333182569170e-08, /* 0x3e61d8bee7ba46e2 */ + 1.45956577586525322754e-08, /* 0x3e4f580c36bea881 */ + 3.46452721050003920866e-08, /* 0x3e62999c25159f11 */ + 8.07090469079979051284e-09, /* 0x3e415506dadd3e2a */ + 2.99439161340839520436e-09, /* 0x3e29b8bc9e8a0388 */ + 9.83621719880452147153e-09, /* 0x3e451f8480e3e236 */ + 8.35492309647188080486e-09, /* 0x3e41f12ae45a1224 */ + 3.48493175137966283582e-08, /* 0x3e62b5a75abd0e6a */ + 1.11084703472699692902e-08, /* 0x3e47daf237553d84 */ + 5.03688744342840346564e-08, /* 0x3e6b0aa538444196 */ + 4.81896001063495806249e-08, /* 0x3e69df20d22a0798 */ + 4.83653666334089557746e-08, /* 0x3e69f7490e4bb40b */ + 1.29745882314081237628e-08, /* 0x3e4bdcdaf5cb4656 */ + 9.84532844621636118964e-09, /* 0x3e452486cc2c7b9d */ + 4.25828404545651943883e-08 }; /* 0x3e66dc8a80ce9f09 */ + + /* + Step 1. Reduce the argument. + + To perform argument reduction, we find the integer n such that + x = n * logbaseof2/32 + remainder, |remainder| <= logbaseof2/64. + n is defined by round-to-nearest-integer( x*32/logbaseof2 ) and + remainder by x - n*logbaseof2/32. The calculation of n is + straightforward whereas the computation of x - n*logbaseof2/32 + must be carried out carefully. + logbaseof2/32 is so represented in two pieces that + (1) logbaseof2/32 is known to extra precision, (2) the product + of n and the leading piece is a model number and is hence + calculated without error, and (3) the subtraction of the value + obtained in (2) from x is a model number and is hence again + obtained without error. + */ + + r = x * thirtytwo_by_logbaseof2; + /* Set n = nearest integer to r */ + /* This is faster on Hammer */ + if (r > 0) + n = (int)(r + 0.5); + else + n = (int)(r - 0.5); + + r1 = x - n * logbaseof2_by_32_lead; + r2 = -n * logbaseof2_by_32_trail; + + /* Set j = n mod 32: 5 mod 32 = 5, -5 mod 32 = 27, etc. */ + /* j = n % 32; + if (j < 0) j += 32; */ + j = n & 0x0000001f; + + f1 = two_to_jby32_lead_table[j]; + f2 = two_to_jby32_trail_table[j]; + + *m = (n - j) / 32; + + /* Step 2. The following is the core approximation. We approximate + exp(r1+r2)-1 by a polynomial. */ + + r1 *= logbase; r2 *= logbase; + + r = r1 + r2; + q = r1 + (r2 + + r * r * (5.00000000000000008883e-01 + + r * (1.66666666665260878863e-01 + + r * (4.16666666662260795726e-02 + + r * (8.33336798434219616221e-03 + + r * (1.38889490863777199667e-03)))))); + + /* Step 3. Function value reconstruction. + We now reconstruct the exponential of the input argument + so that exp(x) = 2**m * (z1 + z2). + The order of the computation below must be strictly observed. */ + + *z1 = f1; + *z2 = f2 + ((f1 + f2) * q); +} + + + + +/* Compute the values m, z1, and z2 such that base**x = 2**m * (z1 + z2). + Small arguments abs(x) < 1/(16*ln(base)) and extreme arguments + abs(x) > large/(ln(base)) (where large is the largest representable + floating point number) should be handled separately instead of calling + this function. This function is called by exp_amd, exp2_amd, exp10_amd, + cosh_amd and sinh_amd. */ +static inline void splitexpf(float x, float logbase, + float thirtytwo_by_logbaseof2, + float logbaseof2_by_32_lead, + float logbaseof2_by_32_trail, + int* m, float* z1, float* z2) +{ + float q, r, r1, r2, f1, f2; + int n, j; + + /* Arrays two_to_jby32_lead_table and two_to_jby32_trail_table contain + leading and trailing parts respectively of precomputed + values of pow(2.0,j/32.0), for j = 0, 1, ..., 31. + two_to_jby32_lead_table contains the first 10 bits of precision, + and two_to_jby32_trail_table contains a further 24 bits precision. */ + + static const float two_to_jby32_lead_table[32] = { + 1.0000000000E+00F, /* 0x3F800000 */ + 1.0214843750E+00F, /* 0x3F82C000 */ + 1.0429687500E+00F, /* 0x3F858000 */ + 1.0664062500E+00F, /* 0x3F888000 */ + 1.0898437500E+00F, /* 0x3F8B8000 */ + 1.1132812500E+00F, /* 0x3F8E8000 */ + 1.1386718750E+00F, /* 0x3F91C000 */ + 1.1621093750E+00F, /* 0x3F94C000 */ + 1.1875000000E+00F, /* 0x3F980000 */ + 1.2148437500E+00F, /* 0x3F9B8000 */ + 1.2402343750E+00F, /* 0x3F9EC000 */ + 1.2675781250E+00F, /* 0x3FA24000 */ + 1.2949218750E+00F, /* 0x3FA5C000 */ + 1.3242187500E+00F, /* 0x3FA98000 */ + 1.3535156250E+00F, /* 0x3FAD4000 */ + 1.3828125000E+00F, /* 0x3FB10000 */ + 1.4140625000E+00F, /* 0x3FB50000 */ + 1.4433593750E+00F, /* 0x3FB8C000 */ + 1.4765625000E+00F, /* 0x3FBD0000 */ + 1.5078125000E+00F, /* 0x3FC10000 */ + 1.5410156250E+00F, /* 0x3FC54000 */ + 1.5742187500E+00F, /* 0x3FC98000 */ + 1.6093750000E+00F, /* 0x3FCE0000 */ + 1.6445312500E+00F, /* 0x3FD28000 */ + 1.6816406250E+00F, /* 0x3FD74000 */ + 1.7167968750E+00F, /* 0x3FDBC000 */ + 1.7558593750E+00F, /* 0x3FE0C000 */ + 1.7929687500E+00F, /* 0x3FE58000 */ + 1.8339843750E+00F, /* 0x3FEAC000 */ + 1.8730468750E+00F, /* 0x3FEFC000 */ + 1.9140625000E+00F, /* 0x3FF50000 */ + 1.9570312500E+00F }; /* 0x3FFA8000 */ + + static const float two_to_jby32_trail_table[32] = { + 0.0000000000E+00F, /* 0x00000000 */ + 4.1277357377E-04F, /* 0x39D86988 */ + 1.3050324051E-03F, /* 0x3AAB0D9F */ + 7.3415064253E-04F, /* 0x3A407404 */ + 6.6398258787E-04F, /* 0x3A2E0F1E */ + 1.1054925853E-03F, /* 0x3A90E62D */ + 1.1675967835E-04F, /* 0x38F4DCE0 */ + 1.6154836630E-03F, /* 0x3AD3BEA3 */ + 1.7071149778E-03F, /* 0x3ADFC146 */ + 4.0360994171E-04F, /* 0x39D39B9C */ + 1.6234370414E-03F, /* 0x3AD4C982 */ + 1.4728321694E-03F, /* 0x3AC10C0C */ + 1.9176795613E-03F, /* 0x3AFB5AA6 */ + 1.0178930825E-03F, /* 0x3A856AD3 */ + 7.3992193211E-04F, /* 0x3A41F752 */ + 1.0973819299E-03F, /* 0x3A8FD607 */ + 1.5106226783E-04F, /* 0x391E6678 */ + 1.8214319134E-03F, /* 0x3AEEBD1D */ + 2.6364589576E-04F, /* 0x398A39F4 */ + 1.3519275235E-03F, /* 0x3AB13329 */ + 1.1952003697E-03F, /* 0x3A9CA845 */ + 1.7620950239E-03F, /* 0x3AE6F619 */ + 1.1153318919E-03F, /* 0x3A923054 */ + 1.2242280645E-03F, /* 0x3AA07647 */ + 1.5220546629E-04F, /* 0x391F9958 */ + 1.8224230735E-03F, /* 0x3AEEDE5F */ + 3.9278529584E-04F, /* 0x39CDEEC0 */ + 1.7403248930E-03F, /* 0x3AE41B9D */ + 2.3711356334E-05F, /* 0x37C6E7C0 */ + 1.1207590578E-03F, /* 0x3A92E66F */ + 1.1440613307E-03F, /* 0x3A95F454 */ + 1.1287408415E-04F }; /* 0x38ECB6D0 */ + + /* + Step 1. Reduce the argument. + + To perform argument reduction, we find the integer n such that + x = n * logbaseof2/32 + remainder, |remainder| <= logbaseof2/64. + n is defined by round-to-nearest-integer( x*32/logbaseof2 ) and + remainder by x - n*logbaseof2/32. The calculation of n is + straightforward whereas the computation of x - n*logbaseof2/32 + must be carried out carefully. + logbaseof2/32 is so represented in two pieces that + (1) logbaseof2/32 is known to extra precision, (2) the product + of n and the leading piece is a model number and is hence + calculated without error, and (3) the subtraction of the value + obtained in (2) from x is a model number and is hence again + obtained without error. + */ + + r = x * thirtytwo_by_logbaseof2; + /* Set n = nearest integer to r */ + /* This is faster on Hammer */ + if (r > 0) + n = (int)(r + 0.5F); + else + n = (int)(r - 0.5F); + + r1 = x - n * logbaseof2_by_32_lead; + r2 = -n * logbaseof2_by_32_trail; + + /* Set j = n mod 32: 5 mod 32 = 5, -5 mod 32 = 27, etc. */ + /* j = n % 32; + if (j < 0) j += 32; */ + j = n & 0x0000001f; + + f1 = two_to_jby32_lead_table[j]; + f2 = two_to_jby32_trail_table[j]; + + *m = (n - j) / 32; + + /* Step 2. The following is the core approximation. We approximate + exp(r1+r2)-1 by a polynomial. */ + + r1 *= logbase; r2 *= logbase; + + r = r1 + r2; + q = r1 + (r2 + + r * r * (5.00000000000000008883e-01F + + r * (1.66666666665260878863e-01F))); + + /* Step 3. Function value reconstruction. + We now reconstruct the exponential of the input argument + so that exp(x) = 2**m * (z1 + z2). + The order of the computation below must be strictly observed. */ + + *z1 = f1; + *z2 = f2 + ((f1 + f2) * q); +} + + + +/* Scales up a double (normal or denormal) whose bit pattern is given + as ux by 2**1024. There are no checks that the input number is + scalable by that amount. */ +static inline void scaleUpDouble1024(unsigned long long ux, unsigned long long* ur) +{ + unsigned long long uy; + double y; + + if ((ux & EXPBITS_DP64) == 0) + { + /* ux is denormalised */ + PUT_BITS_DP64(ux | 0x4010000000000000, y); + if (ux & SIGNBIT_DP64) + y += 4.0; + else + y -= 4.0; + GET_BITS_DP64(y, uy); + } + else + /* ux is normal */ + uy = ux + 0x4000000000000000; + + *ur = uy; + return; +} + + + +/* Scales down a double whose bit pattern is given as ux by 2**k. + There are no checks that the input number is scalable by that amount. */ +static inline void scaleDownDouble(unsigned long long ux, int k, + unsigned long long* ur) +{ + unsigned long long uy, uk, ax, xsign; + int n, shift; + xsign = ux & SIGNBIT_DP64; + ax = ux & ~SIGNBIT_DP64; + n = (int)((ax & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - k; + if (n > 0) + { + uk = (unsigned long long)n << EXPSHIFTBITS_DP64; + uy = (ax & ~EXPBITS_DP64) | uk; + } + else + { + uy = (ax & ~EXPBITS_DP64) | 0x0010000000000000; + shift = (1 - n); + if (shift > MANTLENGTH_DP64 + 1) + /* Sigh. Shifting works mod 64 so be careful not to shift too much */ + uy = 0; + else + { + /* Make sure we round the result */ + uy >>= shift - 1; + uy = (uy >> 1) + (uy & 1); + } + } + *ur = uy | xsign; +} + + +static inline void log_kernel_amd64(double x, unsigned long long ux, int* xexp, double* r1, double* r2) +{ + + int expadjust; + double r, z1, z2, correction, f, f1, f2, q, u, v, poly; + int index; + + /* + Computes natural log(x). Algorithm based on: + Ping-Tak Peter Tang + "Table-driven implementation of the logarithm function in IEEE + floating-point arithmetic" + ACM Transactions on Mathematical Software (TOMS) + Volume 16, Issue 4 (December 1990) + */ + + /* Arrays ln_lead_table and ln_tail_table contain + leading and trailing parts respectively of precomputed + values of natural log(1+i/64), for i = 0, 1, ..., 64. + ln_lead_table contains the first 24 bits of precision, + and ln_tail_table contains a further 53 bits precision. */ + + static const double ln_lead_table[65] = { + 0.00000000000000000000e+00, /* 0x0000000000000000 */ + 1.55041813850402832031e-02, /* 0x3f8fc0a800000000 */ + 3.07716131210327148438e-02, /* 0x3f9f829800000000 */ + 4.58095073699951171875e-02, /* 0x3fa7745800000000 */ + 6.06245994567871093750e-02, /* 0x3faf0a3000000000 */ + 7.52233862876892089844e-02, /* 0x3fb341d700000000 */ + 8.96121263504028320312e-02, /* 0x3fb6f0d200000000 */ + 1.03796780109405517578e-01, /* 0x3fba926d00000000 */ + 1.17783010005950927734e-01, /* 0x3fbe270700000000 */ + 1.31576299667358398438e-01, /* 0x3fc0d77e00000000 */ + 1.45181953907012939453e-01, /* 0x3fc2955280000000 */ + 1.58604979515075683594e-01, /* 0x3fc44d2b00000000 */ + 1.71850204467773437500e-01, /* 0x3fc5ff3000000000 */ + 1.84922337532043457031e-01, /* 0x3fc7ab8900000000 */ + 1.97825729846954345703e-01, /* 0x3fc9525a80000000 */ + 2.10564732551574707031e-01, /* 0x3fcaf3c900000000 */ + 2.23143517971038818359e-01, /* 0x3fcc8ff780000000 */ + 2.35566020011901855469e-01, /* 0x3fce270700000000 */ + 2.47836112976074218750e-01, /* 0x3fcfb91800000000 */ + 2.59957492351531982422e-01, /* 0x3fd0a324c0000000 */ + 2.71933674812316894531e-01, /* 0x3fd1675c80000000 */ + 2.83768117427825927734e-01, /* 0x3fd22941c0000000 */ + 2.95464158058166503906e-01, /* 0x3fd2e8e280000000 */ + 3.07025015354156494141e-01, /* 0x3fd3a64c40000000 */ + 3.18453729152679443359e-01, /* 0x3fd4618bc0000000 */ + 3.29753279685974121094e-01, /* 0x3fd51aad80000000 */ + 3.40926527976989746094e-01, /* 0x3fd5d1bd80000000 */ + 3.51976394653320312500e-01, /* 0x3fd686c800000000 */ + 3.62905442714691162109e-01, /* 0x3fd739d7c0000000 */ + 3.73716354370117187500e-01, /* 0x3fd7eaf800000000 */ + 3.84411692619323730469e-01, /* 0x3fd89a3380000000 */ + 3.94993782043457031250e-01, /* 0x3fd9479400000000 */ + 4.05465066432952880859e-01, /* 0x3fd9f323c0000000 */ + 4.15827870368957519531e-01, /* 0x3fda9cec80000000 */ + 4.26084339618682861328e-01, /* 0x3fdb44f740000000 */ + 4.36236739158630371094e-01, /* 0x3fdbeb4d80000000 */ + 4.46287095546722412109e-01, /* 0x3fdc8ff7c0000000 */ + 4.56237375736236572266e-01, /* 0x3fdd32fe40000000 */ + 4.66089725494384765625e-01, /* 0x3fddd46a00000000 */ + 4.75845873355865478516e-01, /* 0x3fde744240000000 */ + 4.85507786273956298828e-01, /* 0x3fdf128f40000000 */ + 4.95077252388000488281e-01, /* 0x3fdfaf5880000000 */ + 5.04556000232696533203e-01, /* 0x3fe02552a0000000 */ + 5.13945698738098144531e-01, /* 0x3fe0723e40000000 */ + 5.23248136043548583984e-01, /* 0x3fe0be72e0000000 */ + 5.32464742660522460938e-01, /* 0x3fe109f380000000 */ + 5.41597247123718261719e-01, /* 0x3fe154c3c0000000 */ + 5.50647079944610595703e-01, /* 0x3fe19ee6a0000000 */ + 5.59615731239318847656e-01, /* 0x3fe1e85f40000000 */ + 5.68504691123962402344e-01, /* 0x3fe23130c0000000 */ + 5.77315330505371093750e-01, /* 0x3fe2795e00000000 */ + 5.86049020290374755859e-01, /* 0x3fe2c0e9e0000000 */ + 5.94707071781158447266e-01, /* 0x3fe307d720000000 */ + 6.03290796279907226562e-01, /* 0x3fe34e2880000000 */ + 6.11801505088806152344e-01, /* 0x3fe393e0c0000000 */ + 6.20240390300750732422e-01, /* 0x3fe3d90260000000 */ + 6.28608644008636474609e-01, /* 0x3fe41d8fe0000000 */ + 6.36907458305358886719e-01, /* 0x3fe4618bc0000000 */ + 6.45137906074523925781e-01, /* 0x3fe4a4f840000000 */ + 6.53301239013671875000e-01, /* 0x3fe4e7d800000000 */ + 6.61398470401763916016e-01, /* 0x3fe52a2d20000000 */ + 6.69430613517761230469e-01, /* 0x3fe56bf9c0000000 */ + 6.77398800849914550781e-01, /* 0x3fe5ad4040000000 */ + 6.85303986072540283203e-01, /* 0x3fe5ee02a0000000 */ + 6.93147122859954833984e-01 }; /* 0x3fe62e42e0000000 */ + + static const double ln_tail_table[65] = { + 0.00000000000000000000e+00, /* 0x0000000000000000 */ + 5.15092497094772879206e-09, /* 0x3e361f807c79f3db */ + 4.55457209735272790188e-08, /* 0x3e6873c1980267c8 */ + 2.86612990859791781788e-08, /* 0x3e5ec65b9f88c69e */ + 2.23596477332056055352e-08, /* 0x3e58022c54cc2f99 */ + 3.49498983167142274770e-08, /* 0x3e62c37a3a125330 */ + 3.23392843005887000414e-08, /* 0x3e615cad69737c93 */ + 1.35722380472479366661e-08, /* 0x3e4d256ab1b285e9 */ + 2.56504325268044191098e-08, /* 0x3e5b8abcb97a7aa2 */ + 5.81213608741512136843e-08, /* 0x3e6f34239659a5dc */ + 5.59374849578288093334e-08, /* 0x3e6e07fd48d30177 */ + 5.06615629004996189970e-08, /* 0x3e6b32df4799f4f6 */ + 5.24588857848400955725e-08, /* 0x3e6c29e4f4f21cf8 */ + 9.61968535632653505972e-10, /* 0x3e1086c848df1b59 */ + 1.34829655346594463137e-08, /* 0x3e4cf456b4764130 */ + 3.65557749306383026498e-08, /* 0x3e63a02ffcb63398 */ + 3.33431709374069198903e-08, /* 0x3e61e6a6886b0976 */ + 5.13008650536088382197e-08, /* 0x3e6b8abcb97a7aa2 */ + 5.09285070380306053751e-08, /* 0x3e6b578f8aa35552 */ + 3.20853940845502057341e-08, /* 0x3e6139c871afb9fc */ + 4.06713248643004200446e-08, /* 0x3e65d5d30701ce64 */ + 5.57028186706125221168e-08, /* 0x3e6de7bcb2d12142 */ + 5.48356693724804282546e-08, /* 0x3e6d708e984e1664 */ + 1.99407553679345001938e-08, /* 0x3e556945e9c72f36 */ + 1.96585517245087232086e-09, /* 0x3e20e2f613e85bda */ + 6.68649386072067321503e-09, /* 0x3e3cb7e0b42724f6 */ + 5.89936034642113390002e-08, /* 0x3e6fac04e52846c7 */ + 2.85038578721554472484e-08, /* 0x3e5e9b14aec442be */ + 5.09746772910284482606e-08, /* 0x3e6b5de8034e7126 */ + 5.54234668933210171467e-08, /* 0x3e6dc157e1b259d3 */ + 6.29100830926604004874e-09, /* 0x3e3b05096ad69c62 */ + 2.61974119468563937716e-08, /* 0x3e5c2116faba4cdd */ + 4.16752115011186398935e-08, /* 0x3e665fcc25f95b47 */ + 2.47747534460820790327e-08, /* 0x3e5a9a08498d4850 */ + 5.56922172017964209793e-08, /* 0x3e6de647b1465f77 */ + 2.76162876992552906035e-08, /* 0x3e5da71b7bf7861d */ + 7.08169709942321478061e-09, /* 0x3e3e6a6886b09760 */ + 5.77453510221151779025e-08, /* 0x3e6f0075eab0ef64 */ + 4.43021445893361960146e-09, /* 0x3e33071282fb989b */ + 3.15140984357495864573e-08, /* 0x3e60eb43c3f1bed2 */ + 2.95077445089736670973e-08, /* 0x3e5faf06ecb35c84 */ + 1.44098510263167149349e-08, /* 0x3e4ef1e63db35f68 */ + 1.05196987538551827693e-08, /* 0x3e469743fb1a71a5 */ + 5.23641361722697546261e-08, /* 0x3e6c1cdf404e5796 */ + 7.72099925253243069458e-09, /* 0x3e4094aa0ada625e */ + 5.62089493829364197156e-08, /* 0x3e6e2d4c96fde3ec */ + 3.53090261098577946927e-08, /* 0x3e62f4d5e9a98f34 */ + 3.80080516835568242269e-08, /* 0x3e6467c96ecc5cbe */ + 5.66961038386146408282e-08, /* 0x3e6e7040d03dec5a */ + 4.42287063097349852717e-08, /* 0x3e67bebf4282de36 */ + 3.45294525105681104660e-08, /* 0x3e6289b11aeb783f */ + 2.47132034530447431509e-08, /* 0x3e5a891d1772f538 */ + 3.59655343422487209774e-08, /* 0x3e634f10be1fb591 */ + 5.51581770357780862071e-08, /* 0x3e6d9ce1d316eb93 */ + 3.60171867511861372793e-08, /* 0x3e63562a19a9c442 */ + 1.94511067964296180547e-08, /* 0x3e54e2adf548084c */ + 1.54137376631349347838e-08, /* 0x3e508ce55cc8c97a */ + 3.93171034490174464173e-09, /* 0x3e30e2f613e85bda */ + 5.52990607758839766440e-08, /* 0x3e6db03ebb0227bf */ + 3.29990737637586136511e-08, /* 0x3e61b75bb09cb098 */ + 1.18436010922446096216e-08, /* 0x3e496f16abb9df22 */ + 4.04248680368301346709e-08, /* 0x3e65b3f399411c62 */ + 2.27418915900284316293e-08, /* 0x3e586b3e59f65355 */ + 1.70263791333409206020e-08, /* 0x3e52482ceae1ac12 */ + 5.76999904754328540596e-08 }; /* 0x3e6efa39ef35793c */ + + /* Approximating polynomial coefficients for x near 1.0 */ + static const double + ca_1 = 8.33333333333317923934e-02, /* 0x3fb55555555554e6 */ + ca_2 = 1.25000000037717509602e-02, /* 0x3f89999999bac6d4 */ + ca_3 = 2.23213998791944806202e-03, /* 0x3f62492307f1519f */ + ca_4 = 4.34887777707614552256e-04; /* 0x3f3c8034c85dfff0 */ + + /* Approximating polynomial coefficients for other x */ + static const double + cb_1 = 8.33333333333333593622e-02, /* 0x3fb5555555555557 */ + cb_2 = 1.24999999978138668903e-02, /* 0x3f89999999865ede */ + cb_3 = 2.23219810758559851206e-03; /* 0x3f6249423bd94741 */ + + static const unsigned long long + log_thresh1 = 0x3fee0faa00000000, + log_thresh2 = 0x3ff1082c00000000; + + /* log_thresh1 = 9.39412117004394531250e-1 = 0x3fee0faa00000000 + log_thresh2 = 1.06449508666992187500 = 0x3ff1082c00000000 */ + if (ux >= log_thresh1 && ux <= log_thresh2) + { + /* Arguments close to 1.0 are handled separately to maintain + accuracy. + + The approximation in this region exploits the identity + log( 1 + r ) = log( 1 + u/2 ) / log( 1 - u/2 ), where + u = 2r / (2+r). + Note that the right hand side has an odd Taylor series expansion + which converges much faster than the Taylor series expansion of + log( 1 + r ) in r. Thus, we approximate log( 1 + r ) by + u + A1 * u^3 + A2 * u^5 + ... + An * u^(2n+1). + + One subtlety is that since u cannot be calculated from + r exactly, the rounding error in the first u should be + avoided if possible. To accomplish this, we observe that + u = r - r*r/(2+r). + Since x (=1+r) is the input argument, and thus presumed exact, + the formula above approximates u accurately because + u = r - correction, + and the magnitude of "correction" (of the order of r*r) + is small. + With these observations, we will approximate log( 1 + r ) by + r + ( (A1*u^3 + ... + An*u^(2n+1)) - correction ). + + We approximate log(1+r) by an odd polynomial in u, where + u = 2r/(2+r) = r - r*r/(2+r). + */ + r = x - 1.0; + u = r / (2.0 + r); + correction = r * u; + u = u + u; + v = u * u; + z1 = r; + z2 = (u * v * (ca_1 + v * (ca_2 + v * (ca_3 + v * ca_4))) - correction); + *r1 = z1; + *r2 = z2; + *xexp = 0; + } + else + { + /* + First, we decompose the argument x to the form + x = 2**M * (F1 + F2), + where 1 <= F1+F2 < 2, M has the value of an integer, + F1 = 1 + j/64, j ranges from 0 to 64, and |F2| <= 1/128. + + Second, we approximate log( 1 + F2/F1 ) by an odd polynomial + in U, where U = 2 F2 / (2 F2 + F1). + Note that log( 1 + F2/F1 ) = log( 1 + U/2 ) - log( 1 - U/2 ). + The core approximation calculates + Poly = [log( 1 + U/2 ) - log( 1 - U/2 )]/U - 1. + Note that log(1 + U/2) - log(1 - U/2) = 2 arctanh ( U/2 ), + thus, Poly = 2 arctanh( U/2 ) / U - 1. + + It is not hard to see that + log(x) = M*log(2) + log(F1) + log( 1 + F2/F1 ). + Hence, we return Z1 = log(F1), and Z2 = log( 1 + F2/F1). + The values of log(F1) are calculated beforehand and stored + in the program. + */ + + f = x; + if (ux < IMPBIT_DP64) + { + /* The input argument x is denormalized */ + /* Normalize f by increasing the exponent by 60 + and subtracting a correction to account for the implicit + bit. This replaces a slow denormalized + multiplication by a fast normal subtraction. */ + static const double corr = 2.5653355008114851558350183e-290; /* 0x03d0000000000000 */ + GET_BITS_DP64(f, ux); + ux |= 0x03d0000000000000; + PUT_BITS_DP64(ux, f); + f -= corr; + GET_BITS_DP64(f, ux); + expadjust = 60; + } + else + expadjust = 0; + + /* Store the exponent of x in xexp and put + f into the range [0.5,1) */ + *xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64 - expadjust; + PUT_BITS_DP64((ux & MANTBITS_DP64) | HALFEXPBITS_DP64, f); + + /* Now x = 2**xexp * f, 1/2 <= f < 1. */ + + /* Set index to be the nearest integer to 128*f */ + r = 128.0 * f; + index = (int)(r + 0.5); + + z1 = ln_lead_table[index - 64]; + q = ln_tail_table[index - 64]; + f1 = index * 0.0078125; /* 0.0078125 = 1/128 */ + f2 = f - f1; + /* At this point, x = 2**xexp * ( f1 + f2 ) where + f1 = j/128, j = 64, 65, ..., 128 and |f2| <= 1/256. */ + + /* Calculate u = 2 f2 / ( 2 f1 + f2 ) = f2 / ( f1 + 0.5*f2 ) */ + /* u = f2 / (f1 + 0.5 * f2); */ + u = f2 / (f1 + 0.5 * f2); + + /* Here, |u| <= 2(exp(1/16)-1) / (exp(1/16)+1). + The core approximation calculates + poly = [log(1 + u/2) - log(1 - u/2)]/u - 1 */ + v = u * u; + poly = (v * (cb_1 + v * (cb_2 + v * cb_3))); + z2 = q + (u + u * poly); + *r1 = z1; + *r2 = z2; + } + return; +} + +#endif /* LIBM_INLINES_AMD_H_INCLUDED */ diff --git a/src/native/clrmath/inc/libm/libm_poly.h b/src/native/clrmath/inc/libm/libm_poly.h new file mode 100644 index 00000000000000..55100fb754b76c --- /dev/null +++ b/src/native/clrmath/inc/libm/libm_poly.h @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2018-2020, Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __LIBM_POLY_H__ +#define __LIBM_POLY_H__ + + /* + * poly = C1 + C2*r + C3*r^2 + C4*r^3 + */ +#define _POLY_EVAL_3(type, name) \ +inline type name(type r, type c1, type c2, type c3, type c4) \ +{ \ + type t1, t2, r2, q; \ + t1 = c1 + c2*r; \ + t2 = c3 + c4*r; \ + r2 = r * r; \ + q = t1 + r2 * t2; \ + return q; \ +} + +_POLY_EVAL_3(double, POLY_EVAL_3) +_POLY_EVAL_3(float, POLY_EVAL_3F) + + /* + * poly = C1 + C2*r + C3*r^2 + C4*r^3 + * = (C1 + C2*r) + r^2(C3 + C4*r) + */ +#define _POLY_EVAL_4(type, name) \ +inline type name(type r, type c0, type c1, type c2, type c3) \ +{ \ + type t1, t2, r2, q; \ + t1 = c0 + c1*r; \ + t2 = c2 + c3*r; \ + r2 = r * r; \ + q = t1 + r2 * t2; \ + return q; \ +} + +_POLY_EVAL_4(double, POLY_EVAL_4) +_POLY_EVAL_4(float, POLY_EVAL_4F) + + /* + * poly = C1 + C2*r + C3*r^2 + C4*r^3 + C5 *r^4 + * = (C1 + C2*r) + r^2(C3 + C4*r) + r^4*C5 + */ +#define _POLY_EVAL_5(type, name) \ +inline type name(type r, type c0, type c1, type c2, type c3, type c4) \ +{ \ + type t1, t2, r2, q; \ + t1 = c0 + c1*r; \ + t2 = c2 + c3*r; \ + r2 = r * r; \ + q = t1 + r2 * t2; \ + q = q + r2 * r2 * c4; \ + return q; \ +} + +_POLY_EVAL_5(double, POLY_EVAL_5) +_POLY_EVAL_5(float, POLY_EVAL_5F) + + /* + * poly = C1 + C2*r + C3*r^2 + C4*r^3 + C5 *r^4 + C6*r^5 + * = (C1 + C2*r) + r^2(C3 + C4*r) + r^4(C5 + C6*r) + */ +#define _POLY_EVAL_6(type, name) \ +inline type name(type r, type c0, type c1, type c2, type c3, type c4, type c5) \ +{ \ + type t1, t2, t3, r2, q; \ + t1 = c0 + c1*r; \ + t2 = c2 + c3*r; \ + r2 = r * r; \ + t3 = c4 + c5*r; \ + q = t1 + r2 * t2; \ + q = q + r2 * r2 * t3; \ + return q; \ +} + +_POLY_EVAL_6(double, POLY_EVAL_6) +_POLY_EVAL_6(float, POLY_EVAL_6F) + + /* + * poly = C1 + C2*r + C3*r^2 + C4*r^3 + C5 *r^4 + C6*r^5 \ + * + C7*r^6 + C8*r^7 + C9*r^8 + * + * = ((C6+C7*x)*x2 + (C4+C5*x))*x4 + + * (C8+C9*x)*x8) + + * ((C2+C3*x)*x2 + (C0+C1*x)); + */ +#define _POLY_EVAL_9(type, name) \ +inline type name(type r, type c0, type c1, type c2, type c3, type c4, type c5, \ + type c6, type c7, type c8) \ +{ \ + type a1, a2, a3, a4, b1, b2, q; \ + type r2, r4; \ + a1 = c2*r + c1; \ + a2 = c4*r + c3; \ + r2 = r * r; \ + a3 = c6*r + c5; \ + r4 = r2 * r2; \ + a4 = c8*r + c7; \ + \ + b1 = a4*r4 + a3*r2 + a2; \ + b2 = a1*r2 + c0*r; \ + q = b1*r4 + b2; \ + return q; \ +} + +_POLY_EVAL_9(double, POLY_EVAL_9) +_POLY_EVAL_9(float, POLY_EVAL_9F) + + /* + * poly = x * (C1 + C2*x^2 + C3*x^4 + C4*x^6 + C5*x^8 + \ + * C6*x^10 + C7*x^12 + C8*x^14) + * 15 degree polynomial with only even terms + */ +#define _POLY_EVAL_EVEN_15(type, name) \ +inline type name(type r, type c1, type c2, type c3, type c4, type c5, type c6, \ + type c7, type c8) \ +{ \ + type a1, a2, a3, a4, b1, b2 ,q; \ + type r2, r4, r8, r12; \ + r2 = r * r; \ + r4 = r2 * r2; \ + r8 = r4 * r4; \ + r12 = r8 * r4; \ + a1 = c1 + c2*r2; \ + a2 = c3 + c4*r2; \ + a3 = c5 + c6*r2; \ + a4 = c7 + c8*r2; \ + \ + b1 = a1 + a2*r4; \ + b2 = r8*a3 + r12*a4; \ + \ + q = r*(b1 + b2); \ + return q; \ +} + +_POLY_EVAL_EVEN_15(double, POLY_EVAL_EVEN_15) +_POLY_EVAL_EVEN_15(float, POLY_EVAL_EVEN_15F) + +#define _POLY_EVAL_ODD_17(type, name) \ +inline type name(type r, type c1, type c3, type c5, type c7, type c9, \ + type c11, type c13, type c15) \ +{ \ + type a1, a2, a3, a4, b1, b2 ,q; \ + type r2, r4, r6, r10, r14; \ + r2 = r * r; \ + r4 = r2 * r2; \ + r6 = r4 * r2; \ + r10 = r6 * r4; \ + r14 = r10 * r4; \ + a1 = c1 + c3*r2; \ + a2 = c5 + c7*r2; \ + a3 = c9 + c11*r2; \ + a4 = c13 + c15*r2; \ + \ + b1 = a1*r2 + a2*r6; \ + b2 = r10*a3 + r14*a4; \ + \ + q = r*(b1 + b2); \ + return q; \ +} + +_POLY_EVAL_ODD_17(double, POLY_EVAL_ODD_17) +_POLY_EVAL_ODD_17(float, POLY_EVAL_ODD_17F) + + /* + * poly = x + C1*x^3 + C2*x^5 + C3*x^7 + C4*x^9 + C5*x^11 + \ + * C6*x^13 + C7*x^15 + C8*x^17 + C9*x^19 + \ + * C10*x^21 + C11*x^23 + C12*x^25 + C13*x^27 + C14*x^29; + * + * = x + x * G*(C6 + G*(C7 + G*(C8 + + * G*(C9 + G*(C10+ G*(C11 + G*(C12 + + * G*(C13 + C14*G)))) + */ + +#define _POLY_EVAL_ODD_29(type, name) \ +inline type name(type r, type c1, type c3, type c5, type c7, type c9, \ + type c11, type c13, type c15, type c17, type c19, type c21, \ + type c23, type c25, type c27) \ +{ \ + type a1, a2, a3, a4, a5, a6, a7; \ + type b1, b2, b3, b4, q; \ + type g, g2, g3, g5, g7, g9, g11, g13; \ + g = r * r; \ + g2 = g * g; \ + g3 = g * g2; \ + g5 = g3 * g2; \ + g7 = g5 * g2; \ + g9 = g7 * g2; \ + g11 = g9 * g2; \ + g13 = g11 * g2; \ + \ + a1 = c1 + c3*g; \ + a2 = c5 + c7*g; \ + a3 = c9 + c11*g; \ + a4 = c13 + c15*g; \ + a5 = c17 + c19*g; \ + a6 = c21 + c23*g; \ + a7 = c25 + c27*g; \ + \ + b1 = g*a1 + g3*a2; \ + b2 = g5*a3 + g7*a4; \ + b3 = g9*a5 + g11*a6; \ + b4 = g13*a7; \ + \ + q = b1 + b2 + b3 + b4; \ + q = r + r*q; \ + return q; \ +} + +_POLY_EVAL_ODD_29(double, POLY_EVAL_ODD_29) +_POLY_EVAL_ODD_29(float, POLY_EVAL_ODD_29) + + /* + * poly = x + (C1*x^3 + C2*x^5 + C3*x^7 + C4*x^9 + C5*x^11 + \ + * C6*x^13 + C7*x^15) + * = x + x3*(C1 + C2*x^2 + C3*x^4 + C4*x^6 + C5*x^8 + \ + * C6*x^10 + C7*x^12) + * 15 degree polynomial with only odd terms + */ +#define _POLY_EVAL_ODD_15(type, name) \ +inline type name(type r, type c1, type c2, type c3, type c4, type c5, type c6, \ + type c7) \ +{ \ + type a1, a2, a3, b1, b2 ,q; \ + type r2, r4, r8, r12; \ + r2 = r * r; \ + r4 = r2 * r2; \ + r8 = r4 * r4; \ + r12 = r8 * r4; \ + a1 = c1 + c2*r2; \ + a2 = c3 + c4*r2; \ + a3 = c5 + c6*r2; \ + \ + b1 = a1 + a2*r4; \ + b2 = r8*a3 + r12*c7; \ + \ + q = r + r * r2 * (b1 + b2); \ + return q; \ +} + +_POLY_EVAL_ODD_15(double, POLY_EVAL_ODD_15) +_POLY_EVAL_ODD_15(float, POLY_EVAL_ODD_15F) + + /* + * poly = C0 + C1*r^3 + C2*r^5 + C3*r^7+ C4 *r^9 \ + * + * = C0 + r^2*(C1 + C2*r^2) + r^4*(C3*r^2+C4*r^4) + * + */ +#define _POLY_EVAL_ODD_9(type, name) \ +inline type name(type r, type c0, type c1, type c2, type c3, type c4) \ +{ \ + type a0, a1, a2, q; \ + type r2, r4; \ + r2 = r * r; \ + r4 = r2 * r2; \ + \ + a0 = c2*r2 + c1; \ + a1 = a0*r2 + c0; \ + a2 = (c3*r2 + c4*r4)*r4; \ + q = r*(a1 + a2); \ + return q; \ +} + +_POLY_EVAL_ODD_9(double, POLY_EVAL_ODD_9) +_POLY_EVAL_ODD_9(float, POLY_EVAL_ODD_9F) + +#endif /* LIBM_POLY_H */ diff --git a/src/native/clrmath/inc/libm/libm_special.h b/src/native/clrmath/inc/libm/libm_special.h new file mode 100644 index 00000000000000..6cccd6624071c3 --- /dev/null +++ b/src/native/clrmath/inc/libm/libm_special.h @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __LIBM_SPECIAL_H__ +#define __LIBM_SPECIAL_H__ + +double __amd_handle_error( + const char* fname, + int opcode, + unsigned long long value, + int type, + int flags, + int error, + double arg1, + double arg2, + int nargs +); + +float __amd_handle_errorf( + const char* fname, + int opcode, + unsigned int value, + int type, + int flags, + int error, + float arg1, + float arg2, + int nargs +); + + + +typedef enum { + __amd_unspecified, + __amd_add, + __amd_subtract, + __amd_multiply, + __amd_divide, + __amd_squareroot, + __amd_remainder, + __amd_compare, + __amd_convert, + __amd_round, + __amd_truncate, + __amd_floor, + __amd_ceil, + __amd_acos, + __amd_asin, + __amd_atan, + __amd_atan2, + __amd_cabs, + __amd_cos, + __amd_cosh, + __amd_exp, + __amd_fabs, + __amd_fmod, + __amd_frexp, + __amd_hypot, + __amd_ldexp, + __amd_log, + __amd_log10, + __amd_modf, + __amd_pow, + __amd_sin, + __amd_sinh, + __amd_tan, + __amd_tanh, + __amd_y0, + __amd_y1, + __amd_yn, + __amd_logb, + __amd_nextafter, + __amd_negate, + __amd_fmin, + __amd_fmax, + __amd_converttrunc, + __amd_addps, + __amd_addss, + __amd_subps, + __amd_subss, + __amd_mulps, + __amd_mulss, + __amd_divps, + __amd_divss, + __amd_sqrtps, + __amd_sqrtss, + __amd_maxps, + __amd_maxss, + __amd_minps, + __amd_minss, + __amd_cmpps, + __amd_cmpss, + __amd_comiss, + __amd_ucomiss, + __amd_cvtpi2ps, + __amd_cvtsi2ss, + __amd_cvtps2pi, + __amd_Cvtss2si, + __amd_cvttps2pi, + __amd_cvttss2si, + __amd_addsubps, /* XMMI for PNI */ + __amd_haddps, /* XMMI for PNI */ + __amd_hsubps, /* XMMI for PNI */ + __amd_roundps, /* 66 0F 3A 08 */ + __amd_roundss, /* 66 0F 3A 0A */ + __amd_dpps, /* 66 0F 3A 40 */ + __amd_addpd, /* XMMI2 */ + __amd_addsd, + __amd_subpd, + __amd_subsd, + __amd_mulpd, + __amd_mulsd, + __amd_divpd, + __amd_divsd, + __amd_sqrtpd, + __amd_sqrtsd, + __amd_maxpd, + __amd_maxsd, + __amd_minpd, + __amd_minsd, + __amd_cmppd, + __amd_cmpsd, + __amd_comisd, + __amd_ucomisd, + __amd_cvtpd2pi, /* 66 2D */ + __amd_cvtsd2si, /* F2 */ + __amd_cvttpd2pi, /* 66 2C */ + __amd_cvttsd2si, /* F2 */ + __amd_cvtps2pd, /* 0F 5A */ + __amd_cvtss2sd, /* F3 */ + __amd_cvtpd2ps, /* 66 */ + __amd_cvtsd2ss, /* F2 */ + __amd_cvtdq2ps, /* 0F 5B */ + __amd_cvttps2dq, /* F3 */ + __amd_cvtps2dq, /* 66 */ + __amd_cvttpd2dq, /* 66 0F E6 */ + __amd_cvtpd2dq, /* F2 */ + __amd_addsubpd, /* 66 0F D0 */ + __amd_haddpd, /* 66 0F 7C */ + __amd_hsubpd, /* 66 0F 7D */ + __amd_roundpd, /* 66 0F 3A 09 */ + __amd_roundsd, /* 66 0F 3A 0B */ + __amd_dppd, /* 66 0F 3A 41 */ + __amd_fmaSingle, + __amd_fmaDouble, + __amd_fms, + __amd_fmsSingle, + __amd_fmsDouble, + __amd_fnma, + __amd_fnmaSingle, + __amd_fnmaDouble, + __amd_famin, + __amd_famax, +} _AMDLIBM_CODE; + +#define _DOMAIN 1 /* argument domain error */ +#define _SING 2 /* argument singularity */ +#define _OVERFLOW 3 /* overflow range error */ +#define _UNDERFLOW 4 /* underflow range error */ +#define _TLOSS 5 /* total loss of precision */ +#define _PLOSS 6 /* partial loss of precision */ + +typedef enum +{ + __amd_asinh = (__amd_dppd + 20), + __amd_acosh, + __amd_atanh, + __amd_cbrt, + __amd_exp10, + __amd_exp2, + __amd_expm1, + __amd_lrint, + __amd_rint, + __amd_nexttoward, + __amd_nearbyint, + __amd_fdim, + __amd_finite, + __amd_scalbn, + __amd_scalbln, + __amd_log1p, + __amd_log2, + __amd_llrint, + __amd_llround, + __amd_lround, + __amd_remquo, + __amd_fma +}_AMDLIBM_EXTERNAL; + + +extern double _cbrt_special(double x); +extern double _cos_special(double x); +extern double _exp10_special(double x, double y, uint32_t code); +extern double _exp2_special(double x, double y, uint32_t code); +extern double _expm1_special(double x, double y, uint32_t code); +extern double _exp_special(double x, double y, uint32_t code); +extern double _fabs_special(double x); +extern double _fdim_special(double x, double y, double r); +extern double _fmax_special(double x, double y); +extern double _fmin_special(double x, double y); +extern double _fmod_special(double x, double y, uint32_t errorCode); +extern double _log10_special(double x, double y, uint32_t code); +extern double _log1p_special(double x, double y, uint32_t code); +extern double _log2_special(double x, double y, uint32_t code); +extern double _log_special(double x, double y, uint32_t code); +extern double _nearbyint_special(double x); +extern double _pow_special(double x, double y, double z, uint32_t code); +extern double _remainder_special(double x, double y, uint32_t errorCode); +extern double _round_special(double x, double r); +extern double _sin_cos_special(double x, const char* name, _AMDLIBM_CODE code); +extern double _sincos_special_underflow(double x, const char* name, _AMDLIBM_CODE code); +extern double _sin_special(double x); +extern double _sin_special_underflow(double x); +extern double _tan_special(double x); +extern double _trunc_special(double x, double r); +extern void _sincos_special(double x, double* sy, double* cy); + +extern float _cbrtf_special(float x); +extern float _cosf_special(float x); +extern float _exp10f_special(float x, float y, uint32_t code); +extern float _exp2f_special(float x, float y, uint32_t code); +extern float _expf_special(float x, float y, uint32_t code); +extern float _expm1f_special(float x, float y, uint32_t code); +extern float _fabsf_special(float x); +extern float _fdimf_special(float x, float y, float r); +extern float _fmaxf_special(float x, float y); +extern float _fminf_special(float x, float y); +extern float _fmodf_special(float x, float y, uint32_t errorCode); +extern float _log10f_special(float x, float y, uint32_t code); +extern float _log1pf_special(float x, float y, uint32_t code); +extern float _log2f_special(float x, float y, uint32_t code); +extern float _logf_special(float x, float y, uint32_t code); +extern float _powf_special(float x, float y, float z, uint32_t code); +extern float _remainderf_special(float x, float y, uint32_t errorCode); +extern float _sinf_cosf_special(float x, const char* name, _AMDLIBM_CODE code); +extern float _sinf_special(float x); +extern float _tanf_special(float x); +extern float _tanhf_special(float x); +extern float _truncf_special(float x, float r); +extern void _sincosf_special(float x, float* sy, float* cy); +extern float _sinf_cosf_special_underflow(float x, const char* name, _AMDLIBM_CODE code); + +#endif // __LIBM_SPECIAL_H__; diff --git a/src/native/clrmath/inc/libm/libm_typehelper.h b/src/native/clrmath/inc/libm/libm_typehelper.h new file mode 100644 index 00000000000000..932d00e7732565 --- /dev/null +++ b/src/native/clrmath/inc/libm/libm_typehelper.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2018-2020, Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __LIBM_TYPEHELPER_H__ +#define __LIBM_TYPEHELPER_H__ + +#include "libm/libm_types.h" + +static inline uint32_t +asuint32(float f) +{ + flt32u_t fl; + fl.f = f; + return fl.i; +} + +static inline float +asfloat(uint32_t i) +{ + flt32u_t fl; + fl.i = i; + return fl.f; +} + +static inline double +asdouble(uint64_t i) +{ + flt64_t dbl; + dbl.i = i; + return dbl.d; +} + +static inline uint64_t +asuint64(double f) +{ + flt64u_t fl; + fl.d = f; + return fl.i; +} + +static inline double +eval_as_double(double d) +{ + return d; +} + +static inline float +eval_as_float(float f) +{ + return f; +} + +static inline int32_t +cast_float_to_i32(float x) +{ + return (int32_t)x; +} + +static inline int64_t +cast_double_to_i64(double x) +{ + return (int64_t)x; +} + +static inline float +cast_i32_to_float(int32_t x) +{ + return (float)x; +} + +static inline double +cast_i64_to_double(int64_t x) +{ + return (double)x; +} + +#endif /* __LIBM_TYPEHELPER_H__ */ diff --git a/src/native/clrmath/inc/libm/libm_types.h b/src/native/clrmath/inc/libm/libm_types.h new file mode 100644 index 00000000000000..94afec14ebe67d --- /dev/null +++ b/src/native/clrmath/inc/libm/libm_types.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2018-2020, Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __LIBM_TYPES_H__ +#define __LIBM_TYPES_H__ + +#define PASTE2(a, b) a##b +#define STRINGIFY2(x) #x +#define STRINGIFY(x) STRINGIFY2(x) + + +typedef short f16_t; +typedef float f32_t; +typedef double f64_t; +typedef long double f80_t; + +/***************************** + * Internal types + *****************************/ +typedef union { + uint32_t i; + float f; +} flt32u_t; + +typedef union { + int32_t i; + float f; +} flt32_t; + +typedef union { + double d; + uint64_t i; +} flt64u_t; + +typedef union { + int64_t i; + double d; +} flt64_t; + +#endif /* LIBM_TYPES_H */ diff --git a/src/native/clrmath/inc/libm/libm_util.h b/src/native/clrmath/inc/libm/libm_util.h new file mode 100644 index 00000000000000..83e50d1afa1a2f --- /dev/null +++ b/src/native/clrmath/inc/libm/libm_util.h @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef _LIBM_UTIL_H_ +#define _LIBM_UTIL_H_ + +// Various methods have Windows vs non-Windows paths for POSIX compliance +// These paths shouldn't make a difference for managed code, but we'll do the right thing for each platform + +#ifdef TARGET_WINDOWS +#define WINDOWS 1 +#elif defined(WINDOWS) +#error "WINDOWS is defined but TARGET_WINDOWS is not" +#endif + +// We want to follow the IEEE 754 spec +#define FOLLOW_IEEE754_LOGB 1 + +#include "libm/libm_util_amd.h" + +typedef double double_t; +typedef float float_t; + +// We want to just call libm_sqrt and avoid the actual assembly/intrinsics +#define ASMSQRT(x, y) y = clrmath_sqrt(x) +#define ASMSQRTF(x, y) y = clrmath_sqrtf(x) + +#if defined(_MSC_VER) +#define ALIGN(x) __declspec(align(x)) +#define likely(x) (x) +#define unlikely(x) (x) +#else +#define ALIGN(x) __attribute__((aligned((x)))) +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(x, 0) +#endif + +#define ALM_PREFIX clrmath + +#if defined(ALM_SUFFIX) +#define ALM_PROTO(x) ALM_MAKE_PROTO_SFX(ALM_PREFIX, x, ALM_SUFFIX) +#else +#define ALM_PROTO(x) ALM_MAKE_PROTO(ALM_PREFIX, x) +#endif + +#define ALM_MAKE_PROTO_SFX(pfx, fn, sfx) __ALM_MAKE_PROTO_SFX(pfx, fn, sfx) +#define ALM_MAKE_PROTO(pfx, fn) __ALM_MAKE_PROTO(pfx, fn) + +#define __ALM_MAKE_PROTO_SFX(pfx, fn, sfx) pfx##_##fn##_##sfx +#define __ALM_MAKE_PROTO(pfx, fn) pfx##_##fn + +#define ALM_PROTO_OPT(x) clrmath_##x + +#define FN_PROTOTYPE(x) clrmath_##x +#define FN_PROTOTYPE_BAS64(x) clrmath_##x +#define FN_PROTOTYPE_REF(x) clrmath_##x + +#define EDOM 33 +#define ERANGE 34 + +#ifndef _HUGE_ENUF +// _HUGE_ENUF * _HUGE_ENUF must overflow +#define _HUGE_ENUF 1e+300 +#endif // _HUGE_ENUF + +#ifndef INFINITY +#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) +#endif // INFINITY + +#ifndef UNREFERENCED_PARAMETER +#define UNREFERENCED_PARAMETER(P) (void)(P) +#endif // UNREFERENCED_PARAMETER + +#endif // _LIBM_UTIL_H_ diff --git a/src/native/clrmath/inc/libm/libm_util_amd.h b/src/native/clrmath/inc/libm/libm_util_amd.h new file mode 100644 index 00000000000000..87943fd3cd288a --- /dev/null +++ b/src/native/clrmath/inc/libm/libm_util_amd.h @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef LIBM_UTIL_AMD_H_INCLUDED +#define LIBM_UTIL_AMD_H_INCLUDED 1 + +typedef float F32; +typedef unsigned int U32; +typedef int S32; + +typedef double F64; +typedef unsigned long long U64; +typedef long long S64; + +union UT32_ +{ + F32 f32; + U32 u32; +}; + +union UT64_ +{ + F64 f64; + U64 u64; +}; + +typedef union UT32_ UT32; +typedef union UT64_ UT64; + + + + +#define QNAN_MASK_32 0x00400000 +#define QNAN_MASK_64 0x0008000000000000ULL + +#define MULTIPLIER_SP 24 +#define MULTIPLIER_DP 53 + +/*Special numbers Float */ +#define POS_ONE_F32 0x3F800000 +#define NEG_ONE_F32 0xbf800000 +#define POS_ZERO_F32 0x00000000 +#define NEG_ZERO_F32 0x80000000 +#define POS_INF_F32 0x7F800000 +#define NEG_INF_F32 0xFF800000 +#define POS_SNAN_F32 0x7fb00000 +#define NEG_SNAN_F32 0xffb00000 +#define POS_QNAN_F32 0x7ff00000 +#define NEG_QNAN_F32 0xfff00000 +#define POS_PI_F32 0x40490fd8 +#define NEG_PI_F32 0xc0490fd8 + +/*Special numbers Double */ +#define POS_ONE_F64 0x3FF0000000000000 +#define NEG_ONE_F64 0xBFF0000000000000 +#define POS_ZERO_F64 0x0000000000000000 +#define NEG_ZERO_F64 0x8000000000000000 +#define POS_INF_F64 0x7ff0000000000000 +#define NEG_INF_F64 0xfff0000000000000 +#define POS_SNAN_F64 0x7FF4001000000000 +#define NEG_SNAN_F64 0xfff2000000000000 +#define POS_QNAN_F64 0x7ff87ff7fdedffff +#define NEG_QNAN_F64 0xfff2000000000000 +#define POS_PI_F64 0x40091EB851EB851F +#define NEG_PI_F64 0xc00921fb54442d18 + +static const double VAL_2PMULTIPLIER_DP = 9007199254740992.0; +static const double VAL_2PMMULTIPLIER_DP = 1.1102230246251565404236316680908e-16; +static const float VAL_2PMULTIPLIER_SP = 16777216.0F; +static const float VAL_2PMMULTIPLIER_SP = 5.9604645e-8F; + +/* Definitions for double functions on 64 bit machines */ +#define SIGNBIT_DP64 0x8000000000000000 +#define EXPBITS_DP64 0x7ff0000000000000ULL +#define MANTBITS_DP64 0x000fffffffffffff +#define ONEEXPBITS_DP64 0x3ff0000000000000 +#define TWOEXPBITS_DP64 0x4000000000000000 +#define HALFEXPBITS_DP64 0x3fe0000000000000 +#define IMPBIT_DP64 0x0010000000000000 +#define QNANBITPATT_DP64 0x7ff8000000000000ULL +#define INDEFBITPATT_DP64 0xfff8000000000000 +#define PINFBITPATT_DP64 0x7ff0000000000000 +#define NINFBITPATT_DP64 0xfff0000000000000 +#define EXPBIAS_DP64 1023 +#define EXPSHIFTBITS_DP64 52 +#define BIASEDEMIN_DP64 1 +#define EMIN_DP64 -1022 +#define BIASEDEMAX_DP64 2046 +#define EMAX_DP64 1023 +#define LAMBDA_DP64 1.0e300 +#define MANTLENGTH_DP64 53 +#define BASEDIGITS_DP64 15 +#define EXP_MIN 0xc0874910d52d3052 +#define EXP_MAX_DOUBLE 709.7822265625 + +/* These definitions, used by float functions, + are for both 32 and 64 bit machines */ +#define SIGNBIT_SP32 0x80000000 +#define EXPBITS_SP32 0x7f800000 +#define MANTBITS_SP32 0x007fffff +#define ONEEXPBITS_SP32 0x3f800000 +#define TWOEXPBITS_SP32 0x40000000 +#define HALFEXPBITS_SP32 0x3f000000 +#define IMPBIT_SP32 0x00800000 +#define QNANBITPATT_SP32 0x7fc00000 +#define INDEFBITPATT_SP32 0xffc00000 +#define PINFBITPATT_SP32 0x7f800000 +#define NINFBITPATT_SP32 0xff800000 +#define EXPBIAS_SP32 127 +#define EXPSHIFTBITS_SP32 23 +#define BIASEDEMIN_SP32 1 +#define EMIN_SP32 -126 +#define BIASEDEMAX_SP32 254 +#define EMAX_SP32 127 +#define LAMBDA_SP32 1.0e30 +#define MANTLENGTH_SP32 24 +#define BASEDIGITS_SP32 7 + +#define CLASS_SIGNALLING_NAN 1 +#define CLASS_QUIET_NAN 2 +#define CLASS_NEGATIVE_INFINITY 3 +#define CLASS_NEGATIVE_NORMAL_NONZERO 4 +#define CLASS_NEGATIVE_DENORMAL 5 +#define CLASS_NEGATIVE_ZERO 6 +#define CLASS_POSITIVE_ZERO 7 +#define CLASS_POSITIVE_DENORMAL 8 +#define CLASS_POSITIVE_NORMAL_NONZERO 9 +#define CLASS_POSITIVE_INFINITY 10 + +#define OLD_BITS_SP32(x) (*((unsigned int *)&x)) +#define OLD_BITS_DP64(x) (*((unsigned long long *)&x)) + + + // exception status set +#define MXCSR_ES_INEXACT 0x00000020 +#define MXCSR_ES_UNDERFLOW 0x00000010 +#define MXCSR_ES_OVERFLOW 0x00000008 +#define MXCSR_ES_DIVBYZERO 0x00000004 +#define MXCSR_ES_INVALID 0x00000001 + +#if defined(WINDOWS) +#define AMD_F_NONE 0x0 +#define AMD_F_OVERFLOW 0x00000001 +#define AMD_F_UNDERFLOW 0x00000002 +#define AMD_F_DIVBYZERO 0x00000004 +#define AMD_F_INVALID 0x00000008 +#define AMD_F_INEXACT 0x00000010 + +#else + +/* Processor-dependent floating-point status flags */ +#define AMD_F_NONE 0x0 +#define AMD_F_OVERFLOW 0x00000008 +#define AMD_F_UNDERFLOW 0x00000010 +#define AMD_F_DIVBYZERO 0x00000004 +#define AMD_F_INVALID 0x00000001 +#define AMD_F_INEXACT 0x00000020 +#endif +/* Processor-dependent floating-point precision-control flags */ +#define AMD_F_EXTENDED 0x00000300 +#define AMD_F_DOUBLE 0x00000200 +#define AMD_F_SINGLE 0x00000000 + +/* Processor-dependent floating-point rounding-control flags */ +#define AMD_F_RC_NEAREST 0x00000000 +#define AMD_F_RC_DOWN 0x00002000 +#define AMD_F_RC_UP 0x00004000 +#define AMD_F_RC_ZERO 0x00006000 + +#define INT_MIN (-2147483647 - 1) /* minimum (signed) int value */ +#define INT_MAX 2147483647 /* maximum (signed) int value */ + + + +/* Alternatives to the above functions which don't have + problems when using high optimization levels on gcc */ +#define GET_BITS_SP32(x, ux) \ + { \ + volatile union {float f; unsigned int i;} _bitsy; \ + _bitsy.f = (x); \ + ux = _bitsy.i; \ + } +#define PUT_BITS_SP32(ux, x) \ + { \ + volatile union {float f; unsigned int i;} _bitsy; \ + _bitsy.i = (ux); \ + x = _bitsy.f; \ + } + +#define GET_BITS_DP64(x, ux) \ + { \ + volatile union {double d; unsigned long long i;} _bitsy; \ + _bitsy.d = (x); \ + ux = _bitsy.i; \ + } +#define PUT_BITS_DP64(ux, x) \ + { \ + volatile union {double d; unsigned long long i;} _bitsy; \ + _bitsy.i = (ux); \ + x = _bitsy.d; \ + } + +#endif /* LIBM_UTIL_AMD_H_INCLUDED */ diff --git a/src/native/clrmath/src/libm_special.cpp b/src/native/clrmath/src/libm_special.cpp new file mode 100644 index 00000000000000..ffbd6e1c7ffa45 --- /dev/null +++ b/src/native/clrmath/src/libm_special.cpp @@ -0,0 +1,1247 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +static inline void __amd_raise_fp_exc(int flags) +{ + // Managed code doesn't support FP exceptions + UNREFERENCED_PARAMETER(flags); + + // if ((flags & AMD_F_UNDERFLOW) == AMD_F_UNDERFLOW) { + // double a = 0x1.0p-1022; + // __asm __volatile("mulsd %1, %0":"+x"(a) : "x"(a)); + // } + // if ((flags & AMD_F_OVERFLOW) == AMD_F_OVERFLOW) { + // double a = 0x1.fffffffffffffp1023; + // __asm __volatile("mulsd %1, %0":"+x"(a) : "x"(a)); + // } + // if ((flags & AMD_F_DIVBYZERO) == AMD_F_DIVBYZERO) { + // double a = 1.0, b = 0.0; + // __asm __volatile("divsd %1, %0":"+x"(a) : "x"(b)); + // } + // if ((flags & AMD_F_INVALID) == AMD_F_INVALID) { + // double a = 0.0; + // __asm __volatile("divsd %1, %0":"+x"(a) : "x"(a)); + // } +} + +double __amd_handle_error(const char* fname, int opcode, + unsigned long long value, int type, + int flags, int error, double arg1, + double arg2, int nargs) +{ + double z; + + //To avoid compiler warnings + //These variables are coming from the microsoft based exception handling routines. + //We just refer them and leave it. + UNREFERENCED_PARAMETER(fname); + UNREFERENCED_PARAMETER(opcode); + UNREFERENCED_PARAMETER(type); + UNREFERENCED_PARAMETER(error); + UNREFERENCED_PARAMETER(arg1); + UNREFERENCED_PARAMETER(arg2); + UNREFERENCED_PARAMETER(nargs); + PUT_BITS_DP64(value, z); + __amd_raise_fp_exc(flags); + return z; +} + +float __amd_handle_errorf(const char* fname, int opcode, + unsigned int value, int type, int flags, + int error, float arg1, float arg2, int nargs) +{ + float z; + + //To avoid compiler warnings + //These variables are coming from the microsoft based exception handling routines. + //We just refer them and leave it. + UNREFERENCED_PARAMETER(fname); + UNREFERENCED_PARAMETER(opcode); + UNREFERENCED_PARAMETER(type); + UNREFERENCED_PARAMETER(error); + UNREFERENCED_PARAMETER(arg1); + UNREFERENCED_PARAMETER(arg2); + UNREFERENCED_PARAMETER(nargs); + PUT_BITS_SP32(value, z); + __amd_raise_fp_exc(flags); + return z; +} + +double _sincos_special_underflow(double x, const char* name, _AMDLIBM_CODE code) +{ + UT64 xu; + xu.f64 = x; + return __amd_handle_error(name, code, xu.u64, _DOMAIN, + AMD_F_UNDERFLOW | AMD_F_INEXACT, EDOM, x, + 0.0, 1); +} + +float _sinf_cosf_special_underflow(float x, const char* name, _AMDLIBM_CODE code) +{ + UT32 xu; + xu.f32 = x; + return __amd_handle_errorf(name, code, xu.u32, _DOMAIN, + AMD_F_UNDERFLOW | AMD_F_INEXACT, EDOM, x, + 0.0, 1); +} + +double _sin_cos_special(double x, const char* name, _AMDLIBM_CODE code) +{ + UT64 xu; + xu.f64 = x; + if ((xu.u64 & EXPBITS_DP64) == EXPBITS_DP64) { + + // x is Inf or NaN + if ((xu.u64 & MANTBITS_DP64) == 0x0) { + + // x is Inf + xu.u64 = INDEFBITPATT_DP64; + return __amd_handle_error(name, code, xu.u64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, + 1); + } + else { + + // x is NaN +#if defined(WINDOWS) + return __amd_handle_error(name, code, + xu.u64 | QNAN_MASK_64, + _DOMAIN, 0, EDOM, x, 0.0, 1); + +#else /* */ + if (xu.u64 & QNAN_MASK_64) + return __amd_handle_error(name, code, xu.u64, + _DOMAIN, 0, EDOM, x, + 0.0, 1); + + else + return __amd_handle_error(name, code, + xu.u64 | QNAN_MASK_64, + _DOMAIN, + AMD_F_INVALID, EDOM, + x, 0.0, 1); + +#endif /* */ + } + } + return xu.f64; +} + +float _sinf_cosf_special(float x, const char* name, _AMDLIBM_CODE code) +{ + UT32 xu; + xu.f32 = x; + if ((xu.u32 & EXPBITS_SP32) == EXPBITS_SP32) { + + // x is Inf or NaN + if ((xu.u32 & MANTBITS_SP32) == 0x0) { + + // x is Inf + xu.u32 = INDEFBITPATT_SP32; + return __amd_handle_errorf(name, code, xu.u32, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, + 1); + } + else { + + // x is NaN +#if defined(WINDOWS) + return __amd_handle_errorf(name, code, + xu.u32 | QNAN_MASK_32, + _DOMAIN, 0, EDOM, x, 0.0, 1); + +#else /* */ + if (xu.u32 & QNAN_MASK_32) + return __amd_handle_errorf(name, code, xu.u32, + _DOMAIN, 0, EDOM, x, + 0.0, 1); + + else + return __amd_handle_errorf(name, code, + xu.u32 | + QNAN_MASK_32, + _DOMAIN, + AMD_F_INVALID, EDOM, + x, 0.0, 1); + +#endif /* */ + } + } + return xu.f32; +} + +double _sin_special_underflow(double x) +{ + return _sincos_special_underflow(x, "sin", __amd_sin); +} + +float _sinf_special(float x) +{ + return _sinf_cosf_special(x, "sinf", __amd_sin); +} + +double _sin_special(double x) +{ + return _sin_cos_special(x, "sin", __amd_sin); +} + +float _cosf_special(float x) +{ + return _sinf_cosf_special(x, "cosf", __amd_cos); +} + +double _cos_special(double x) +{ + return _sin_cos_special(x, "cos", __amd_cos); +} + +void _sincosf_special(float x, float* sy, float* cy) +{ + float xu = _sinf_cosf_special(x, "sincosf", __amd_sin); + *sy = xu; + *cy = xu; + return; +} + +void _sincos_special(double x, double* sy, double* cy) +{ + double xu = _sin_cos_special(x, "sincos", __amd_sin); + *sy = xu; + *cy = xu; + return; +} + +double _tan_special(double x) +{ + return _sin_cos_special(x, "tan", __amd_tan); +} + +float _tanf_special(float x) +{ + + UT32 xu; + xu.f32 = x; + if ((xu.u32 & ~SIGNBIT_SP32) < 0x39000000) { + __amd_handle_errorf("tanf", __amd_tan, xu.u32, _UNDERFLOW, AMD_F_UNDERFLOW, + ERANGE, x, 0.0F, 1); + } + return _sinf_cosf_special(x, "tanf", __amd_tan); +} + +float _tanhf_special(float x) +{ + UT32 xu; + xu.f32 = x; + return __amd_handle_errorf("tanhf", __amd_tanh, xu.u32, _UNDERFLOW, + AMD_F_INEXACT | AMD_F_UNDERFLOW, ERANGE, x, 0.0, 1); +} + +double _fabs_special(double x) +{ + UT64 xu; + xu.f64 = x; + + // x is NaN +#ifdef WINDOWS // + return __amd_handle_error("fabs", __amd_fabs, xu.u64 | QNAN_MASK_64, + _DOMAIN, 0, EDOM, x, 0.0, 1); + +#else /* */ + if (xu.u64 & QNAN_MASK_64) + return __amd_handle_error("fabs", __amd_fabs, + xu.u64 | QNAN_MASK_64, _DOMAIN, + AMD_F_NONE, EDOM, x, 0.0, 1); + + else + return __amd_handle_error("fabs", __amd_fabs, + xu.u64 | QNAN_MASK_64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + +#endif /* */ +} + +float _fabsf_special(float x) +{ + UT32 xu; + xu.f32 = x; + + // x is NaN +#ifdef WINDOWS // + return __amd_handle_errorf("fabsf", __amd_fabs, + xu.u32 | QNAN_MASK_32, _DOMAIN, 0, EDOM, + x, 0.0, 1); + +#else /* */ + if (xu.u32 & QNAN_MASK_32) + return __amd_handle_errorf("fabsf", __amd_fabs, + xu.u32 | QNAN_MASK_32, _DOMAIN, + AMD_F_NONE, EDOM, x, 0.0, 1); + + else + return __amd_handle_errorf("fabsf", __amd_fabs, + xu.u32 | QNAN_MASK_32, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + +#endif /* */ +} + +double _cbrt_special(double x) +{ + UT64 xu; + xu.f64 = x; + + // x is NaN + return __amd_handle_error("cbrt", __amd_cbrt, xu.u64 | QNAN_MASK_64, + _DOMAIN, 0, EDOM, x, 0.0, 1); +} + +float _cbrtf_special(float x) +{ + UT32 xu; + xu.f32 = x; + + // x is NaN + return __amd_handle_errorf("cbrtf", __amd_cbrt, + xu.u32 | QNAN_MASK_32, _DOMAIN, 0, EDOM, + x, 0.0F, 1); +} + +double _nearbyint_special(double x) +{ + UT64 checkbits; + checkbits.f64 = x; + + /* take care of nan or inf */ + if ((checkbits.u64 & EXPBITS_DP64) == EXPBITS_DP64) { + if ((checkbits.u64 & MANTBITS_DP64) == 0x0) { + + // x is Inf +#ifdef WINDOWS + return __amd_handle_error("nearbyint", + __amd_nearbyint, + checkbits.u64, _DOMAIN, + AMD_F_INVALID, EDOM, x, + 0.0, 1); + +#else /* */ + return __amd_handle_error("nearbyint", + __amd_nearbyint, + checkbits.u64, _DOMAIN, + AMD_F_NONE, EDOM, x, 0.0, 1); + +#endif /* */ + } + + else { + +#ifdef WINDOWS + return __amd_handle_error("nearbyint", + __amd_nearbyint, + checkbits.u64 | QNAN_MASK_64, + _DOMAIN, 0, EDOM, x, 0.0, 1); + +#else /* */ + if (checkbits.u64 & QNAN_MASK_64) + return __amd_handle_error("nearbyint", + __amd_nearbyint, + checkbits.u64 | + QNAN_MASK_64, _DOMAIN, + AMD_F_NONE, EDOM, x, + 0.0, 1); + + else + return __amd_handle_error("nearbyint", + __amd_nearbyint, + checkbits.u64 | + QNAN_MASK_64, _DOMAIN, + AMD_F_INVALID, EDOM, + x, 0.0, 1); + +#endif /* */ + } + } + + else + return x; +} + +#define EXP_X_NAN 1 +#define EXP_Y_ZERO 2 +#define EXP_Y_INF 3 +float _expf_special(float x, float y, U32 code) +{ + switch (code) { + case EXP_X_NAN: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("expf", __amd_exp, ym.u32, _DOMAIN, + 0, EDOM, x, 0.0, 1); + } + break; + case EXP_Y_ZERO: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("expf", __amd_exp, ym.u32, + _UNDERFLOW, + AMD_F_INEXACT | AMD_F_UNDERFLOW, + ERANGE, x, 0.0, 1); + } + break; + case EXP_Y_INF: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("expf", __amd_exp, ym.u32, + _OVERFLOW, + AMD_F_INEXACT | AMD_F_OVERFLOW, + ERANGE, x, 0.0, 1); + } + break; + } + return y; +} + +float _exp2f_special(float x, float y, U32 code) +{ + switch (code) { + case EXP_X_NAN: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("exp2f", __amd_exp2, ym.u32, + _DOMAIN, 0, EDOM, x, 0.0, 1); + } + break; + case EXP_Y_ZERO: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("exp2f", __amd_exp2, ym.u32, + _UNDERFLOW, + AMD_F_INEXACT | AMD_F_UNDERFLOW, + ERANGE, x, 0.0, 1); + } + break; + case EXP_Y_INF: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("exp2f", __amd_exp2, ym.u32, + _OVERFLOW, + AMD_F_INEXACT | AMD_F_OVERFLOW, + ERANGE, x, 0.0, 1); + } + break; + } + return y; +} + +float _exp10f_special(float x, float y, U32 code) +{ + switch (code) { + case EXP_X_NAN: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("exp10f", __amd_exp10, ym.u32, + _DOMAIN, 0, EDOM, x, 0.0, 1); + } + break; + case EXP_Y_ZERO: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("exp10f", __amd_exp10, ym.u32, + _UNDERFLOW, + AMD_F_INEXACT | AMD_F_UNDERFLOW, + ERANGE, x, 0.0, 1); + } + break; + case EXP_Y_INF: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("exp10f", __amd_exp10, ym.u32, + _OVERFLOW, + AMD_F_INEXACT | AMD_F_OVERFLOW, + ERANGE, x, 0.0, 1); + } + break; + } + return y; +} + +float _expm1f_special(float x, float y, U32 code) +{ + switch (code) { + case EXP_X_NAN: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("expm1f", __amd_expm1, ym.u32, + _DOMAIN, 0, EDOM, x, 0.0, 1); + } + break; + case EXP_Y_ZERO: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("expm1f", __amd_expm1, ym.u32, + _UNDERFLOW, + AMD_F_INEXACT | AMD_F_UNDERFLOW, + ERANGE, x, 0.0, 1); + } + break; + case EXP_Y_INF: + { + UT32 ym; + ym.u32 = 0; + ym.f32 = y; + __amd_handle_errorf("expm1f", __amd_expm1, ym.u32, + _OVERFLOW, + AMD_F_INEXACT | AMD_F_OVERFLOW, + ERANGE, x, 0.0, 1); + } + break; + } + return y; +} + +double _exp_special(double x, double y, U32 code) +{ + switch (code) { + case EXP_X_NAN: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("exp", __amd_exp, ym.u64, _DOMAIN, + 0, EDOM, x, 0.0, 1); + } + break; + case EXP_Y_ZERO: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("exp", __amd_exp, ym.u64, + _UNDERFLOW, + AMD_F_INEXACT | AMD_F_UNDERFLOW, + ERANGE, x, 0.0, 1); + } + break; + case EXP_Y_INF: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("exp", __amd_exp, ym.u64, _OVERFLOW, + AMD_F_INEXACT | AMD_F_OVERFLOW, + ERANGE, x, 0.0, 1); + } + break; + } + return y; +} + +double _exp2_special(double x, double y, U32 code) +{ + switch (code) { + case EXP_X_NAN: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("exp2", __amd_exp2, ym.u64, _DOMAIN, + 0, EDOM, x, 0.0, 1); + } + break; + case EXP_Y_ZERO: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("exp2", __amd_exp2, ym.u64, + _UNDERFLOW, + AMD_F_INEXACT | AMD_F_UNDERFLOW, + ERANGE, x, 0.0, 1); + } + break; + case EXP_Y_INF: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("exp2", __amd_exp2, ym.u64, + _OVERFLOW, + AMD_F_INEXACT | AMD_F_OVERFLOW, + ERANGE, x, 0.0, 1); + } + break; + } + return y; +} + +double _exp10_special(double x, double y, U32 code) +{ + switch (code) { + case EXP_X_NAN: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("exp10", __amd_exp10, ym.u64, + _DOMAIN, 0, EDOM, x, 0.0, 1); + } + break; + case EXP_Y_ZERO: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("exp10", __amd_exp10, ym.u64, + _UNDERFLOW, + AMD_F_INEXACT | AMD_F_UNDERFLOW, + ERANGE, x, 0.0, 1); + } + break; + case EXP_Y_INF: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("exp10", __amd_exp10, ym.u64, + _OVERFLOW, + AMD_F_INEXACT | AMD_F_OVERFLOW, + ERANGE, x, 0.0, 1); + } + break; + } + return y; +} + +double _expm1_special(double x, double y, U32 code) +{ + switch (code) { + case EXP_X_NAN: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("expm1", __amd_expm1, ym.u64, + _DOMAIN, 0, EDOM, x, 0.0, 1); + } + break; + case EXP_Y_ZERO: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("expm1", __amd_expm1, ym.u64, + _UNDERFLOW, + AMD_F_INEXACT | AMD_F_UNDERFLOW, + ERANGE, x, 0.0, 1); + } + break; + case EXP_Y_INF: + { + UT64 ym; + ym.f64 = y; + __amd_handle_error("expm1", __amd_expm1, ym.u64, + _OVERFLOW, + AMD_F_INEXACT | AMD_F_OVERFLOW, + ERANGE, x, 0.0, 1); + } + break; + } + return y; +} + +float _truncf_special(float x, float r) +{ + UT32 rm; + rm.u32 = 0; + rm.f32 = r; + __amd_handle_errorf("truncf", __amd_truncate, rm.u32, _DOMAIN, 0, EDOM, + x, 0.0, 1); + return r; +} + +double _trunc_special(double x, double r) +{ + UT64 rm; + rm.f64 = r; + __amd_handle_error("trunc", __amd_truncate, rm.u64, _DOMAIN, 0, EDOM, + x, 0.0, 1); + return r; +} + +double _round_special(double x, double r) +{ + UT64 rm; + rm.f64 = r; + __amd_handle_error("round", __amd_round, rm.u64, _DOMAIN, 0, EDOM, x, + 0.0, 1); + return r; +} + +#define LOG_X_ZERO 1 +#define LOG_X_NEG 2 +#define LOG_X_NAN 3 +static float _logf_special_common(float x, float y, U32 fnCode, + U32 errorCode, const char* name) +{ + switch (errorCode) { + case LOG_X_ZERO: + { + UT32 Y; + Y.f32 = y; + __amd_handle_errorf(name, fnCode, Y.u32, _SING, + AMD_F_DIVBYZERO, ERANGE, x, 0.0, 1); + } + break; + case LOG_X_NEG: + { + UT32 Y; + Y.f32 = y; + __amd_handle_errorf(name, fnCode, Y.u32, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + break; + case LOG_X_NAN: + { + +#ifdef WINDOWS + UT32 Y; + Y.f32 = y; + __amd_handle_errorf(name, fnCode, Y.u32, _DOMAIN, + AMD_F_NONE, EDOM, x, 0.0, 1); + +#else /* */ + return x + x; + +#endif /* */ + } + break; + } + return y; +} + +float _logf_special(float x, float y, U32 code) +{ + return _logf_special_common(x, y, __amd_log, code, "logf"); +} + +float _log10f_special(float x, float y, U32 code) +{ + return _logf_special_common(x, y, __amd_log10, code, "log10f"); +} + +float _log2f_special(float x, float y, U32 code) +{ + return _logf_special_common(x, y, __amd_log, code, "log2f"); +} + +float _log1pf_special(float x, float y, U32 code) +{ + return _logf_special_common(x, y, __amd_log1p, code, "log1pf"); +} + +static double _log_special_common(double x, double y, U32 fnCode, + U32 errorCode, const char* name) +{ + switch (errorCode) { + case LOG_X_ZERO: + { + UT64 Y; + Y.f64 = y; + __amd_handle_error(name, fnCode, Y.u64, _SING, + AMD_F_DIVBYZERO, ERANGE, x, 0.0, 1); + } + break; + case LOG_X_NEG: + { + UT64 Y; + Y.f64 = y; + __amd_handle_error(name, fnCode, Y.u64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + break; + case LOG_X_NAN: + { + +#ifdef WINDOWS + UT64 Y; + Y.f64 = y; + __amd_handle_error(name, fnCode, Y.u64, _DOMAIN, + AMD_F_NONE, EDOM, x, 0.0, 1); + +#else /* */ + return x + x; + +#endif /* */ + } + break; + } + return y; +} + +double _log_special(double x, double y, U32 code) +{ + return _log_special_common(x, y, __amd_log, code, "log"); +} + +double _log10_special(double x, double y, U32 code) +{ + return _log_special_common(x, y, __amd_log10, code, "log10"); +} + +double _log2_special(double x, double y, U32 code) +{ + return _log_special_common(x, y, __amd_log, code, "log2"); +} + +double _log1p_special(double x, double y, U32 code) +{ + return _log_special_common(x, y, __amd_log1p, code, "log1p"); +} + +float _fdimf_special(float x, float y, float r) +{ + UT32 rm; + rm.u32 = 0; + rm.f32 = r; + __amd_handle_errorf("fdimf", __amd_fdim, rm.u32, _DOMAIN, 0, EDOM, x, + y, 2); + return r; +} + +double _fdim_special(double x, double y, double r) +{ + UT64 rm; + rm.f64 = r; + __amd_handle_error("fdim", __amd_fdim, rm.u64, _DOMAIN, 0, EDOM, x, y, + 2); + return r; +} + +double _fmax_special(double x, double y) +{ + UT64 xu, yu; + xu.f64 = x; + yu.f64 = y; + if ((xu.u64 & ~SIGNBIT_DP64) > EXPBITS_DP64) { + if ((yu.u64 & ~SIGNBIT_DP64) > EXPBITS_DP64) +#ifdef WINDOWS + return __amd_handle_error("fmax", __amd_fmax, + yu.u64 | QNAN_MASK_64, + _DOMAIN, 0, EDOM, x, y, 2); + +#else /* */ + return __amd_handle_error("fmax", __amd_fmax, + yu.u64 | QNAN_MASK_64, + _DOMAIN, AMD_F_INVALID, + EDOM, x, y, 2); + +#endif /* */ + else + return __amd_handle_error("fmax", __amd_fmax, yu.u64, + _DOMAIN, 0, EDOM, x, y, 2); + } + return __amd_handle_error("fmax", __amd_fmax, xu.u64, _DOMAIN, 0, EDOM, + x, y, 2); +} + +float _fmaxf_special(float x, float y) +{ + UT32 xu, yu; + xu.f32 = x; + yu.f32 = y; + if ((xu.u32 & ~SIGNBIT_SP32) > EXPBITS_SP32) { + if ((yu.u32 & ~SIGNBIT_SP32) > EXPBITS_SP32) +#ifdef WINDOWS + return __amd_handle_errorf("fmaxf", __amd_fmax, + yu.u32 | QNAN_MASK_32, + _DOMAIN, 0, EDOM, x, y, 2); + +#else /* */ + return __amd_handle_errorf("fmaxf", __amd_fmax, + yu.u32 | QNAN_MASK_32, + _DOMAIN, AMD_F_INVALID, + EDOM, x, y, 2); + +#endif /* */ + else + return __amd_handle_errorf("fmaxf", __amd_fmax, yu.u32, + _DOMAIN, 0, EDOM, x, y, 2); + } + return __amd_handle_errorf("fmaxf", __amd_fmax, xu.u32, _DOMAIN, 0, + EDOM, x, y, 2); +} + +double _fmin_special(double x, double y) +{ + UT64 xu, yu; + xu.f64 = x; + yu.f64 = y; + if ((xu.u64 & ~SIGNBIT_DP64) > EXPBITS_DP64) { + if ((yu.u64 & ~SIGNBIT_DP64) > EXPBITS_DP64) +#ifdef WINDOWS + return __amd_handle_error("fmin", __amd_fmin, + yu.u64 | QNAN_MASK_64, + _DOMAIN, 0, EDOM, x, y, 2); + +#else /* */ + return __amd_handle_error("fmin", __amd_fmin, + yu.u64 | QNAN_MASK_64, + _DOMAIN, AMD_F_INVALID, + EDOM, x, y, 2); + +#endif /* */ + else + return __amd_handle_error("fmin", __amd_fmin, yu.u64, + _DOMAIN, 0, EDOM, x, y, 2); + } + return __amd_handle_error("fmin", __amd_fmax, xu.u64, _DOMAIN, 0, EDOM, + x, y, 2); +} + +float _fminf_special(float x, float y) +{ + UT32 xu, yu; + xu.f32 = x; + yu.f32 = y; + if ((xu.u32 & ~SIGNBIT_SP32) > EXPBITS_SP32) { + if ((yu.u32 & ~SIGNBIT_SP32) > EXPBITS_SP32) +#ifdef WINDOWS + return __amd_handle_errorf("fminf", __amd_fmin, + yu.u32 | QNAN_MASK_32, + _DOMAIN, 0, EDOM, x, y, 2); + +#else /* */ + return __amd_handle_errorf("fminf", __amd_fmin, + yu.u32 | QNAN_MASK_32, + _DOMAIN, AMD_F_INVALID, + EDOM, x, y, 2); + +#endif /* */ + else + return __amd_handle_errorf("fminf", __amd_fmin, yu.u32, + _DOMAIN, 0, EDOM, x, y, 2); + } + return __amd_handle_errorf("fminf", __amd_fmin, xu.u32, _DOMAIN, 0, + EDOM, x, y, 2); +} + +#define REMAINDER_X_NAN 1 +#define REMAINDER_Y_ZERO 2 +#define REMAINDER_X_DIVIDEND_INF 3 +float _remainderf_special(float x, float y, U32 errorCode) +{ + switch (errorCode) { + + /*All the three conditions are considered to be the same + for Windows. It might be different for Linux. + May have to come back for linux/WIndows. */ + case REMAINDER_Y_ZERO: + case REMAINDER_X_DIVIDEND_INF: + { + UT32 Y; + Y.f32 = y; + return __amd_handle_errorf("remainderf", + __amd_remainder, Y.u32, + _DOMAIN, AMD_F_INVALID, + EDOM, x, 0.0, 1); + } + break; + case REMAINDER_X_NAN: + { + +#ifdef WINDOWS + UT32 Y; + Y.f32 = y; + __amd_handle_errorf("remainderf", __amd_remainder, + Y.u32, _DOMAIN, AMD_F_INVALID, + EDOM, x, 0.0, 1); + +#else /* */ + return x + x; + +#endif /* */ + } + break; + } + return y; +} + +double _remainder_special(double x, double y, U32 errorCode) +{ + switch (errorCode) { + + /*All the three conditions are considered to be the same + for Windows. It might be different for Linux. + May have to come back for linux/WIndows. */ + case REMAINDER_Y_ZERO: + case REMAINDER_X_DIVIDEND_INF: + { + UT64 Y; + Y.f64 = y; + __amd_handle_error("remainder", __amd_remainder, Y.u64, + _DOMAIN, AMD_F_INVALID, EDOM, x, + 0.0, 1); + } + break; + case REMAINDER_X_NAN: + { + +#ifdef WINDOWS + UT64 Y; + Y.f64 = y; + __amd_handle_error("remainder", __amd_remainder, Y.u64, + _DOMAIN, AMD_F_INVALID, EDOM, x, + 0.0, 1); + +#else /* */ + return x + x; + +#endif /* */ + } + break; + } + return y; +} + +double _fmod_special(double x, double y, U32 errorCode) +{ + switch (errorCode) { + + /*All the three conditions are considered to be the same + for Windows. It might be different for Linux. + May have to come back for linux/WIndows. */ + case REMAINDER_Y_ZERO: + case REMAINDER_X_DIVIDEND_INF: + { + UT64 Y; + Y.f64 = y; + __amd_handle_error("fmod", __amd_fmod, Y.u64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + break; + case REMAINDER_X_NAN: + { + +#ifdef WINDOWS + UT64 Y; + Y.f64 = y; + __amd_handle_error("fmod", __amd_fmod, Y.u64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + +#else /* */ + return x + x; + +#endif /* */ + } + break; + } + return y; +} + +float _fmodf_special(float x, float y, U32 errorCode) +{ + switch (errorCode) { + + /*All the three conditions are considered to be the same + for Windows. It might be different for Linux. + May have to come back for linux/WIndows. */ + case REMAINDER_Y_ZERO: + case REMAINDER_X_DIVIDEND_INF: + { + UT32 Y; + Y.f32 = y; + __amd_handle_errorf("fmodf", __amd_fmod, Y.u32, + _DOMAIN, AMD_F_INVALID, EDOM, x, + 0.0, 1); + } + break; + case REMAINDER_X_NAN: + { + +#ifdef WINDOWS + UT32 Y; + Y.f32 = y; + __amd_handle_errorf("fmodf", __amd_fmod, Y.u32, + _DOMAIN, AMD_F_INVALID, EDOM, x, + 0.0, 1); + +#else /* */ + return x + x; + +#endif /* */ + } + break; + } + return y; +} + +#define POW_X_ONE_Y_SNAN 1 +#define POW_X_ZERO_Z_INF 2 +#define POW_X_NAN 3 +#define POW_Y_NAN 4 +#define POW_X_NAN_Y_NAN 5 +#define POW_X_NEG_Y_NOTINT 6 +#define POW_Z_ZERO 7 +#define POW_Z_DENORMAL 8 +#define POW_Z_INF 9 +double _pow_special(double x, double y, double z, U32 code) +{ + y = z; + switch (code) { + case POW_X_ONE_Y_SNAN: + { + UT64 zu; + zu.f64 = z; + __amd_handle_error("pow", __amd_pow, zu.u64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + break; + case POW_X_ZERO_Z_INF: + { + UT64 zu; + zu.f64 = z; + __amd_handle_error("pow", __amd_pow, zu.u64, _SING, + AMD_F_DIVBYZERO, ERANGE, x, 0.0, 1); + } + break; + case POW_X_NAN: + case POW_Y_NAN: + case POW_X_NAN_Y_NAN: + { + UT64 zu; + zu.f64 = z; + __amd_handle_error("pow", __amd_pow, zu.u64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + break; + case POW_X_NEG_Y_NOTINT: + { + UT64 zu; + zu.f64 = z; + __amd_handle_error("pow", __amd_pow, zu.u64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + break; + case POW_Z_ZERO: + case POW_Z_DENORMAL: + { + UT64 zu; + zu.f64 = z; + __amd_handle_error("pow", __amd_pow, zu.u64, + _UNDERFLOW, + AMD_F_INEXACT | AMD_F_UNDERFLOW, + ERANGE, x, 0.0, 1); + } + break; + case POW_Z_INF: + { + UT64 zu; + zu.f64 = z; + __amd_handle_error("pow", __amd_pow, zu.u64, _OVERFLOW, + AMD_F_INEXACT | AMD_F_OVERFLOW, + ERANGE, x, 0.0, 1); + } + break; + } + return z; +} + +float _powf_special(float x, float y, float z, U32 code) +{ + y = z; + switch (code) { + case POW_X_ONE_Y_SNAN: + { + UT32 zu; + zu.f32 = z; + __amd_handle_errorf("powf", __amd_pow, zu.u32, 0, + AMD_F_INVALID, 0, x, 0.0, 1); + } + break; + case POW_X_ZERO_Z_INF: + { + UT32 zu; + zu.f32 = z; + __amd_handle_errorf("powf", __amd_pow, zu.u32, _SING, + AMD_F_DIVBYZERO, ERANGE, x, 0.0, 1); + } + break; + case POW_X_NAN: + case POW_Y_NAN: + case POW_X_NAN_Y_NAN: + { + UT32 zu; + zu.f32 = z; + __amd_handle_errorf("powf", __amd_pow, zu.u32, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + break; + case POW_X_NEG_Y_NOTINT: + { + UT32 zu; + zu.f32 = z; + __amd_handle_errorf("powf", __amd_pow, zu.u32, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + break; + case POW_Z_ZERO: + { + UT32 zu; + zu.f32 = z; + __amd_handle_errorf("powf", __amd_pow, zu.u32, + _UNDERFLOW, + AMD_F_INEXACT | AMD_F_UNDERFLOW, + ERANGE, x, 0.0, 1); + } + break; + case POW_Z_INF: + { + UT32 zu; + zu.f32 = z; + __amd_handle_errorf("powf", __amd_pow, zu.u32, + _OVERFLOW, + AMD_F_INEXACT | AMD_F_OVERFLOW, + ERANGE, x, 0.0, 1); + } + break; + } + return z; +} diff --git a/src/native/clrmath/src/opt/cos.cpp b/src/native/clrmath/src/opt/cos.cpp new file mode 100644 index 00000000000000..fe69da42d12bf4 --- /dev/null +++ b/src/native/clrmath/src/opt/cos.cpp @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + /* + * ISO-IEC-10967-2: Elementary Numerical Functions + * Signature: + * double cos(double x) + * + * Spec: + * cos(0) = 1 + * cos(-0) = -1 + * cos(inf) = NaN + * cos(-inf) = NaN + * + * + ****************************************** + * Implementation Notes + * --------------------- + * + * checks for special cases + * if ( ux = infinity) raise overflow exception and return x + * if x is NaN then raise invalid FP operation exception and return x. + * + * 1. Argument reduction + * if |x| > 5e5 then + * __amd_remainder_piby2(x, &r, &rr, ®ion) + * else + * Argument reduction + * Let z = |x| * 2/pi + * z = dn + r, where dn = round(z) + * rhead = dn * pi/2_head + * rtail = dn * pi/2_tail + * r = z - dn = |x| - rhead - rtail + * expdiff = exp(dn) - exp(r) + * if(expdiff) > 15) + * rtail = |x| - dn*pi/2_tail2 + * r = |x| - dn*pi/2_head - dn*pi/2_tail1 - dn*pi/2_tail2 - (((rhead + rtail) - rhead )-rtail) + * rr = (|x| - rhead) - r + rtail + * + * 2. Polynomial approximation + * if(dn is even) + * rr = rr * r; + * x4 = x2 * x2; + * s = 0.5 * x2; + * t = s - 1.0; + * poly = x4 * (C1 + x2 * (C2 + x2 * (C3 + x2 * (C4 + x2 * (C5 + x2 * x6))))) + * r = (((1.0 + t) - s) - rr) + poly - t + * else + * x3 = x2 * r + * poly = S2 + (r2 * (S3 + (r2 * (S4 + (r2 * (S5 + S6 * r2)))))) + * r = r - ((x2 * (0.5*rr - x3 * poly)) - rr) - S1 * x3 + * if((sign + 1) & 2) + * return r + * else + * return -r; + + * if |x| < pi/4 && |x| > 2.0^(-13) + * r = 0.5 * x2; + * t = 1 - r; + * cos(x) = t + ((1.0 - t) - r) + (x*x * (x*x * C1 + C2*x*x + C3*x*x + * + C4*x*x +x*x*C5 + x*x*C6))) + * + * if |x| < 2.0^(-13) && |x| > 2.0^(-27) + * cos(x) = 1.0 - x*x*0.5;; + * + * else return 1.0 + ****************************************** + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_types.h" +#include "libm/libm_typehelper.h" +#include "libm/libm_poly.h" + +struct cos_data_t { + const double twobypi, piby2_1, piby2_1tail, invpi, pi, pi1, pi2; + const double piby2_2, piby2_2tail, ALM_SHIFT; + const double one_by_six; + double poly_sin[7]; + double poly_cos[6]; +}; + +static const cos_data_t cos_data = { + /* .twobypi = */ 0x1.45f306dc9c883p-1, + /* .piby2_1 = */ 0x1.921fb54400000p0, + /* .piby2_1tail = */ 0x1.0b4611a626331p-34, + /* .invpi = */ 0x1.45f306dc9c883p-2, + /* .pi = */ 0x1.921fb54442d18p1, + /* .pi1 = */ 0x1.921fb50000000p1, + /* .pi2 = */ 0x1.110b4611a6263p-25, + /* .piby2_2 = */ 0x1.0b4611a600000p-34, + /* .piby2_2tail = */ 0x1.3198a2e037073p-69, + /* .ALM_SHIFT = */ 0x1.8p+52, + /* .one_by_six = */ 0.1666666666666666666, + + /* + * Polynomial coefficients + */ + + /* .poly_sin = */ { + -0x1.5555555555555p-3, + 0x1.1111111110bb3p-7, + -0x1.a01a019e83e5cp-13, + 0x1.71de3796cde01p-19, + -0x1.ae600b42fdfa7p-26, + 0x1.5e0b2f9a43bb8p-33 + }, + /* .poly_cos = */ { + 0x1.5555555555555p-5, /* 0.0416667 */ + -0x1.6c16c16c16967p-10, /* -0.00138889 */ + 0x1.A01A019F4EC91p-16, /* 2.48016e-005 */ + -0x1.27E4FA17F667Bp-22, /* -2.75573e-007 */ + 0x1.1EEB690382EECp-29, /* 2.08761e-009 */ + -0x1.907DB47258AA7p-37 /* -1.13826e-011 */ + }, +}; + +void __amd_remainder_piby2(double x, double* r, double* rr, int* region); + +#define pi cos_data.pi +#define pi1 cos_data.pi1 +#define pi2 cos_data.pi2 +#define invpi cos_data.invpi +#define TwobyPI cos_data.twobypi +#define PIby2_1 cos_data.piby2_1 +#define PIby2_1tail cos_data.piby2_1tail +#define PIby2_2 cos_data.piby2_2 +#define PIby2_2tail cos_data.piby2_2tail +#define PIby4 0x3fe921fb54442d18 +#define FiveE6 0x415312d000000000 +#define ONE_BY_SIX cos_data.one_by_six +#define ALM_SHIFT cos_data.ALM_SHIFT + +#define S1 cos_data.poly_sin[0] +#define S2 cos_data.poly_sin[1] +#define S3 cos_data.poly_sin[2] +#define S4 cos_data.poly_sin[3] +#define S5 cos_data.poly_sin[4] +#define S6 cos_data.poly_sin[5] + +#define C1 cos_data.poly_cos[0] +#define C2 cos_data.poly_cos[1] +#define C3 cos_data.poly_cos[2] +#define C4 cos_data.poly_cos[3] +#define C5 cos_data.poly_cos[4] +#define C6 cos_data.poly_cos[5] + +#define SIGN_MASK 0x7FFFFFFFFFFFFFFF /* Infinity */ +#define INF 0x7ff0000000000000 +#define SIGN_MASK32 0x7FFFFFFF +#define COS_SMALL 0x3f20000000000000 /* 2.0^(-13) */ +#define COS_SMALLER 0X3e40000000000000 /* 2.0^(-27) */ + + +double _cos_special(double x); + +double +ALM_PROTO_OPT(cos)(double x) +{ + + double r, rr, poly, x2, t, s; + double rhead, rtail, x3, x4; + uint64_t uy; + int32_t region; + + /* cos(inf) = cos(-inf) = cos(NaN) = NaN */ + + uint64_t ux = asuint64(x); + + ux = ux & SIGN_MASK; + + if (unlikely((ux & SIGN_MASK) >= INF)) { + /* infinity or NaN */ + return _cos_special(x); + } + + if (ux > PIby4) { + + x = asdouble(ux); + /* ux > pi/4 */ + if (ux < FiveE6) { + /* reduce the argument to be in a range from -pi/4 to +pi/4 + by subtracting multiples of pi/2 */ + + r = TwobyPI * x; /* x * two_by_pi*/ + + int32_t xexp = ux >> 52; + + double npi2d = r + ALM_SHIFT; + + int64_t npi2 = asuint64(npi2d); + + npi2d -= ALM_SHIFT; + + rhead = x - npi2d * PIby2_1; + + rtail = npi2d * PIby2_1tail; + + r = rhead - rtail; + + uy = asuint64(r); + + int64_t expdiff = xexp - ((uy << 1) >> 53); + + region = (int32_t)npi2; + + if (expdiff > 15) { + + t = rhead; + + rtail = npi2d * PIby2_2; + + rhead = t - rtail; + + rtail = npi2d * PIby2_2tail - ((t - rhead) - rtail); + + r = rhead - rtail; + } + + rr = (rhead - r) - rtail; + } + else { + // Reduce x into range [-pi/4,pi/4] + __amd_remainder_piby2(x, &r, &rr, ®ion); + } + + x2 = r * r; + + if (region & 1) { + + /*if region 1 or 3 then sin region */ + + x3 = x2 * r; + + /* poly = S2 + (r2 * (S3 + (r2 * (S4 + (r2 * (S5 + S6 * r2)))))) */ + poly = POLY_EVAL_5(x2, S2, S3, S4, S5, S6); + + s = 0.5 * rr; + + poly = ((x2 * (s - x3 * poly)) - rr) - S1 * x3; + + r -= poly; /* r - ((r2 * (0.5 * rr - x3 * poly) - rr) - S1*r3 */ + + } + else { + /* region 0 or 2 do a cos calculation */ + rr = rr * r; + + x4 = x2 * x2; + + s = 0.5 * x2; + + t = s - 1.0; + + /* poly = x4 * (C1 + x2 * (C2 + x2 * (C3 + x2 * (C4 + x2 * (C5 + x2 * x6))))) */ + poly = x4 * POLY_EVAL_6(x2, C1, C2, C3, C4, C5, C6); + + r = (((1.0 + t) - s) - rr) + poly; + + r -= t; + + } + + region += 1; + + if (region & 2) { + + return -r; + + } + + return r; + } + else if (ux >= COS_SMALL) { + /* pi/4 > |x| > 2.0^(-13) */ + x2 = x * x; + + r = 0.5 * x2; + + t = 1 - r; + + s = t + ((1.0 - t) - r); + + return s + (x2 * (x2 * POLY_EVAL_6(x2, C1, C2, C3, C4, C5, C6))); + + } + else if (ux >= COS_SMALLER) { + /* if 2.0^(-13) > |x| > 2.0^(-27) */ + return 1.0 - (x * x * 0.5); + + } + + return 1.0; +} diff --git a/src/native/clrmath/src/opt/cosf.cpp b/src/native/clrmath/src/opt/cosf.cpp new file mode 100644 index 00000000000000..94e08409d9b10b --- /dev/null +++ b/src/native/clrmath/src/opt/cosf.cpp @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + /* + * ISO-IEC-10967-2: Elementary Numerical Functions + * Signature: + * float cosf(float x) + * + * Spec: + * cos(0) = 1 + * cos(-0) = -1 + * cos(inf) = NaN + * cos(-inf) = NaN + * + * + ****************************************** + * Implementation Notes + * --------------------- + * + * Checks for special cases + * if ( ux = infinity) raise overflow exception and return x + * if x is NaN then raise invalid FP operation exception and return x. + * + * 1. Argument reduction + * if |x| > 5e5 then + * __amd_remainder_piby2d2f((uint64_t)x, &r, ®ion) + * else + * Argument reduction + * Let z = |x| * 2/pi + * z = dn + r, where dn = round(z) + * rhead = dn * pi/2_head + * rtail = dn * pi/2_tail + * r = z - dn = |x| - rhead - rtail + * expdiff = exp(dn) - exp(r) + * if(expdiff) > 15) + * rtail = |x| - dn*pi/2_tail2 + * r = |x| - dn*pi/2_head - dn*pi/2_tail1 + * - dn*pi/2_tail2 - (((rhead + rtail) - rhead )-rtail) + * + * 2. Polynomial approximation + * if(dn is even) + * x4 = x2 * x2; + * s = 0.5 * x2; + * t = 1.0 - s; + * poly = x4 * (C1 + x2 * (C2 + x2 * (C3 + x2 * C4 ))) + * r = t + poly + * else + * x3 = x2 * r + * poly = x3 * (S1 + x2 * (S2 + x2 * (S3 + x2 * S4))) + * r = r + poly + * if((sign + 1) & 2) + * return r + * else + * return -r; + * + * if |x| < pi/4 && |x| > 2.0^(-13) + * r = 0.5 * x2; + * t = 1 - r; + * cos(x) = t + ((1.0 - t) - r) + (x*x * (x*x * C1 + C2*x*x + C3*x*x + * + C4*x*x +x*x*C5 + x*x*C6))) + * + * if |x| < 2.0^(-13) && |x| > 2.0^(-27) + * cos(x) = 1.0 - x*x*0.5;; + * + * else return 1.0 + ****************************************** + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_types.h" +#include "libm/libm_typehelper.h" +#include "libm/libm_poly.h" + +struct cosf_data_t { + const double piby2_1, piby2_1tail; + const double piby2_2, piby2_2tail; + const double twobypi, alm_shift; + double poly_sin[4]; + double poly_cos[4]; +}; + +static const cosf_data_t cosf_data = { + /* .piby2_1 = */ 0x1.921fb54400000p0, + /* .piby2_1tail = */ 0x1.0b4611a626331p-34, + /* .piby2_2 = */ 0x1.0b4611a600000p-34, + /* .piby2_2tail = */ 0x1.3198a2e037073p-69, + /* .twobypi = */ 0x1.45f306dc9c883p-1, + /* .alm_shift = */ 0x1.8p+52, + + /* + * Polynomial coefficients + */ + + /* .poly_sin = */ { + -0x1.5555555555555p-3, + 0x1.1111111110bb3p-7, + -0x1.a01a019e83e5cp-13, + 0x1.71de3796cde01p-19, + }, + /* .poly_cos = */ { + 0x1.5555555555555p-5, + -0x1.6c16c16c16967p-10, + 0x1.A01A019F4EC91p-16, + -0x1.27E4FA17F667Bp-22, + }, +}; + +void __amd_remainder_piby2d2f(uint64_t x, double* r, int* region); + +#define COSF_PIBY2_1 cosf_data.piby2_1 +#define COSF_PIBY2_1TAIL cosf_data.piby2_1tail +#define COSF_PIBY2_2 cosf_data.piby2_2 +#define COSF_PIBY2_2TAIL cosf_data.piby2_2tail +#define COSF_TWO_BY_PI cosf_data.twobypi +#define COSF_ALM_SHIFT cosf_data.alm_shift + +#define COSF_PIBY4 0x3F490FDB +#define COSF_FIVE_E6 0x4A989680 + +#define S1 cosf_data.poly_sin[0] +#define S2 cosf_data.poly_sin[1] +#define S3 cosf_data.poly_sin[2] +#define S4 cosf_data.poly_sin[3] + +#define C1 cosf_data.poly_cos[0] +#define C2 cosf_data.poly_cos[1] +#define C3 cosf_data.poly_cos[2] +#define C4 cosf_data.poly_cos[3] + +#define SIGN_MASK32 0x7FFFFFFF +#define COSF_SMALL 0x3C000000 /* 2.0^(-13) */ +#define COSF_SMALLER 0x39000000 /* 2.0^(-27) */ + + +float _cosf_special(float x); + +float +ALM_PROTO_OPT(cosf)(float x) +{ + + double r, rhead, rtail; + double xd, x2, x3, x4; + double poly, t, s; + uint64_t uy; + int32_t region; + + /* cos(inf) = cos(-inf) = cos(NaN) = NaN */ + + /* Get absolute value of input x */ + uint32_t ux = asuint32(x); + ux = ux & SIGN_MASK32; + + if (unlikely(ux >= PINFBITPATT_SP32)) { + /* infinity or NaN */ + return _cosf_special(x); + } + + /* ux > pi/4 */ + if (ux > COSF_PIBY4) { + + float ax = asfloat(ux); + + /* Convert input to double precision */ + xd = (double)ax; + + if (ux < COSF_FIVE_E6) { + /* reduce the argument to be in a range from -pi/4 to +pi/4 + by subtracting multiples of pi/2 */ + + /* |x| * 2/pi */ + r = COSF_TWO_BY_PI * xd; + + /* Get the exponent part */ + int32_t xexp = ux >> 23; + + /* dn = int(|x| * 2/pi) */ + double npi2d = r + COSF_ALM_SHIFT; + int64_t npi2 = asuint64(npi2d); + npi2d -= COSF_ALM_SHIFT; + + /* rhead = x - dn * pi/2_head */ + rhead = xd - npi2d * COSF_PIBY2_1; + + /* rtail = dn * pi/2_tail */ + rtail = npi2d * COSF_PIBY2_1TAIL; + + /* r = |x| * 2/pi - dn */ + r = rhead - rtail; + + uy = asuint64(r); + + /* expdiff = exponent(dn) - exponent(r) */ + int64_t expdiff = xexp - ((uy << 1) >> 53); + + region = (int32_t)npi2; + + if (expdiff > 15) { + + t = rhead; + + /* rtail = |x| - dn*pi/2_tail2 */ + rtail = npi2d * COSF_PIBY2_2; + + /* r = |x| - dn*pi/2_head - dn*pi/2_tail1 + * - dn*pi/2_tail2 - (((rhead + rtail) + * - rhead )-rtail) + */ + rhead = t - rtail; + rtail = npi2d * COSF_PIBY2_2TAIL - ((t - rhead) - rtail); + r = rhead - rtail; + } + + } + else { + + /* Reduce x into range [-pi/4,pi/4] */ + __amd_remainder_piby2d2f(asuint64(xd), &r, ®ion); + } + + x2 = r * r; + + if (region & 1) { + + /*if region 1 or 3 then sin region */ + x3 = x2 * r; + + /* poly = x3 * (S1 + x2 * (S2 + x2 * (S3 + x2 * S4))) */ + r += x3 * POLY_EVAL_3(x2, S1, S2, S3, S4); + + } + else { + + /* region 0 or 2 do a cos calculation */ + x4 = x2 * x2; + s = 0.5 * x2; + t = 1.0 - s; + + /* poly = x4 * (C1 + x2 * (C2 + x2 * (C3 + x2 * C4))) */ + poly = x4 * POLY_EVAL_3(x2, C1, C2, C3, C4); + r = t + poly; + + } + + region += 1; + + if (region & 2) { + + /* If region is 2 or 3, sign is -ve */ + return (float)-r; + + } + + return (float)(r); + } + /* if |x| < 2.0^(-13) && |x| > 2.0^(-27) */ + else if (ux >= COSF_SMALLER) { + + /* if |x| < pi/4 && |x| > 2.0^(-13) */ + if (ux >= COSF_SMALL) { + + /* r = 0.5 * x2 */ + x2 = x * x; + r = 0.5 * x2; + + t = 1 - r; + + /* cos(x) = t + ((1.0 - t) - r) + (x2 * (x2 * C1 + C2 * x2 + C3 * x2 + * + C4 * x2 )) + */ + s = t + ((1.0f - t) - r); + return (float)(s + (x2 * (x2 * POLY_EVAL_4(x2, C1, C2, C3, C4)))); + + } + + /* cos(x) = 1.0 - x * x* 0.5 */ + return (float)(1.0f - (x * x * 0.5)); + } + + return 1.0f; +} diff --git a/src/native/clrmath/src/opt/coshf.cpp b/src/native/clrmath/src/opt/coshf.cpp new file mode 100644 index 00000000000000..704748ac84673e --- /dev/null +++ b/src/native/clrmath/src/opt/coshf.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + /* + * ISO-IEC-10967-2: Elementary Numerical Functions + * Signature: + * float coshf(float x) + * + * Spec: + * coshf(|x| > 89.415985107421875) = Infinity + * coshf(Infinity) = infinity + * coshf(-Infinity) = infinity + * + ****************************************** + * Implementation Notes + * --------------------- + * + * cosh(x) = (exp(x) + exp(-x))/2 + * cosh(-x) = +cosh(x) + * + * checks for special cases + * if ( asint(x) > infinity) return x with overflow exception and + * return x. + * if x is NaN then raise invalid FP operation exception and return x. + * + * if x < 0x1p-11 + * coshf(x) = 1+1/2*x*x + * if 0x1p-11 < x < 0x1.62e43p-2 + * + * coshf = C0 + Y*Y*(C1 + Y*Y*(C2 + Y*Y*C3)) + * if 0x1.62e43p-2 < x < 8.5 + * coshf = 0.5 * (exp(x) + 1/exp(x)) + * + * if 8.5 < x < 0x1.62e42ep6 + * coshf = 0.5 * exp(x) + * + * if 0x1.62e42ep6 < x + * coshf = v/2 * exp(x - log(v)) where v = 0x1.0000e8p-1 + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_inlines.h" +#include "libm/libm_special.h" +#include "libm/libm_types.h" +#include "libm/libm_typehelper.h" +#include "libm/libm_poly.h" + +struct coshf_data_t { + uint32_t arg_max, infinity; + float logV, invV2, halfV, halfVm1; + float theeps, xc, ybar, wmax; + float poly_coshf[4]; + float half, t1; +}; + +static const coshf_data_t coshf_data = { + /* .arg_max = */ 0x42B2D4FC, + /* .infinity = */ 0x7F800000, + /* .logV = */ 0x1.62e6p-1, + /* .invV2 = */ 0x1.fffc6p-3, + /* .halfV = */ 0x1.0000e8p0, + /* .halfVm1 = */ 0x1.d0112ep-17, + /* .theeps = */ 0x1p-11, + /* .xc = */ 0x1.62e43p-2, + /* .ybar = */ 0x1.62e42ep6, + /* .wmax = */ 0x1.62e0f2p6, + /* .poly_coshf = */ { + 0x1p+0, + 0x1p-1, + 0x1.555466p-5, + 0x1.6da5e2p-10, + }, + /* .half = */ 0x1p-1, + /* .t1 = */ 0x1p-1, +}; + +#define C0 coshf_data.poly_coshf[0] +#define C1 coshf_data.poly_coshf[1] +#define C2 coshf_data.poly_coshf[2] +#define C3 coshf_data.poly_coshf[3] + +#define LOGV coshf_data.logV +#define INVV2 coshf_data.invV2 +#define HALFVM1 coshf_data.halfVm1 +#define HALFV coshf_data.halfV +#define THEEPS coshf_data.theeps +#define XC coshf_data.xc +#define YBAR coshf_data.ybar +#define WMAX coshf_data.wmax +#define HALF coshf_data.half +#define T1 coshf_data.t1 +#define INF coshf_date.infinity +#define ARG_MAX coshf_data.arg_max + +float ALM_PROTO_OPT(coshf)(float x) +{ + + float y, w, z, r, result; + + uint32_t ux = asuint32(x) & 0x7FFFFFFF; + + y = asfloat(ux); + + if (unlikely(ux > ARG_MAX)) { + + if (ux > PINFBITPATT_SP32) /* |x| is a NaN? */ { + + return x + x; + + } + else { + /* x is infinity */ + return FN_PROTOTYPE(copysignf)(INFINITY, x); + + } + + } + + if (ux <= asuint32(THEEPS)) { + + return (float)(1.0 + T1 * y * y); + + } + + if (ux > asuint32(8.5)) { + + if (y > YBAR) { + + w = y - LOGV; + + z = ALM_PROTO(expf)(w); + + return HALFV * z; + } + + z = ALM_PROTO(expf)(y); + + return (HALF * z); + } + else { + /*if(y > THEEPS)*/ + if (y > XC) { + + z = ALM_PROTO(expf)(y); + + return (float)(HALF * (z + (1.0 / z))); + } + + /* coshf(x) = C0 + y*y*(C1 + y*y*(C2 + y*y*C3)) */ + r = y * y; + + result = C0 + r * (C1 + r * (C2 + r * C3)); + + return (result); + + } + +} diff --git a/src/native/clrmath/src/opt/data/_exp_j_by_64.cpp b/src/native/clrmath/src/opt/data/_exp_j_by_64.cpp new file mode 100644 index 00000000000000..567a1af17b9127 --- /dev/null +++ b/src/native/clrmath/src/opt/data/_exp_j_by_64.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" + +/* + * expm1f data + * Generated for: + * (j/64.0) + * 2 ; for j = 0, 1, 2, ... 63 + */ +extern "C" const uint64_t __two_to_jby64[] = { + 0x3ff0000000000000, + 0x3fefec9a3e778061, + 0x3fefd9b0d3158574, + 0x3fefc74518759bc8, + 0x3fefb5586cf9890f, + 0x3fefa3ec32d3d1a2, + 0x3fef9301d0125b51, + 0x3fef829aaea92de0, + 0x3fef72b83c7d517b, + 0x3fef635beb6fcb75, + 0x3fef54873168b9aa, + 0x3fef463b88628cd6, + 0x3fef387a6e756238, + 0x3fef2b4565e27cdd, + 0x3fef1e9df51fdee1, + 0x3fef1285a6e4030b, + 0x3fef06fe0a31b715, + 0x3feefc08b26416ff, + 0x3feef1a7373aa9cb, + 0x3feee7db34e59ff7, + 0x3feedea64c123422, + 0x3feed60a21f72e2a, + 0x3feece086061892d, + 0x3feec6a2b5c13cd0, + 0x3feebfdad5362a27, + 0x3feeb9b2769d2ca7, + 0x3feeb42b569d4f82, + 0x3feeaf4736b527da, + 0x3feeab07dd485429, + 0x3feea76f15ad2148, + 0x3feea47eb03a5585, + 0x3feea23882552225, + 0x3feea09e667f3bcd, + 0x3fee9fb23c651a2f, + 0x3fee9f75e8ec5f74, + 0x3fee9feb564267c9, + 0x3feea11473eb0187, + 0x3feea2f336cf4e62, + 0x3feea589994cce13, + 0x3feea8d99b4492ed, + 0x3feeace5422aa0db, + 0x3feeb1ae99157736, + 0x3feeb737b0cdc5e5, + 0x3feebd829fde4e50, + 0x3feec49182a3f090, + 0x3feecc667b5de565, + 0x3feed503b23e255d, + 0x3feede6b5579fdbf, + 0x3feee89f995ad3ad, + 0x3feef3a2b84f15fb, + 0x3feeff76f2fb5e47, + 0x3fef0c1e904bc1d2, + 0x3fef199bdd85529c, + 0x3fef27f12e57d14b, + 0x3fef3720dcef9069, + 0x3fef472d4a07897c, + 0x3fef5818dcfba487, + 0x3fef69e603db3285, + 0x3fef7c97337b9b5f, + 0x3fef902ee78b3ff6, + 0x3fefa4afa2a490da, + 0x3fefba1bee615a27, + 0x3fefd0765b6e4540, + 0x3fefe7c1819e90d8, + +}; diff --git a/src/native/clrmath/src/opt/data/_exp_tbl_128_interleaved.data b/src/native/clrmath/src/opt/data/_exp_tbl_128_interleaved.data new file mode 100644 index 00000000000000..8ad3da3aaaec92 --- /dev/null +++ b/src/native/clrmath/src/opt/data/_exp_tbl_128_interleaved.data @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * tblsz_byln2 = (-1) x (log(2) / TABLE_SIZE); + * head = asuint64(tblsz_byln2) + * tail = tblsz_byln2 - head + */ + +/* Main Head Tail */ + {0x1.0000000000000p+0, 0x1.0000000000000p+0, 0x0.0000000000000p+0}, + {0x1.0163da9fb3335p+0, 0x1.0163da8000000p+0, 0x1.fb33356d84a66p-28}, + {0x1.02c9a3e778061p+0, 0x1.02c9a3c000000p+0, 0x1.3bc0307737be5p-27}, + {0x1.04315e86e7f85p+0, 0x1.04315e8000000p+0, 0x1.b9fe12f5ce3e8p-30}, + {0x1.059b0d3158574p+0, 0x1.059b0d0000000p+0, 0x1.8ac2ba1d73e2ap-27}, + {0x1.0706b29ddf6dep+0, 0x1.0706b28000000p+0, 0x1.ddf6ddc6dc404p-28}, + {0x1.0874518759bc8p+0, 0x1.0874518000000p+0, 0x1.d66f20230d7c8p-30}, + {0x1.09e3ecac6f383p+0, 0x1.09e3ec8000000p+0, 0x1.6379c1a290f03p-27}, + {0x1.0b5586cf9890fp+0, 0x1.0b5586c000000p+0, 0x1.f3121ec531724p-29}, + {0x1.0cc922b7247f7p+0, 0x1.0cc9228000000p+0, 0x1.b923fba03db83p-27}, + {0x1.0e3ec32d3d1a2p+0, 0x1.0e3ec30000000p+0, 0x1.69e8d10103a17p-27}, + {0x1.0fb66affed31bp+0, 0x1.0fb66ac000000p+0, 0x1.ff698d7919049p-27}, + {0x1.11301d0125b51p+0, 0x1.11301d0000000p+0, 0x1.25b50a4ebbf20p-32}, + {0x1.12abdc06c31ccp+0, 0x1.12abdc0000000p+0, 0x1.b0c72fee4aeb8p-30}, + {0x1.1429aaea92de0p+0, 0x1.1429aac000000p+0, 0x1.5496efd9a080dp-27}, + {0x1.15a98c8a58e51p+0, 0x1.15a98c8000000p+0, 0x1.4b1ca24901ab0p-29}, + {0x1.172b83c7d517bp+0, 0x1.172b83c000000p+0, 0x1.f545eb737df20p-30}, + {0x1.18af9388c8deap+0, 0x1.18af938000000p+0, 0x1.191bd3777ee18p-29}, + {0x1.1a35beb6fcb75p+0, 0x1.1a35be8000000p+0, 0x1.b7e5ba9e5b4c8p-27}, + {0x1.1bbe084045cd4p+0, 0x1.1bbe084000000p+0, 0x1.1734e6ac79c80p-34}, + {0x1.1d4873168b9aap+0, 0x1.1d48730000000p+0, 0x1.68b9aa7805b80p-28}, + {0x1.1ed5022fcd91dp+0, 0x1.1ed5020000000p+0, 0x1.7e6c8e5c40d00p-27}, + {0x1.2063b88628cd6p+0, 0x1.2063b88000000p+0, 0x1.8a3358ee3bac0p-30}, + {0x1.21f49917ddc96p+0, 0x1.21f4990000000p+0, 0x1.7ddc962552fd2p-28}, + {0x1.2387a6e756238p+0, 0x1.2387a6c000000p+0, 0x1.3ab11c3360fd7p-27}, + {0x1.251ce4fb2a63fp+0, 0x1.251ce4c000000p+0, 0x1.d9531f9ac155cp-27}, + {0x1.26b4565e27cddp+0, 0x1.26b4564000000p+0, 0x1.e27cdd257a674p-28}, + {0x1.284dfe1f56381p+0, 0x1.284dfe0000000p+0, 0x1.f5638096cf15cp-28}, + {0x1.29e9df51fdee1p+0, 0x1.29e9df4000000p+0, 0x1.1fdee12c25d16p-28}, + {0x1.2b87fd0dad990p+0, 0x1.2b87fd0000000p+0, 0x1.b5b31ffbbd48cp-29}, + {0x1.2d285a6e4030bp+0, 0x1.2d285a4000000p+0, 0x1.720185a0048ebp-27}, + {0x1.2ecafa93e2f56p+0, 0x1.2ecafa8000000p+0, 0x1.3e2f5611ca0f4p-28}, + {0x1.306fe0a31b715p+0, 0x1.306fe08000000p+0, 0x1.18db8a96f46adp-27}, + {0x1.32170fc4cd831p+0, 0x1.32170fc000000p+0, 0x1.3360c4d4e73c8p-30}, + {0x1.33c08b26416ffp+0, 0x1.33c08b0000000p+0, 0x1.320b7fa64e431p-27}, + {0x1.356c55f929ff1p+0, 0x1.356c55c000000p+0, 0x1.c94ff864a311ap-27}, + {0x1.371a7373aa9cbp+0, 0x1.371a734000000p+0, 0x1.9d54e5538a2a8p-27}, + {0x1.38cae6d05d866p+0, 0x1.38cae6c000000p+0, 0x1.05d86585a9cb0p-28}, + {0x1.3a7db34e59ff7p+0, 0x1.3a7db34000000p+0, 0x1.cb3fedd437924p-29}, + {0x1.3c32dc313a8e5p+0, 0x1.3c32dc0000000p+0, 0x1.89d47242000f9p-27}, + {0x1.3dea64c123422p+0, 0x1.3dea64c000000p+0, 0x1.2342235b41220p-32}, + {0x1.3fa4504ac801cp+0, 0x1.3fa4504000000p+0, 0x1.590037417ee04p-29}, + {0x1.4160a21f72e2ap+0, 0x1.4160a20000000p+0, 0x1.f72e29f84325cp-28}, + {0x1.431f5d950a897p+0, 0x1.431f5d8000000p+0, 0x1.50a896dc70444p-28}, + {0x1.44e086061892dp+0, 0x1.44e0860000000p+0, 0x1.8624b40c4dbd0p-30}, + {0x1.46a41ed1d0057p+0, 0x1.46a41ec000000p+0, 0x1.1d005772512f4p-28}, + {0x1.486a2b5c13cd0p+0, 0x1.486a2b4000000p+0, 0x1.c13cd013c1a3cp-28}, + {0x1.4a32af0d7d3dep+0, 0x1.4a32af0000000p+0, 0x1.afa7bcce5b178p-29}, + {0x1.4bfdad5362a27p+0, 0x1.4bfdad4000000p+0, 0x1.362a271d4397ap-28}, + {0x1.4dcb299fddd0dp+0, 0x1.4dcb298000000p+0, 0x1.fddd0d63b36f0p-28}, + {0x1.4f9b2769d2ca7p+0, 0x1.4f9b274000000p+0, 0x1.4e96535699ec6p-27}, + {0x1.516daa2cf6642p+0, 0x1.516daa0000000p+0, 0x1.67b320e0897a9p-27}, + {0x1.5342b569d4f82p+0, 0x1.5342b54000000p+0, 0x1.4ea7c0ef8541ep-27}, + {0x1.551a4ca5d920fp+0, 0x1.551a4c8000000p+0, 0x1.2ec9076297631p-27}, + {0x1.56f4736b527dap+0, 0x1.56f4734000000p+0, 0x1.5a93ed3376580p-27}, + {0x1.58d12d497c7fdp+0, 0x1.58d12d4000000p+0, 0x1.2f8ffa4a57858p-29}, + {0x1.5ab07dd485429p+0, 0x1.5ab07dc000000p+0, 0x1.48542958c9302p-28}, + {0x1.5c9268a5946b7p+0, 0x1.5c92688000000p+0, 0x1.2ca35b80e258ep-27}, + {0x1.5e76f15ad2148p+0, 0x1.5e76f14000000p+0, 0x1.ad21486e9be4cp-28}, + {0x1.605e1b976dc09p+0, 0x1.605e1b8000000p+0, 0x1.76dc08b076f5ap-28}, + {0x1.6247eb03a5585p+0, 0x1.6247eb0000000p+0, 0x1.d2ac258f87d00p-31}, + {0x1.6434634ccc320p+0, 0x1.6434634000000p+0, 0x1.99863f8edf0e4p-29}, + {0x1.6623882552225p+0, 0x1.6623880000000p+0, 0x1.2a91124893ecfp-27}, + {0x1.68155d44ca973p+0, 0x1.68155d4000000p+0, 0x1.32a5cc20715c8p-30}, + {0x1.6a09e667f3bcdp+0, 0x1.6a09e64000000p+0, 0x1.3f9de6484597ep-27}, + {0x1.6c012750bdabfp+0, 0x1.6c01274000000p+0, 0x1.0bdabeed76a9ap-28}, + {0x1.6dfb23c651a2fp+0, 0x1.6dfb23c000000p+0, 0x1.9468bbc8838b0p-30}, + {0x1.6ff7df9519484p+0, 0x1.6ff7df8000000p+0, 0x1.519483cf87e1cp-28}, + {0x1.71f75e8ec5f74p+0, 0x1.71f75e8000000p+0, 0x1.d8bee7ba46e20p-29}, + {0x1.73f9a48a58174p+0, 0x1.73f9a48000000p+0, 0x1.4b02e77ab9348p-29}, + {0x1.75feb564267c9p+0, 0x1.75feb54000000p+0, 0x1.2133e45fb74d5p-27}, + {0x1.780694fde5d3fp+0, 0x1.780694c000000p+0, 0x1.ef2e9fb0cd701p-27}, + {0x1.7a11473eb0187p+0, 0x1.7a11470000000p+0, 0x1.f580c36bea881p-27}, + {0x1.7c1ed0130c132p+0, 0x1.7c1ed00000000p+0, 0x1.30c1327c49334p-28}, + {0x1.7e2f336cf4e62p+0, 0x1.7e2f334000000p+0, 0x1.67a731082e816p-27}, + {0x1.80427543e1a12p+0, 0x1.8042754000000p+0, 0x1.f0d08db06f340p-31}, + {0x1.82589994cce13p+0, 0x1.8258998000000p+0, 0x1.4cce128acf88ap-28}, + {0x1.8471a4623c7adp+0, 0x1.8471a44000000p+0, 0x1.11e3d667297b6p-27}, + {0x1.868d99b4492edp+0, 0x1.868d998000000p+0, 0x1.a2497640720edp-27}, + {0x1.88ac7d98a6699p+0, 0x1.88ac7d8000000p+0, 0x1.8a669966530bcp-28}, + {0x1.8ace5422aa0dbp+0, 0x1.8ace540000000p+0, 0x1.15506dadd3e2bp-27}, + {0x1.8cf3216b5448cp+0, 0x1.8cf3214000000p+0, 0x1.5aa245f79550ep-27}, + {0x1.8f1ae99157736p+0, 0x1.8f1ae98000000p+0, 0x1.1577362b98274p-28}, + {0x1.9145b0b91ffc6p+0, 0x1.9145b08000000p+0, 0x1.c8ffe2c4530dap-27}, + {0x1.93737b0cdc5e5p+0, 0x1.93737b0000000p+0, 0x1.9b8bc9e8a0388p-29}, + {0x1.95a44cbc8520fp+0, 0x1.95a44c8000000p+0, 0x1.e4290774da41bp-27}, + {0x1.97d829fde4e50p+0, 0x1.97d829c000000p+0, 0x1.ef2727c5cf490p-27}, + {0x1.9a0f170ca07bap+0, 0x1.9a0f170000000p+0, 0x1.940f737462138p-29}, + {0x1.9c49182a3f090p+0, 0x1.9c49180000000p+0, 0x1.51f8480e3e236p-27}, + {0x1.9e86319e32323p+0, 0x1.9e86318000000p+0, 0x1.e323231824ca8p-28}, + {0x1.a0c667b5de565p+0, 0x1.a0c6678000000p+0, 0x1.aef2b2594d6d4p-27}, + {0x1.a309bec4a2d33p+0, 0x1.a309bec000000p+0, 0x1.28b4cd6305c80p-30}, + {0x1.a5503b23e255dp+0, 0x1.a5503b0000000p+0, 0x1.1f12ae45a1225p-27}, + {0x1.a799e1330b358p+0, 0x1.a799e10000000p+0, 0x1.9859ac3796fd9p-27}, + {0x1.a9e6b5579fdbfp+0, 0x1.a9e6b54000000p+0, 0x1.79fdbf43eb244p-28}, + {0x1.ac36bbfd3f37ap+0, 0x1.ac36bbc000000p+0, 0x1.e9f9bce06dcb3p-27}, + {0x1.ae89f995ad3adp+0, 0x1.ae89f98000000p+0, 0x1.5ad3ad5e8734ep-28}, + {0x1.b0e07298db666p+0, 0x1.b0e0728000000p+0, 0x1.8db66590842acp-28}, + {0x1.b33a2b84f15fbp+0, 0x1.b33a2b8000000p+0, 0x1.3c57ebdaff438p-30}, + {0x1.b59728de5593ap+0, 0x1.b59728c000000p+0, 0x1.e559398e38812p-28}, + {0x1.b7f76f2fb5e47p+0, 0x1.b7f76f0000000p+0, 0x1.7daf237553d84p-27}, + {0x1.ba5b030a1064ap+0, 0x1.ba5b030000000p+0, 0x1.420c930819678p-29}, + {0x1.bcc1e904bc1d2p+0, 0x1.bcc1e90000000p+0, 0x1.2f074891ee840p-30}, + {0x1.bf2c25bd71e09p+0, 0x1.bf2c258000000p+0, 0x1.eb8f0442046b8p-27}, + {0x1.c199bdd85529cp+0, 0x1.c199bdc000000p+0, 0x1.85529c2220cb2p-28}, + {0x1.c40ab5fffd07ap+0, 0x1.c40ab5c000000p+0, 0x1.ffe83d368a6fcp-27}, + {0x1.c67f12e57d14bp+0, 0x1.c67f12c000000p+0, 0x1.2be8a5a5109c0p-27}, + {0x1.c8f6d9406e7b5p+0, 0x1.c8f6d94000000p+0, 0x1.b9ed446b2f100p-34}, + {0x1.cb720dcef9069p+0, 0x1.cb720dc000000p+0, 0x1.df20d22a0797cp-29}, + {0x1.cdf0b555dc3fap+0, 0x1.cdf0b54000000p+0, 0x1.5dc3f9c44f896p-28}, + {0x1.d072d4a07897cp+0, 0x1.d072d48000000p+0, 0x1.03c4bdc687918p-27}, + {0x1.d2f87080d89f2p+0, 0x1.d2f8708000000p+0, 0x1.b13e315bc2480p-33}, + {0x1.d5818dcfba487p+0, 0x1.d5818dc000000p+0, 0x1.f7490e4bb40b4p-29}, + {0x1.d80e316c98398p+0, 0x1.d80e314000000p+0, 0x1.64c1cbddc27cfp-27}, + {0x1.da9e603db3285p+0, 0x1.da9e600000000p+0, 0x1.ed9942b84600dp-27}, + {0x1.dd321f301b460p+0, 0x1.dd321f0000000p+0, 0x1.80da3025b4aefp-27}, + {0x1.dfc97337b9b5fp+0, 0x1.dfc9730000000p+0, 0x1.bdcdaf5cb4656p-27}, + {0x1.e264614f5a129p+0, 0x1.e264614000000p+0, 0x1.eb4251424ec40p-29}, + {0x1.e502ee78b3ff6p+0, 0x1.e502ee4000000p+0, 0x1.c59ffb139e898p-27}, + {0x1.e7a51fbc74c83p+0, 0x1.e7a51f8000000p+0, 0x1.e3a641a5aa459p-27}, + {0x1.ea4afa2a490dap+0, 0x1.ea4afa0000000p+0, 0x1.52486cc2c7b9dp-27}, + {0x1.ecf482d8e67f1p+0, 0x1.ecf482c000000p+0, 0x1.8e67f08db0312p-28}, + {0x1.efa1bee615a27p+0, 0x1.efa1bec000000p+0, 0x1.30ad13bb8fe91p-27}, + {0x1.f252b376bba97p+0, 0x1.f252b34000000p+0, 0x1.b5dd4ba7434b8p-27}, + {0x1.f50765b6e4540p+0, 0x1.f507658000000p+0, 0x1.b722a033a7c26p-27}, + {0x1.f7bfdad9cbe14p+0, 0x1.f7bfdac000000p+0, 0x1.9cbe138913b4cp-28}, + {0x1.fa7c1819e90d8p+0, 0x1.fa7c180000000p+0, 0x1.9e90d82e90a7ep-28}, + {0x1.fd3c22b8f71f1p+0, 0x1.fd3c228000000p+0, 0x1.c7b8f884badd2p-27}, + +/* Local Variables: */ +/* mode: c */ +/* comment-column: 0 */ +/* End: */ diff --git a/src/native/clrmath/src/opt/data/_exp_tbl_64_interleaved.data b/src/native/clrmath/src/opt/data/_exp_tbl_64_interleaved.data new file mode 100644 index 00000000000000..6ec43872ebeda1 --- /dev/null +++ b/src/native/clrmath/src/opt/data/_exp_tbl_64_interleaved.data @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * tblsz_byln2 = (-1) x (log(2) / TABLE_SIZE); + * head = asuint64(tblsz_byln2) + * tail = tblsz_byln2 - head + */ +/* Main Head Tail */ + {0x1.0000000000000p+0, 0x1.0000000000000p+0, 0x0.0000000000000p+0}, + {0x1.02c9a3e778061p+0, 0x1.02c9a30000000p+0, 0x1.cef00c1dcdef9p-25}, + {0x1.059b0d3158574p+0, 0x1.059b0d0000000p+0, 0x1.8ac2ba1d73e2ap-27}, + {0x1.0874518759bc8p+0, 0x1.0874510000000p+0, 0x1.0eb37901186bep-25}, + {0x1.0b5586cf9890fp+0, 0x1.0b55860000000p+0, 0x1.9f3121ec53172p-25}, + {0x1.0e3ec32d3d1a2p+0, 0x1.0e3ec30000000p+0, 0x1.69e8d10103a17p-27}, + {0x1.11301d0125b51p+0, 0x1.11301d0000000p+0, 0x1.25b50a4ebbf1ap-32}, + {0x1.1429aaea92de0p+0, 0x1.1429aa0000000p+0, 0x1.d525bbf668203p-25}, + {0x1.172b83c7d517bp+0, 0x1.172b830000000p+0, 0x1.8faa2f5b9bef9p-25}, + {0x1.1a35beb6fcb75p+0, 0x1.1a35be0000000p+0, 0x1.6df96ea796d31p-25}, + {0x1.1d4873168b9aap+0, 0x1.1d48730000000p+0, 0x1.68b9aa7805b80p-28}, + {0x1.2063b88628cd6p+0, 0x1.2063b80000000p+0, 0x1.0c519ac771dd6p-25}, + {0x1.2387a6e756238p+0, 0x1.2387a60000000p+0, 0x1.ceac470cd83f5p-25}, + {0x1.26b4565e27cddp+0, 0x1.26b4560000000p+0, 0x1.789f37495e99cp-26}, + {0x1.29e9df51fdee1p+0, 0x1.29e9df0000000p+0, 0x1.47f7b84b09745p-26}, + {0x1.2d285a6e4030bp+0, 0x1.2d285a0000000p+0, 0x1.b900c2d002475p-26}, + {0x1.306fe0a31b715p+0, 0x1.306fe00000000p+0, 0x1.4636e2a5bd1abp-25}, + {0x1.33c08b26416ffp+0, 0x1.33c08b0000000p+0, 0x1.320b7fa64e430p-27}, + {0x1.371a7373aa9cbp+0, 0x1.371a730000000p+0, 0x1.ceaa72a9c5154p-26}, + {0x1.3a7db34e59ff7p+0, 0x1.3a7db30000000p+0, 0x1.3967fdba86f24p-26}, + {0x1.3dea64c123422p+0, 0x1.3dea640000000p+0, 0x1.82468446b6824p-25}, + {0x1.4160a21f72e2ap+0, 0x1.4160a20000000p+0, 0x1.f72e29f84325bp-28}, + {0x1.44e086061892dp+0, 0x1.44e0860000000p+0, 0x1.8624b40c4dbd0p-30}, + {0x1.486a2b5c13cd0p+0, 0x1.486a2b0000000p+0, 0x1.704f3404f068ep-26}, + {0x1.4bfdad5362a27p+0, 0x1.4bfdad0000000p+0, 0x1.4d8a89c750e5ep-26}, + {0x1.4f9b2769d2ca7p+0, 0x1.4f9b270000000p+0, 0x1.a74b29ab4cf62p-26}, + {0x1.5342b569d4f82p+0, 0x1.5342b50000000p+0, 0x1.a753e077c2a0fp-26}, + {0x1.56f4736b527dap+0, 0x1.56f4730000000p+0, 0x1.ad49f699bb2c0p-26}, + {0x1.5ab07dd485429p+0, 0x1.5ab07d0000000p+0, 0x1.a90a852b19260p-25}, + {0x1.5e76f15ad2148p+0, 0x1.5e76f10000000p+0, 0x1.6b48521ba6f93p-26}, + {0x1.6247eb03a5585p+0, 0x1.6247eb0000000p+0, 0x1.d2ac258f87d03p-31}, + {0x1.6623882552225p+0, 0x1.6623880000000p+0, 0x1.2a91124893ecfp-27}, + {0x1.6a09e667f3bcdp+0, 0x1.6a09e60000000p+0, 0x1.9fcef32422cbep-26}, + {0x1.6dfb23c651a2fp+0, 0x1.6dfb230000000p+0, 0x1.8ca345de441c5p-25}, + {0x1.71f75e8ec5f74p+0, 0x1.71f75e0000000p+0, 0x1.1d8bee7ba46e1p-25}, + {0x1.75feb564267c9p+0, 0x1.75feb50000000p+0, 0x1.9099f22fdba6ap-26}, + {0x1.7a11473eb0187p+0, 0x1.7a11470000000p+0, 0x1.f580c36bea881p-27}, + {0x1.7e2f336cf4e62p+0, 0x1.7e2f330000000p+0, 0x1.b3d398841740ap-26}, + {0x1.82589994cce13p+0, 0x1.8258990000000p+0, 0x1.2999c25159f11p-25}, + {0x1.868d99b4492edp+0, 0x1.868d990000000p+0, 0x1.68925d901c83bp-25}, + {0x1.8ace5422aa0dbp+0, 0x1.8ace540000000p+0, 0x1.15506dadd3e2ap-27}, + {0x1.8f1ae99157736p+0, 0x1.8f1ae90000000p+0, 0x1.22aee6c57304ep-25}, + {0x1.93737b0cdc5e5p+0, 0x1.93737b0000000p+0, 0x1.9b8bc9e8a0387p-29}, + {0x1.97d829fde4e50p+0, 0x1.97d8290000000p+0, 0x1.fbc9c9f173d24p-25}, + {0x1.9c49182a3f090p+0, 0x1.9c49180000000p+0, 0x1.51f8480e3e235p-27}, + {0x1.a0c667b5de565p+0, 0x1.a0c6670000000p+0, 0x1.6bbcac96535b5p-25}, + {0x1.a5503b23e255dp+0, 0x1.a5503b0000000p+0, 0x1.1f12ae45a1224p-27}, + {0x1.a9e6b5579fdbfp+0, 0x1.a9e6b50000000p+0, 0x1.5e7f6fd0fac90p-26}, + {0x1.ae89f995ad3adp+0, 0x1.ae89f90000000p+0, 0x1.2b5a75abd0e69p-25}, + {0x1.b33a2b84f15fbp+0, 0x1.b33a2b0000000p+0, 0x1.09e2bf5ed7fa1p-25}, + {0x1.b7f76f2fb5e47p+0, 0x1.b7f76f0000000p+0, 0x1.7daf237553d84p-27}, + {0x1.bcc1e904bc1d2p+0, 0x1.bcc1e90000000p+0, 0x1.2f074891ee83dp-30}, + {0x1.c199bdd85529cp+0, 0x1.c199bd0000000p+0, 0x1.b0aa538444196p-25}, + {0x1.c67f12e57d14bp+0, 0x1.c67f120000000p+0, 0x1.cafa29694426fp-25}, + {0x1.cb720dcef9069p+0, 0x1.cb720d0000000p+0, 0x1.9df20d22a0797p-25}, + {0x1.d072d4a07897cp+0, 0x1.d072d40000000p+0, 0x1.40f12f71a1e45p-25}, + {0x1.d5818dcfba487p+0, 0x1.d5818d0000000p+0, 0x1.9f7490e4bb40bp-25}, + {0x1.da9e603db3285p+0, 0x1.da9e600000000p+0, 0x1.ed9942b84600dp-27}, + {0x1.dfc97337b9b5fp+0, 0x1.dfc9730000000p+0, 0x1.bdcdaf5cb4656p-27}, + {0x1.e502ee78b3ff6p+0, 0x1.e502ee0000000p+0, 0x1.e2cffd89cf44cp-26}, + {0x1.ea4afa2a490dap+0, 0x1.ea4afa0000000p+0, 0x1.52486cc2c7b9dp-27}, + {0x1.efa1bee615a27p+0, 0x1.efa1be0000000p+0, 0x1.cc2b44eee3fa4p-25}, + {0x1.f50765b6e4540p+0, 0x1.f507650000000p+0, 0x1.6dc8a80ce9f09p-25}, + {0x1.fa7c1819e90d8p+0, 0x1.fa7c180000000p+0, 0x1.9e90d82e90a7ep-28}, + + +/* Local Variables: */ +/* mode: c */ +/* comment-column: 0 */ +/* End: */ diff --git a/src/native/clrmath/src/opt/data/_log_data.cpp b/src/native/clrmath/src/opt/data/_log_data.cpp new file mode 100644 index 00000000000000..1af06a46669b9f --- /dev/null +++ b/src/native/clrmath/src/opt/data/_log_data.cpp @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" + +struct logf_table { + uint32_t f_inv, f_128_head, f_128_tail; +}; + +extern "C" logf_table logf_lookup[] = { + {0x40000000, 0x0, 0x0}, + {0x3fff00ff, 0x3b7f8000, 0x32aa2b11}, + {0x3ffe03f8, 0x3bff0000, 0x3429ac42}, + {0x3ffd08e5, 0x3c3ee000, 0x350ebf02}, + {0x3ffc0fc1, 0x3c7e0000, 0x35a8b0fc}, + {0x3ffb1885, 0x3c9e7000, 0x36244347}, + {0x3ffa232d, 0x3cbdc000, 0x368d83eb}, + {0x3ff92fb2, 0x3cdcf000, 0x36e013d8}, + {0x3ff83e10, 0x3cfc1000, 0x361b0e78}, + {0x3ff74e40, 0x3d0d8000, 0x36d98924}, + {0x3ff6603e, 0x3d1cf000, 0x3687b9ff}, + {0x3ff57404, 0x3d2c5000, 0x36375f92}, + {0x3ff4898d, 0x3d3ba000, 0x3631ec66}, + {0x3ff3a0d5, 0x3d4ae000, 0x36830ec9}, + {0x3ff2b9d6, 0x3d5a1000, 0x36dd7119}, + {0x3ff1d48c, 0x3d693000, 0x3735c56e}, + {0x3ff0f0f1, 0x3d785000, 0x35c30046}, + {0x3ff00f01, 0x3d83a000, 0x37cc1acc}, + {0x3fef2eb7, 0x3d8b2000, 0x379b7752}, + {0x3fee500f, 0x3d929000, 0x37fb1785}, + {0x3fed7304, 0x3d9a0000, 0x37ebcb0e}, + {0x3fec9791, 0x3da17000, 0x375cbea6}, + {0x3febbdb3, 0x3da8d000, 0x37839f83}, + {0x3feae564, 0x3db03000, 0x36b1526f}, + {0x3fea0ea1, 0x3db78000, 0x37528ae5}, + {0x3fe93965, 0x3dbed000, 0x36ecdaf6}, + {0x3fe865ac, 0x3dc61000, 0x37a2eb19}, + {0x3fe79373, 0x3dcd5000, 0x37a12310}, + {0x3fe6c2b4, 0x3dd49000, 0x36da7496}, + {0x3fe5f36d, 0x3ddbc000, 0x37482bb1}, + {0x3fe52598, 0x3de2f000, 0x36a91eb8}, + {0x3fe45933, 0x3dea1000, 0x3789eb36}, + {0x3fe38e39, 0x3df13000, 0x3783b715}, + {0x3fe2c4a7, 0x3df85000, 0x36430046}, + {0x3fe1fc78, 0x3dff6000, 0x371131dc}, + {0x3fe135aa, 0x3e033000, 0x380a8965}, + {0x3fe07038, 0x3e06b000, 0x383f3e68}, + {0x3fdfac1f, 0x3e0a3000, 0x3842c234}, + {0x3fdee95c, 0x3e0db000, 0x38156a98}, + {0x3fde27eb, 0x3e113000, 0x375e3215}, + {0x3fdd67c9, 0x3e14a000, 0x38297c10}, + {0x3fdca8f1, 0x3e181000, 0x386b8c72}, + {0x3fdbeb62, 0x3e1b8000, 0x387e100f}, + {0x3fdb2f17, 0x3e1ef000, 0x38615876}, + {0x3fda740e, 0x3e226000, 0x3815b666}, + {0x3fd9ba42, 0x3e25d000, 0x36dbce69}, + {0x3fd901b2, 0x3e293000, 0x37e5e3a2}, + {0x3fd84a5a, 0x3e2c9000, 0x381c6ccc}, + {0x3fd79436, 0x3e2ff000, 0x38183854}, + {0x3fd6df44, 0x3e335000, 0x37cd4273}, + {0x3fd62b81, 0x3e36b000, 0x35fe719d}, + {0x3fd578e9, 0x3e3a0000, 0x37f8f540}, + {0x3fd4c77b, 0x3e3d5000, 0x38448108}, + {0x3fd41733, 0x3e40a000, 0x386050a2}, + {0x3fd3680d, 0x3e43f000, 0x38503290}, + {0x3fd2ba08, 0x3e474000, 0x38146f44}, + {0x3fd20d21, 0x3e4a9000, 0x373539e9}, + {0x3fd16154, 0x3e4dd000, 0x381b173f}, + {0x3fd0b6a0, 0x3e511000, 0x385e0ff1}, + {0x3fd00d01, 0x3e545000, 0x38767e44}, + {0x3fcf6475, 0x3e579000, 0x3864a740}, + {0x3fcebcf9, 0x3e5ad000, 0x3828cf48}, + {0x3fce168a, 0x3e5e1000, 0x3786742e}, + {0x3fcd7127, 0x3e614000, 0x38342ac6}, + {0x3fcccccd, 0x3e647000, 0x387be3cd}, + {0x3fcc2978, 0x3e67b000, 0x36d53827}, + {0x3fcb8728, 0x3e6ae000, 0x3685ad3f}, + {0x3fcae5d8, 0x3e6e0000, 0x385e5056}, + {0x3fca4588, 0x3e713000, 0x3803b715}, + {0x3fc9a634, 0x3e746000, 0x3494aa97}, + {0x3fc907da, 0x3e778000, 0x37adcbdc}, + {0x3fc86a79, 0x3e7aa000, 0x38052b26}, + {0x3fc7ce0c, 0x3e7dc000, 0x380c36af}, + {0x3fc73294, 0x3e807000, 0x37d88b5b}, + {0x3fc6980c, 0x3e820000, 0x371652d3}, + {0x3fc5fe74, 0x3e838000, 0x38dc2fe7}, + {0x3fc565c8, 0x3e851000, 0x3892713a}, + {0x3fc4ce08, 0x3e86a000, 0x37d6af35}, + {0x3fc43730, 0x3e882000, 0x38c5fcd7}, + {0x3fc3a13e, 0x3e89b000, 0x38070294}, + {0x3fc30c31, 0x3e8b3000, 0x38ae55d6}, + {0x3fc27806, 0x3e8cc000, 0x3652dd42}, + {0x3fc1e4bc, 0x3e8e4000, 0x3818c16a}, + {0x3fc15250, 0x3e8fc000, 0x387f9e49}, + {0x3fc0c0c1, 0x3e914000, 0x38a0fde8}, + {0x3fc0300c, 0x3e92c000, 0x38b00870}, + {0x3fbfa030, 0x3e944000, 0x38ad09ef}, + {0x3fbf112b, 0x3e95c000, 0x38981d5c}, + {0x3fbe82fa, 0x3e974000, 0x3862bae1}, + {0x3fbdf59d, 0x3e98c000, 0x37e392a9}, + {0x3fbd6910, 0x3e9a3000, 0x38eecd4c}, + {0x3fbcdd53, 0x3e9bb000, 0x38933160}, + {0x3fbc5264, 0x3e9d3000, 0x3798aad3}, + {0x3fbbc841, 0x3e9ea000, 0x38a7d2e1}, + {0x3fbb3ee7, 0x3ea02000, 0x37421a1b}, + {0x3fbab656, 0x3ea19000, 0x386f2a05}, + {0x3fba2e8c, 0x3ea30000, 0x38c5e10e}, + {0x3fb9a786, 0x3ea48000, 0x35d00801}, + {0x3fb92144, 0x3ea5f000, 0x37bf2aef}, + {0x3fb89bc3, 0x3ea76000, 0x38173260}, + {0x3fb81703, 0x3ea8d000, 0x382d872e}, + {0x3fb79301, 0x3eaa4000, 0x3822c3ae}, + {0x3fb70fbb, 0x3eabb000, 0x37ee2e8b}, + {0x3fb68d31, 0x3ead2000, 0x372ac3d3}, + {0x3fb60b61, 0x3eae8000, 0x38dedfac}, + {0x3fb58a48, 0x3eaff000, 0x38983854}, + {0x3fb509e7, 0x3eb16000, 0x3802f2ba}, + {0x3fb48a3a, 0x3eb2c000, 0x38dab982}, + {0x3fb40b41, 0x3eb43000, 0x38481e9b}, + {0x3fb38cfa, 0x3eb59000, 0x38dd911b}, + {0x3fb30f63, 0x3eb70000, 0x380eaa2c}, + {0x3fb2927c, 0x3eb86000, 0x38a1713c}, + {0x3fb21643, 0x3eb9c000, 0x38ebfb5e}, + {0x3fb19ab6, 0x3ebb3000, 0x379c2474}, + {0x3fb11fd4, 0x3ebc9000, 0x38255fdd}, + {0x3fb0a59b, 0x3ebdf000, 0x385e0a38}, + {0x3fb02c0b, 0x3ebf5000, 0x38783b83}, + {0x3fafb322, 0x3ec0b000, 0x38741da1}, + {0x3faf3ade, 0x3ec21000, 0x3851da1f}, + {0x3faec33e, 0x3ec37000, 0x38119a33}, + {0x3fae4c41, 0x3ec4d000, 0x374e1b05}, + {0x3fadd5e6, 0x3ec62000, 0x38dbe42c}, + {0x3fad602b, 0x3ec78000, 0x388f439b}, + {0x3faceb10, 0x3ec8e000, 0x37cfd68b}, + {0x3fac7692, 0x3eca3000, 0x38ca0e11}, + {0x3fac02b0, 0x3ecb9000, 0x38234113}, + {0x3fab8f6a, 0x3ecce000, 0x38cac08c}, + {0x3fab1cbe, 0x3ece4000, 0x37d605b8}, + {0x3faaaaab, 0x3ecf9000, 0x3891f660}, + {0x3faa392f, 0x3ed0e000, 0x38e0326b}, + {0x3fa9c84a, 0x3ed24000, 0x378121cb}, + {0x3fa957fb, 0x3ed39000, 0x3824966c}, + {0x3fa8e83f, 0x3ed4e000, 0x386c9a9a}, + {0x3fa87917, 0x3ed63000, 0x388c612c}, + {0x3fa80a81, 0x3ed78000, 0x38949924}, + {0x3fa79c7b, 0x3ed8d000, 0x388f075f}, + {0x3fa72f05, 0x3eda2000, 0x38777bcd}, + {0x3fa6c21e, 0x3edb7000, 0x38359d3d}, + {0x3fa655c4, 0x3edcc000, 0x37b12d26}, + {0x3fa5e9f7, 0x3ede0000, 0x38f04587}, + {0x3fa57eb5, 0x3edf5000, 0x38a6ced4}, + {0x3fa513fd, 0x3ee0a000, 0x381ff116}, + {0x3fa4a9cf, 0x3ee1e000, 0x38ebd3e7}, + {0x3fa44029, 0x3ee33000, 0x3874e3ff}, + {0x3fa3d70a, 0x3ee47000, 0x38fbe3cd}, + {0x3fa36e72, 0x3ee5c000, 0x3860744d}, + {0x3fa3065e, 0x3ee70000, 0x38d785c3}, + {0x3fa29ecf, 0x3ee85000, 0x37c75ce4}, + {0x3fa237c3, 0x3ee99000, 0x387e7e01}, + {0x3fa1d13a, 0x3eead000, 0x38bfcd71}, + {0x3fa16b31, 0x3eec1000, 0x38f392c5}, + {0x3fa105a9, 0x3eed6000, 0x3754f8b1}, + {0x3fa0a0a1, 0x3eeea000, 0x37d40984}, + {0x3fa03c17, 0x3eefe000, 0x38059907}, + {0x3f9fd80a, 0x3ef12000, 0x38081a7c}, + {0x3f9f747a, 0x3ef26000, 0x37e350d1}, + {0x3f9f1166, 0x3ef3a000, 0x3784c3ad}, + {0x3f9eaecd, 0x3ef4d000, 0x38fd32cc}, + {0x3f9e4cad, 0x3ef61000, 0x38cce923}, + {0x3f9deb07, 0x3ef75000, 0x38906320}, + {0x3f9d89d9, 0x3ef89000, 0x380f5faf}, + {0x3f9d2922, 0x3ef9c000, 0x38f2de41}, + {0x3f9cc8e1, 0x3efb0000, 0x3891fd38}, + {0x3f9c6917, 0x3efc4000, 0x37946dfd}, + {0x3f9c09c1, 0x3efd7000, 0x38ac47bc}, + {0x3f9baadf, 0x3efeb000, 0x379e41ec}, + {0x3f9b4c70, 0x3effe000, 0x3897042c}, + {0x3f9aee73, 0x3f008000, 0x397d5893}, + {0x3f9a90e8, 0x3f012000, 0x392952d3}, + {0x3f9a33cd, 0x3f01c000, 0x389eefce}, + {0x3f99d723, 0x3f025000, 0x396fced5}, + {0x3f997ae7, 0x3f02f000, 0x390a5e93}, + {0x3f991f1a, 0x3f039000, 0x37f97073}, + {0x3f98c3bb, 0x3f042000, 0x392e4426}, + {0x3f9868c8, 0x3f04c000, 0x385e9eae}, + {0x3f980e41, 0x3f055000, 0x393b5f67}, + {0x3f97b426, 0x3f05f000, 0x3865c84a}, + {0x3f975a75, 0x3f068000, 0x3931e65d}, + {0x3f97012e, 0x3f072000, 0x38130ba4}, + {0x3f96a850, 0x3f07b000, 0x39120e4e}, + {0x3f964fda, 0x3f084000, 0x3979cf17}, + {0x3f95f7cc, 0x3f08e000, 0x38b81788}, + {0x3f95a025, 0x3f097000, 0x3938caca}, + {0x3f9548e5, 0x3f0a1000, 0x37809491}, + {0x3f94f209, 0x3f0aa000, 0x38c3d2f5}, + {0x3f949b93, 0x3f0b3000, 0x392e55d6}, + {0x3f944581, 0x3f0bc000, 0x39755dec}, + {0x3f93efd2, 0x3f0c6000, 0x385c1fec}, + {0x3f939a86, 0x3f0cf000, 0x38e6b468}, + {0x3f93459c, 0x3f0d8000, 0x392a5abf}, + {0x3f92f114, 0x3f0e1000, 0x395c0fb9}, + {0x3f929cec, 0x3f0eb000, 0x3707f33c}, + {0x3f924925, 0x3f0f4000, 0x383ebce1}, + {0x3f91f5bd, 0x3f0fd000, 0x38a34b87}, + {0x3f91a2b4, 0x3f106000, 0x38dcd193}, + {0x3f915009, 0x3f10f000, 0x3905fe33}, + {0x3f90fdbc, 0x3f118000, 0x39186bdf}, + {0x3f90abcc, 0x3f121000, 0x3925b7a4}, + {0x3f905a38, 0x3f12a000, 0x392de74c}, + {0x3f900901, 0x3f133000, 0x3931009a}, + {0x3f8fb824, 0x3f13c000, 0x392f0945}, + {0x3f8f67a2, 0x3f145000, 0x392806fb}, + {0x3f8f177a, 0x3f14e000, 0x391bff61}, + {0x3f8ec7ab, 0x3f157000, 0x390af813}, + {0x3f8e7835, 0x3f160000, 0x38e9ed45}, + {0x3f8e2918, 0x3f169000, 0x38b4012f}, + {0x3f8dda52, 0x3f172000, 0x38686dc8}, + {0x3f8d8be3, 0x3f17b000, 0x37aa6542}, + {0x3f8d3dcb, 0x3f183000, 0x396b99a8}, + {0x3f8cf009, 0x3f18c000, 0x393d07d4}, + {0x3f8ca29c, 0x3f195000, 0x39099c89}, + {0x3f8c5584, 0x3f19e000, 0x38a2ba33}, + {0x3f8c08c1, 0x3f1a7000, 0x37a27674}, + {0x3f8bbc51, 0x3f1af000, 0x395276ea}, + {0x3f8b7034, 0x3f1b8000, 0x390bdaa4}, + {0x3f8b246b, 0x3f1c1000, 0x3880fe58}, + {0x3f8ad8f3, 0x3f1c9000, 0x397069ab}, + {0x3f8a8dcd, 0x3f1d2000, 0x391b9f3f}, + {0x3f8a42f8, 0x3f1db000, 0x38844a00}, + {0x3f89f874, 0x3f1e3000, 0x3963fffc}, + {0x3f89ae41, 0x3f1ec000, 0x39013539}, + {0x3f89645c, 0x3f1f5000, 0x37ce4dad}, + {0x3f891ac7, 0x3f1fd000, 0x392dc269}, + {0x3f88d181, 0x3f206000, 0x38749102}, + {0x3f888889, 0x3f20e000, 0x3947f423}, + {0x3f883fde, 0x3f217000, 0x389c6de0}, + {0x3f87f781, 0x3f21f000, 0x394ff17d}, + {0x3f87af70, 0x3f228000, 0x389a5134}, + {0x3f8767ab, 0x3f230000, 0x3945e10e}, + {0x3f872033, 0x3f239000, 0x38687e67}, + {0x3f86d905, 0x3f241000, 0x3929e8f5}, + {0x3f869223, 0x3f24a000, 0x37aa0e8c}, + {0x3f864b8a, 0x3f252000, 0x38f85db0}, + {0x3f86053c, 0x3f25a000, 0x395eb4ab}, + {0x3f85bf37, 0x3f263000, 0x38735f9a}, + {0x3f85797c, 0x3f26b000, 0x39169d1d}, + {0x3f853408, 0x3f273000, 0x396c08dc}, + {0x3f84eedd, 0x3f27c000, 0x38747ea0}, + {0x3f84a9fa, 0x3f284000, 0x3909e601}, + {0x3f84655e, 0x3f28c000, 0x3952605d}, + {0x3f842108, 0x3f295000, 0x37b4996f}, + {0x3f83dcf9, 0x3f29d000, 0x38ad05ba}, + {0x3f839930, 0x3f2a5000, 0x391233cd}, + {0x3f8355ad, 0x3f2ad000, 0x3949aa5a}, + {0x3f83126f, 0x3f2b5000, 0x397ceada}, + {0x3f82cf75, 0x3f2be000, 0x382fe66e}, + {0x3f828cc0, 0x3f2c6000, 0x38adb5cd}, + {0x3f824a4e, 0x3f2ce000, 0x38fb25fb}, + {0x3f820821, 0x3f2d6000, 0x3920261b}, + {0x3f81c636, 0x3f2de000, 0x393e9874}, + {0x3f81848e, 0x3f2e6000, 0x3958ee36}, + {0x3f814328, 0x3f2ee000, 0x396f2b8a}, + {0x3f810204, 0x3f2f7000, 0x35aa4906}, + {0x3f80c122, 0x3f2ff000, 0x3776d68c}, + {0x3f808081, 0x3f307000, 0x37cbd11e}, + {0x3f804020, 0x3f30f000, 0x37fbf692}, + {0x3f800000, 0x3f317000, 0x3805fdf4}, +}; diff --git a/src/native/clrmath/src/opt/exp.cpp b/src/native/clrmath/src/opt/exp.cpp new file mode 100644 index 00000000000000..e2c9c5f478b8c5 --- /dev/null +++ b/src/native/clrmath/src/opt/exp.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + + /* + * Literal translation of ASM routine + optimizations + * + * ISO-IEC-10967-2: Elementary Numerical Functions + * Signature: + * double exp(double x) + * + * Spec: + * exp(1) = e + * exp(x) = 1 if x ∈ F and exp(x) ≠ eË£ + * exp(x) = 1 if x = -0 + * exp(x) = +inf if x = +inf + * exp(x) = 0 if x = -inf + * exp(x) = eË£ + * + * exp(x) overflows if (approximately) x > ln(DBL_MAX). (709.782712893384) + */ + + /* + * Implementation Notes + * ---------------------- + * 1. Argument Reduction: + * e^x = 2^(x/ln2) = 2^(x*(64/ln(2))/64) --- (1) + * + * Choose 'n' and 'f', such that + * x * 64/ln2 = n + f --- (2) | n is integer + * | |f| <= 0.5 + * Choose 'm' and 'j' such that, + * n = (64 * m) + j --- (3) + * + * From (1), (2) and (3), + * e^x = 2^((64*m + j + f)/64) + * = (2^m) * (2^(j/64)) * 2^(f/64) + * = (2^m) * (2^(j/64)) * e^(f*(ln(2)/64)) + * + * 2. Table Lookup + * Values of (2^(j/64)) are precomputed, j = 0, 1, 2, 3 ... 63 + * + * 3. Polynomial Evaluation + * From (2), + * f = x*(64/ln(2)) - n + * Let, + * r = f*(ln(2)/64) = x - n*(ln(2)/64) + * + * 4. Reconstruction + * Thus, + * e^x = (2^m) * (2^(j/64)) * e^r + * + */ +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_types.h" +#include "libm/libm_typehelper.h" + + /* + * N defines the precision with which we deal with 'x' + * I.O.W (1 << N) is the size of the look up table + */ + +#define EXP_N 6 + +#include "exp_data.h" + +double _exp_special(double x, double y, uint32_t code); + +static inline uint32_t top12(double x) +{ + return asuint64(x) >> 52; +} + +#define FMAX_X 0x1.62e42fefa39efp+9 +#define FMIN_X -0x1.74910d52d3051p+9 +#define DENORMAL_LOW -0x1.74046dfefd9d0p+9 +#define DENORMAL_MIN 0x0000000000000001 + +double +ALM_PROTO_OPT(exp)(double x) +{ + double_t r, q, dn; + int64_t n, m; + int32_t j; + flt64_t q1; + q1.i = 0; + +#define EXP_X_NAN 1 +#define EXP_Y_ZERO 2 +#define EXP_Y_INF 3 + + /* + * Top 11 bits, ignoring sign bit + * this is with BIAS + */ + uint32_t exponent = top12(x) & 0x7ff; + /* + * 11-bit 'exponent' is compared with, 12-bit unsigned value + * one comparison for multiple decisions + */ + if (unlikely(exponent - top12(0x1p-54) >= top12(512.0) - top12(0x1p-54))) { + if (exponent - top12(0x1p-54) >= 0x80000000) + return 1.0; + + if (x > FMAX_X) { + if (_isnan(x)) + return _exp_special(x, asdouble(QNANBITPATT_DP64), EXP_X_NAN); + + if (x == INFINITY) + return x; /* No exception to be raised */ + + return _exp_special(x, asdouble(PINFBITPATT_DP64), EXP_Y_INF); + } + + if (x <= FMIN_X) { + if (asuint64(x) == NINFBITPATT_DP64) + return 0.0; /* No exception to be raised */ + + return _exp_special(x, 0.0, EXP_Y_ZERO); + } + + if (x <= DENORMAL_LOW) + return _exp_special(x, asdouble(DENORMAL_MIN), EXP_Y_ZERO); + + + exponent = 0xfff; + } + + double_t a = x * EXP_TBLSZ_BY_LN2; + +#define FAST_INTEGER_CONVERSION 1 +#if FAST_INTEGER_CONVERSION + q1.d = a + EXP_HUGE; + n = q1.i; + dn = q1.d - EXP_HUGE; +#else + n = cast_double_to_i64(a); + dn = cast_i64_to_double(n); +#endif + + double_t r1 = x + dn * EXP_LN2_BY_TBLSZ_HEAD; + double_t r2 = dn * EXP_LN2_BY_TBLSZ_TAIL; + r = r1 + r2; + + /* table index, for lookup, truncated */ + j = n % EXP_TABLE_SIZE; + + /* + * n-j/TABLE_SIZE, TABLE_SIZE = 1<> N and + * m <<= 52 + */ + m = (n - j) << (52 - EXP_N); + + /* redefining for easy reading */ +#define C2 EXP_C2 +#define C3 EXP_C3 +#define C4 EXP_C4 +#define C5 EXP_C5 +#define C6 EXP_C6 +#define C7 EXP_C7 + +#define ESTRIN_SCHEME 0xee +#define HORNER_SCHEME 0xef + +#define POLY_EVAL_METHOD ESTRIN_SCHEME +#define EXP_POLY_DEGREE 6 +#if POLY_EVAL_METHOD == HORNER_SCHEME +#if !defined(EXP_POLY_DEGREE) +#define EXP_POLY_DEGREE 6 +#endif +#if EXP_POLY_DEGREE == 7 + q = r * (1 + r * (C2 + r * (C3 + r * (C4 + r * (C5 + r * (C6 + r * C7)))))); +#elif EXP_POLY_DEGREE == 6 + q = r * (1 + r * (C2 + r * (C3 + r * (C4 + r * (C5 + r * C6))))); +#elif EXP_POLY_DEGREE == 5 + q = r * (1 + r * (C2 + r * (C3 + r * (C4 + r * C5)))); +#elif EXP_POLY_DEGREE == 4 + q = r * (1 + r * (C2 + r * (C3 + r * C4))); +#elif EXP_POLY_DEGREE == 3 + q = r * (1 + r * (C2 + r * C3)); +#else /* Poly order <=2 */ + q = r * (1 + r * C2); +#endif /* Order <=2 && Order == 3 */ + +#elif POLY_EVAL_METHOD == ESTRIN_SCHEME + /* Estrin's */ + // r + ((r*r)*(1/2 + (r*1/6))) + + // ((r*r) * (r*r)) * (1/24 + (r * (1/120 + (r*1/720)))) + + r2 = r * r; /* r^2 */ + q = r + (r2 * (C2 + r * C3)); + +#if EXP_POLY_DEGREE == 4 + q += (r2 * r2) * C4; /* r^4 * C4 */ +#elif EXP_POLY_DEGREE == 5 + q += (r2 * r2) * (C4 + r * C5); +#elif EXP_POLY_DEGREE == 6 + q += (r2 * r2) * (C4 + r * (C5 + r * C6)); +#endif +#else + #warning "POLY_EVAL_METHOD is not defined" +#endif /* if HORNER_SCHEME || ESTRIN_SCHEME */ + + /* f(j)*q + f1 + f2 */ + struct exp_table* tbl = &((struct exp_table*)EXP_TABLE_DATA)[j]; + q = q * tbl->main + tbl->head + tbl->tail; + + /* + * Processing denormals + */ + if (unlikely(exponent == 0xfff)) { + /* re-calculate m */ + int32_t m2 = (int32_t)((n - j) >> EXP_N); + if (m2 <= -1022) { + if (m2 < -1022 || q < 1.0) { + /* Process true de-normals */ + m2 += 1074; + flt64u_t tmp; + tmp.i = (1ULL << m2); + return q * tmp.d; + } + } + } + + q1.d = asdouble(m + asuint64(q)); + + return q1.d; + +#if defined(__ENABLE_IEEE_EXCEPTIONS) +#endif +} diff --git a/src/native/clrmath/src/opt/exp_data.h b/src/native/clrmath/src/opt/exp_data.h new file mode 100644 index 00000000000000..162c73226aaca9 --- /dev/null +++ b/src/native/clrmath/src/opt/exp_data.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __OPTIMIZED_EXP_H__ +#define __OPTIMIZED_EXP_H__ + + +#ifndef EXP_N +#define EXP_N 7 +#endif + +#define EXP_TABLE_SIZE (1ULL << EXP_N) + +#if EXP_N == 6 /* Table size 64 */ +#define EXP_POLY_DEGREE 6 + +#elif EXP_N == 7 /* Table size 128 */ +#define EXP_POLY_DEGREE 5 + +#elif EXP_N == 8 /* Table size 256 */ +#define EXP_POLY_DEGREE 4 + +#elif EXP_N == 9 /* Table size 512 */ +#define EXP_POLY_DEGREE 4 + +#elif EXP_N == 10 /* Table size 1024 */ +#define EXP_POLY_DEGREE 4 +#endif + +#define EXP_MAX_POLYDEGREE 8 + + /* + * tblsz_byln2 = (-1) x (log(2) / TABLE_SIZE); + * head = asuint64(tblsz_byln2) + * tail = tblsz_byln2 - head + */ +struct exp_table { + double main, head, tail; +}; + +struct exp_data_t { + double Huge; + double tblsz_byln2; + struct { + double head, tail; + } ln2by_tblsz; + double ALIGN(16) poly[EXP_MAX_POLYDEGREE]; + struct exp_table table[EXP_TABLE_SIZE]; +}; + +static const exp_data_t exp_data = { + /* .Huge = */ 0x1.8p+52, +#if EXP_N == 10 + /* .tblsz_byln2 = */ 0x1.71547652b82fep+10, + /* .ln2by_tblsz = */ {-0x1.62e42fefa0000p-11, -0x1.cf79abc9e3b3ap-50}, +#elif EXP_N == 9 + /* .tblsz_byln2 = */ 0x1.71547652b82fep+9, + /* .ln2by_tblsz = */ {-0x1.62e42fefa0000p-10, -0x1.cf79abc9e3b39p-49} +#elif EXP_N == 8 + /* .tblsz_byln2 = */ 0x1.71547652b82fep+8, + /* .ln2by_tblsz = */ {-0x1.62e42fefa0000p-9, -0x1.cf79abc9e3b39p-48}, +#elif EXP_N == 7 + /* .tblsz_byln2 = */ 0x1.71547652b82fep+7, + /* .ln2by_tblsz = */ {-0x1.62e42fefa0000p-8, -0x1.cf79abc9e3b39p-47}, +#elif EXP_N == 6 + /* .tblsz_byln2 = */ 0x1.71547652b82fep+6, + /* .ln2by_tblsz = */ {-0x1.62e42fefa0000p-7, -0x1.cf79abc9e3b39p-46}, +#else +#error "N not defined" +#endif + + /* + * Polynomial constants, 1/x! (reciprocal of factorial(x)) + * To make better use of cache line, we dont store 0! and 1! + */ + + /* .poly = */ { /* skip for 0! and 1! */ + 0x1.0000000000000p-1, /* 1/2! = 1/2 */ + 0x1.5555555555555p-3, /* 1/3! = 1/6 */ + 0x1.5555555555555p-5, /* 1/4! = 1/24 */ + 0x1.1111111111111p-7, /* 1/5! = 1/120 */ +#if EXP_POLY_DEGREE >= 5 + 0x1.6c16c16c16c17p-10, /* 1/6! = 1/720 */ +#if EXP_POLY_DEGREE >= 6 + 0x1.a01a01a01a01ap-13, /* 1/7! = 1/5040 */ +#if EXP_POLY_DEGREE >= 7 + 0x1.a01a01a01a01ap-16, /* 1/8! = 1/40320*/ +#if EXP_POLY_DEGREE >= 8 + 0x1.71de3a556c734p-19, /* 1/9! = 1/322880*/ +#endif +#endif +#endif +#endif + }, + + /* .table = */ { +#if EXP_N == 6 + #include "data/_exp_tbl_64_interleaved.data" +#elif EXP_N == 7 + #include "data/_exp_tbl_128_interleaved.data" +#endif + }, +}; + +/* C1 is 1 as 1! = 1 and 1/1! = 1 */ +#define EXP_C2 exp_data.poly[0] +#define EXP_C3 exp_data.poly[1] +#define EXP_C4 exp_data.poly[2] +#define EXP_C5 exp_data.poly[3] +#define EXP_C6 exp_data.poly[4] +#define EXP_C7 exp_data.poly[5] +#define EXP_C8 exp_data.poly[6] +#define EXP_HUGE exp_data.Huge + +#define EXP_TBLSZ_BY_LN2 exp_data.tblsz_byln2 +#define EXP_LN2_BY_TBLSZ_HEAD exp_data.ln2by_tblsz.head +#define EXP_LN2_BY_TBLSZ_TAIL exp_data.ln2by_tblsz.tail +#define EXP_TABLE_DATA exp_data.table + + +#endif /* OPTIMIZIED_EXP_H */ diff --git a/src/native/clrmath/src/opt/exp_tables.cpp b/src/native/clrmath/src/opt/exp_tables.cpp new file mode 100644 index 00000000000000..8a81c44f1640f9 --- /dev/null +++ b/src/native/clrmath/src/opt/exp_tables.cpp @@ -0,0 +1,862 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" + +extern "C" uint64_t __two_to_jby64_table[] = { + 0x3ff0000000000000, 0x3ff02c9a3e778061, 0x3ff059b0d3158574, 0x3ff0874518759bc8, + 0x3ff0b5586cf9890f, 0x3ff0e3ec32d3d1a2, 0x3ff11301d0125b51, 0x3ff1429aaea92de0, + 0x3ff172b83c7d517b, 0x3ff1a35beb6fcb75, 0x3ff1d4873168b9aa, 0x3ff2063b88628cd6, + 0x3ff2387a6e756238, 0x3ff26b4565e27cdd, 0x3ff29e9df51fdee1, 0x3ff2d285a6e4030b, + 0x3ff306fe0a31b715, 0x3ff33c08b26416ff, 0x3ff371a7373aa9cb, 0x3ff3a7db34e59ff7, + 0x3ff3dea64c123422, 0x3ff4160a21f72e2a, 0x3ff44e086061892d, 0x3ff486a2b5c13cd0, + 0x3ff4bfdad5362a27, 0x3ff4f9b2769d2ca7, 0x3ff5342b569d4f82, 0x3ff56f4736b527da, + 0x3ff5ab07dd485429, 0x3ff5e76f15ad2148, 0x3ff6247eb03a5585, 0x3ff6623882552225, + 0x3ff6a09e667f3bcd, 0x3ff6dfb23c651a2f, 0x3ff71f75e8ec5f74, 0x3ff75feb564267c9, + 0x3ff7a11473eb0187, 0x3ff7e2f336cf4e62, 0x3ff82589994cce13, 0x3ff868d99b4492ed, + 0x3ff8ace5422aa0db, 0x3ff8f1ae99157736, 0x3ff93737b0cdc5e5, 0x3ff97d829fde4e50, + 0x3ff9c49182a3f090, 0x3ffa0c667b5de565, 0x3ffa5503b23e255d, 0x3ffa9e6b5579fdbf, + 0x3ffae89f995ad3ad, 0x3ffb33a2b84f15fb, 0x3ffb7f76f2fb5e47, 0x3ffbcc1e904bc1d2, + 0x3ffc199bdd85529c, 0x3ffc67f12e57d14b, 0x3ffcb720dcef9069, 0x3ffd072d4a07897c, + 0x3ffd5818dcfba487, 0x3ffda9e603db3285, 0x3ffdfc97337b9b5f, 0x3ffe502ee78b3ff6, + 0x3ffea4afa2a490da, 0x3ffefa1bee615a27, 0x3fff50765b6e4540, 0x3fffa7c1819e90d8, +}; + +extern "C" uint64_t __two_to_jby64_head_table[] = { + 0x3ff0000000000000, 0x3ff02c9a30000000, 0x3ff059b0d0000000, 0x3ff0874510000000, + 0x3ff0b55860000000, 0x3ff0e3ec30000000, 0x3ff11301d0000000, 0x3ff1429aa0000000, + 0x3ff172b830000000, 0x3ff1a35be0000000, 0x3ff1d48730000000, 0x3ff2063b80000000, + 0x3ff2387a60000000, 0x3ff26b4560000000, 0x3ff29e9df0000000, 0x3ff2d285a0000000, + 0x3ff306fe00000000, 0x3ff33c08b0000000, 0x3ff371a730000000, 0x3ff3a7db30000000, + 0x3ff3dea640000000, 0x3ff4160a20000000, 0x3ff44e0860000000, 0x3ff486a2b0000000, + 0x3ff4bfdad0000000, 0x3ff4f9b270000000, 0x3ff5342b50000000, 0x3ff56f4730000000, + 0x3ff5ab07d0000000, 0x3ff5e76f10000000, 0x3ff6247eb0000000, 0x3ff6623880000000, + 0x3ff6a09e60000000, 0x3ff6dfb230000000, 0x3ff71f75e0000000, 0x3ff75feb50000000, + 0x3ff7a11470000000, 0x3ff7e2f330000000, 0x3ff8258990000000, 0x3ff868d990000000, + 0x3ff8ace540000000, 0x3ff8f1ae90000000, 0x3ff93737b0000000, 0x3ff97d8290000000, + 0x3ff9c49180000000, 0x3ffa0c6670000000, 0x3ffa5503b0000000, 0x3ffa9e6b50000000, + 0x3ffae89f90000000, 0x3ffb33a2b0000000, 0x3ffb7f76f0000000, 0x3ffbcc1e90000000, + 0x3ffc199bd0000000, 0x3ffc67f120000000, 0x3ffcb720d0000000, 0x3ffd072d40000000, + 0x3ffd5818d0000000, 0x3ffda9e600000000, 0x3ffdfc9730000000, 0x3ffe502ee0000000, + 0x3ffea4afa0000000, 0x3ffefa1be0000000, 0x3fff507650000000, 0x3fffa7c180000000, +}; + +extern "C" uint64_t __two_to_jby64_tail_table[] = { + 0x0000000000000000, 0x3e6cef00c1dcdef9, 0x3e48ac2ba1d73e2a, 0x3e60eb37901186be, + 0x3e69f3121ec53172, 0x3e469e8d10103a17, 0x3df25b50a4ebbf1a, 0x3e6d525bbf668203, + 0x3e68faa2f5b9bef9, 0x3e66df96ea796d31, 0x3e368b9aa7805b80, 0x3e60c519ac771dd6, + 0x3e6ceac470cd83f5, 0x3e5789f37495e99c, 0x3e547f7b84b09745, 0x3e5b900c2d002475, + 0x3e64636e2a5bd1ab, 0x3e4320b7fa64e430, 0x3e5ceaa72a9c5154, 0x3e53967fdba86f24, + 0x3e682468446b6824, 0x3e3f72e29f84325b, 0x3e18624b40c4dbd0, 0x3e5704f3404f068e, + 0x3e54d8a89c750e5e, 0x3e5a74b29ab4cf62, 0x3e5a753e077c2a0f, 0x3e5ad49f699bb2c0, + 0x3e6a90a852b19260, 0x3e56b48521ba6f93, 0x3e0d2ac258f87d03, 0x3e42a91124893ecf, + 0x3e59fcef32422cbe, 0x3e68ca345de441c5, 0x3e61d8bee7ba46e1, 0x3e59099f22fdba6a, + 0x3e4f580c36bea881, 0x3e5b3d398841740a, 0x3e62999c25159f11, 0x3e668925d901c83b, + 0x3e415506dadd3e2a, 0x3e622aee6c57304e, 0x3e29b8bc9e8a0387, 0x3e6fbc9c9f173d24, + 0x3e451f8480e3e235, 0x3e66bbcac96535b5, 0x3e41f12ae45a1224, 0x3e55e7f6fd0fac90, + 0x3e62b5a75abd0e69, 0x3e609e2bf5ed7fa1, 0x3e47daf237553d84, 0x3e12f074891ee83d, + 0x3e6b0aa538444196, 0x3e6cafa29694426f, 0x3e69df20d22a0797, 0x3e640f12f71a1e45, + 0x3e69f7490e4bb40b, 0x3e4ed9942b84600d, 0x3e4bdcdaf5cb4656, 0x3e5e2cffd89cf44c, + 0x3e452486cc2c7b9d, 0x3e6cc2b44eee3fa4, 0x3e66dc8a80ce9f09, 0x3e39e90d82e90a7e, +}; + +extern "C" uint64_t __two_to_jby1024_table[] = { + 0x3ff0000000000000, 0x3ff002c605e2e8cf, 0x3ff0058c86da1c0a, 0x3ff0085382faef83, + 0x3ff00b1afa5abcbf, 0x3ff00de2ed0ee0f5, 0x3ff010ab5b2cbd11, 0x3ff0137444c9b5b5, + 0x3ff0163da9fb3335, 0x3ff019078ad6a19f, 0x3ff01bd1e77170b4, 0x3ff01e9cbfe113ef, + 0x3ff02168143b0281, 0x3ff02433e494b755, 0x3ff027003103b10e, 0x3ff029ccf99d720a, + 0x3ff02c9a3e778061, 0x3ff02f67ffa765e6, 0x3ff032363d42b027, 0x3ff03504f75ef071, + 0x3ff037d42e11bbcc, 0x3ff03aa3e170aafe, 0x3ff03d7411915a8a, 0x3ff04044be896ab6, + 0x3ff04315e86e7f85, 0x3ff045e78f5640b9, 0x3ff048b9b35659d8, 0x3ff04b8c54847a28, + 0x3ff04e5f72f654b1, 0x3ff051330ec1a03f, 0x3ff0540727fc1762, 0x3ff056dbbebb786b, + 0x3ff059b0d3158574, 0x3ff05c866520045b, 0x3ff05f5c74f0bec2, 0x3ff06233029d8216, + 0x3ff0650a0e3c1f89, 0x3ff067e197e26c14, 0x3ff06ab99fa6407c, 0x3ff06d92259d794d, + 0x3ff0706b29ddf6de, 0x3ff07344ac7d9d51, 0x3ff0761ead925493, 0x3ff078f92d32085d, + 0x3ff07bd42b72a836, 0x3ff07eafa86a2771, 0x3ff0818ba42e7d30, 0x3ff084681ed5a462, + 0x3ff0874518759bc8, 0x3ff08a22912465f2, 0x3ff08d0088f8093f, 0x3ff08fdf00068fe2, + 0x3ff092bdf66607e0, 0x3ff0959d6c2c830d, 0x3ff0987d61701716, 0x3ff09b5dd646dd77, + 0x3ff09e3ecac6f383, 0x3ff0a1203f067a63, 0x3ff0a402331b9715, 0x3ff0a6e4a71c726e, + 0x3ff0a9c79b1f3919, 0x3ff0acab0f3a1b9c, 0x3ff0af8f03834e52, 0x3ff0b27378110974, + 0x3ff0b5586cf9890f, 0x3ff0b83de2530d11, 0x3ff0bb23d833d93f, 0x3ff0be0a4eb2353b, + 0x3ff0c0f145e46c85, 0x3ff0c3d8bde0ce7a, 0x3ff0c6c0b6bdae53, 0x3ff0c9a93091632a, + 0x3ff0cc922b7247f7, 0x3ff0cf7ba776bb94, 0x3ff0d265a4b520ba, 0x3ff0d5502343de02, + 0x3ff0d83b23395dec, 0x3ff0db26a4ac0ed5, 0x3ff0de12a7b26300, 0x3ff0e0ff2c62d096, + 0x3ff0e3ec32d3d1a2, 0x3ff0e6d9bb1be415, 0x3ff0e9c7c55189c6, 0x3ff0ecb6518b4874, + 0x3ff0efa55fdfa9c5, 0x3ff0f294f0653b45, 0x3ff0f58503328e6d, 0x3ff0f875985e389b, + 0x3ff0fb66affed31b, 0x3ff0fe584a2afb21, 0x3ff1014a66f951ce, 0x3ff1043d06807c2f, + 0x3ff1073028d7233e, 0x3ff10a23ce13f3e2, 0x3ff10d17f64d9ef1, 0x3ff1100ca19ad92f, + 0x3ff11301d0125b51, 0x3ff115f781cae1fa, 0x3ff118edb6db2dc1, 0x3ff11be46f5a032c, + 0x3ff11edbab5e2ab6, 0x3ff121d36afe70c9, 0x3ff124cbae51a5c8, 0x3ff127c4756e9e05, + 0x3ff12abdc06c31cc, 0x3ff12db78f613d5b, 0x3ff130b1e264a0e9, 0x3ff133acb98d40a2, + 0x3ff136a814f204ab, 0x3ff139a3f4a9d922, 0x3ff13ca058cbae1e, 0x3ff13f9d416e77af, + 0x3ff1429aaea92de0, 0x3ff14598a092ccb7, 0x3ff1489717425438, 0x3ff14b9612cec861, + 0x3ff14e95934f312e, 0x3ff1519598da9a9a, 0x3ff154962388149e, 0x3ff15797336eb333, + 0x3ff15a98c8a58e51, 0x3ff15d9ae343c1f2, 0x3ff1609d83606e12, 0x3ff163a0a912b6ac, + 0x3ff166a45471c3c2, 0x3ff169a88594c157, 0x3ff16cad3c92df73, 0x3ff16fb279835224, + 0x3ff172b83c7d517b, 0x3ff175be85981992, 0x3ff178c554eaea89, 0x3ff17bccaa8d0888, + 0x3ff17ed48695bbc0, 0x3ff181dce91c506a, 0x3ff184e5d23816c9, 0x3ff187ef4200632b, + 0x3ff18af9388c8dea, 0x3ff18e03b5f3f36b, 0x3ff1910eba4df41f, 0x3ff1941a45b1f487, + 0x3ff1972658375d2f, 0x3ff19a32f1f59ab4, 0x3ff19d4013041dc2, 0x3ff1a04dbb7a5b13, + 0x3ff1a35beb6fcb75, 0x3ff1a66aa2fbebc7, 0x3ff1a979e2363cf8, 0x3ff1ac89a936440d, + 0x3ff1af99f8138a1c, 0x3ff1b2aacee59c53, 0x3ff1b5bc2dc40bf0, 0x3ff1b8ce14c66e4c, + 0x3ff1bbe084045cd4, 0x3ff1bef37b95750b, 0x3ff1c206fb91588f, 0x3ff1c51b040fad15, + 0x3ff1c82f95281c6b, 0x3ff1cb44aef2547a, 0x3ff1ce5a51860746, 0x3ff1d1707cfaeaed, + 0x3ff1d4873168b9aa, 0x3ff1d79e6ee731d7, 0x3ff1dab6358e15e8, 0x3ff1ddce85752c71, + 0x3ff1e0e75eb44027, 0x3ff1e400c1631fdb, 0x3ff1e71aad999e82, 0x3ff1ea35236f9330, + 0x3ff1ed5022fcd91d, 0x3ff1f06bac594fa0, 0x3ff1f387bf9cda38, 0x3ff1f6a45cdf6085, + 0x3ff1f9c18438ce4d, 0x3ff1fcdf35c1137a, 0x3ff1fffd7190241e, 0x3ff2031c37bdf872, + 0x3ff2063b88628cd6, 0x3ff2095b6395e1d2, 0x3ff20c7bc96ffc18, 0x3ff20f9cba08e483, + 0x3ff212be3578a819, 0x3ff215e03bd7580c, 0x3ff21902cd3d09b9, 0x3ff21c25e9c1d6aa, + 0x3ff21f49917ddc96, 0x3ff2226dc4893d64, 0x3ff2259282fc1f27, 0x3ff228b7cceeac25, + 0x3ff22bdda27912d1, 0x3ff22f0403b385d2, 0x3ff2322af0b63bff, 0x3ff2355269997062, + 0x3ff2387a6e756238, 0x3ff23ba2ff6254f4, 0x3ff23ecc1c78903a, 0x3ff241f5c5d05fe6, + 0x3ff2451ffb82140a, 0x3ff2484abda600ef, 0x3ff24b760c547f15, 0x3ff24ea1e7a5eb35, + 0x3ff251ce4fb2a63f, 0x3ff254fb44931561, 0x3ff25828c65fa1ff, 0x3ff25b56d530b9bc, + 0x3ff25e85711ece75, 0x3ff261b49a425645, 0x3ff264e450b3cb82, 0x3ff26814948bacc3, + 0x3ff26b4565e27cdd, 0x3ff26e76c4d0c2e5, 0x3ff271a8b16f0a30, 0x3ff274db2bd5e254, + 0x3ff2780e341ddf29, 0x3ff27b41ca5f98cb, 0x3ff27e75eeb3ab98, 0x3ff281aaa132b832, + 0x3ff284dfe1f56381, 0x3ff28815b11456b1, 0x3ff28b4c0ea83f36, 0x3ff28e82fac9ceca, + 0x3ff291ba7591bb70, 0x3ff294f27f18bf72, 0x3ff2982b17779965, 0x3ff29b643ec70c27, + 0x3ff29e9df51fdee1, 0x3ff2a1d83a9add08, 0x3ff2a5130f50d65c, 0x3ff2a84e735a9eec, + 0x3ff2ab8a66d10f13, 0x3ff2aec6e9cd037b, 0x3ff2b203fc675d1f, 0x3ff2b5419eb90148, + 0x3ff2b87fd0dad990, 0x3ff2bbbe92e5d3e3, 0x3ff2befde4f2e280, 0x3ff2c23dc71afbf7, + 0x3ff2c57e39771b2f, 0x3ff2c8bf3c203f5f, 0x3ff2cc00cf2f6c18, 0x3ff2cf42f2bda93d, + 0x3ff2d285a6e4030b, 0x3ff2d5c8ebbb8a15, 0x3ff2d90cc15d5346, 0x3ff2dc5127e277e3, + 0x3ff2df961f641589, 0x3ff2e2dba7fb4e33, 0x3ff2e621c1c14833, 0x3ff2e9686ccf2e3b, + 0x3ff2ecafa93e2f56, 0x3ff2eff777277ef0, 0x3ff2f33fd6a454d2, 0x3ff2f688c7cded23, + 0x3ff2f9d24abd886b, 0x3ff2fd1c5f8c6b93, 0x3ff300670653dfe4, 0x3ff303b23f2d330b, + 0x3ff306fe0a31b715, 0x3ff30a4a677ac276, 0x3ff30d975721b004, 0x3ff310e4d93fdefb, + 0x3ff31432edeeb2fd, 0x3ff3178195479413, 0x3ff31ad0cf63eeac, 0x3ff31e209c5d33a0, + 0x3ff32170fc4cd831, 0x3ff324c1ef4c560a, 0x3ff3281375752b40, 0x3ff32b658ee0da54, + 0x3ff32eb83ba8ea32, 0x3ff3320b7be6e633, 0x3ff3355f4fb45e20, 0x3ff338b3b72ae62d, + 0x3ff33c08b26416ff, 0x3ff33f5e41798daa, 0x3ff342b46484ebb4, 0x3ff3460b1b9fd712, + 0x3ff3496266e3fa2d, 0x3ff34cba466b03e1, 0x3ff35012ba4ea77d, 0x3ff3536bc2a89cc4, + 0x3ff356c55f929ff1, 0x3ff35a1f912671b1, 0x3ff35d7a577dd72b, 0x3ff360d5b2b299fc, + 0x3ff36431a2de883b, 0x3ff3678e281b7475, 0x3ff36aeb428335b4, 0x3ff36e48f22fa77c, + 0x3ff371a7373aa9cb, 0x3ff3750611be211c, 0x3ff3786581d3f669, 0x3ff37bc587961726, + 0x3ff37f26231e754a, 0x3ff3828754870746, 0x3ff385e91be9c811, 0x3ff3894b7960b71f, + 0x3ff38cae6d05d866, 0x3ff39011f6f3345f, 0x3ff393761742d808, 0x3ff396dace0ed4e1, + 0x3ff39a401b7140ef, 0x3ff39da5ff8436bc, 0x3ff3a10c7a61d55b, 0x3ff3a4738c244064, + 0x3ff3a7db34e59ff7, 0x3ff3ab4374c020bd, 0x3ff3aeac4bcdf3ea, 0x3ff3b215ba294f39, + 0x3ff3b57fbfec6cf4, 0x3ff3b8ea5d318bef, 0x3ff3bc559212ef89, 0x3ff3bfc15eaadfb1, + 0x3ff3c32dc313a8e5, 0x3ff3c69abf679c2e, 0x3ff3ca0853c10f28, 0x3ff3cd76803a5c00, + 0x3ff3d0e544ede173, 0x3ff3d454a1f602d0, 0x3ff3d7c4976d27fa, 0x3ff3db35256dbd67, + 0x3ff3dea64c123422, 0x3ff3e2180b7501cc, 0x3ff3e58a63b0a09b, 0x3ff3e8fd54df8f5c, + 0x3ff3ec70df1c5175, 0x3ff3efe502816ee3, 0x3ff3f359bf29743f, 0x3ff3f6cf152ef2b8, + 0x3ff3fa4504ac801c, 0x3ff3fdbb8dbcb6d2, 0x3ff40132b07a35df, 0x3ff404aa6cffa0e5, + 0x3ff40822c367a024, 0x3ff40b9bb3cce07c, 0x3ff40f153e4a136a, 0x3ff4128f62f9ef0e, + 0x3ff4160a21f72e2a, 0x3ff419857b5c901f, 0x3ff41d016f44d8f5, 0x3ff4207dfdcad153, + 0x3ff423fb2709468a, 0x3ff42778eb1b0a8b, 0x3ff42af74a1af3f1, 0x3ff42e764423ddfd, + 0x3ff431f5d950a897, 0x3ff4357609bc3850, 0x3ff438f6d5817663, 0x3ff43c783cbb50b4, + 0x3ff43ffa3f84b9d4, 0x3ff4437cddf8a8fe, 0x3ff4470018321a1a, 0x3ff44a83ee4c0dbd, + 0x3ff44e086061892d, 0x3ff4518d6e8d965b, 0x3ff4551318eb43ec, 0x3ff458995f95a532, + 0x3ff45c2042a7d232, 0x3ff45fa7c23ce7a4, 0x3ff4632fde7006f4, 0x3ff466b8975c563e, + 0x3ff46a41ed1d0057, 0x3ff46dcbdfcd34c8, 0x3ff471566f8827d0, 0x3ff474e19c691265, + 0x3ff4786d668b3237, 0x3ff47bf9ce09c9ab, 0x3ff47f86d3001fe5, 0x3ff48314758980bf, + 0x3ff486a2b5c13cd0, 0x3ff48a3193c2a96c, 0x3ff48dc10fa920a1, 0x3ff491512990013f, + 0x3ff494e1e192aed2, 0x3ff4987337cc91a5, 0x3ff49c052c5916c4, 0x3ff49f97bf53affd, + 0x3ff4a32af0d7d3de, 0x3ff4a6bec100fdba, 0x3ff4aa532feaada6, 0x3ff4ade83db0687a, + 0x3ff4b17dea6db7d7, 0x3ff4b514363e2a20, 0x3ff4b8ab213d5283, 0x3ff4bc42ab86c8f1, + 0x3ff4bfdad5362a27, 0x3ff4c3739e6717aa, 0x3ff4c70d073537ca, 0x3ff4caa70fbc35a1, + 0x3ff4ce41b817c114, 0x3ff4d1dd00638ed8, 0x3ff4d578e8bb586b, 0x3ff4d915713adc1e, + 0x3ff4dcb299fddd0d, 0x3ff4e05063202327, 0x3ff4e3eeccbd7b2a, 0x3ff4e78dd6f1b6a6, + 0x3ff4eb2d81d8abff, 0x3ff4eecdcd8e3669, 0x3ff4f26eba2e35f0, 0x3ff4f61047d48f73, + 0x3ff4f9b2769d2ca7, 0x3ff4fd5546a3fc17, 0x3ff500f8b804f127, 0x3ff5049ccadc0412, + 0x3ff508417f4531ee, 0x3ff50be6d55c7ca9, 0x3ff50f8ccd3deb0d, 0x3ff51333670588bf, + 0x3ff516daa2cf6642, 0x3ff51a8280b798f4, 0x3ff51e2b00da3b14, 0x3ff521d423536bbe, + 0x3ff5257de83f4eef, 0x3ff529284fba0d84, 0x3ff52cd359dfd53d, 0x3ff5307f06ccd8ba, + 0x3ff5342b569d4f82, 0x3ff537d8496d75fc, 0x3ff53b85df598d78, 0x3ff53f34187ddc28, + 0x3ff542e2f4f6ad27, 0x3ff5469274e05078, 0x3ff54a4298571b06, 0x3ff54df35f7766a3, + 0x3ff551a4ca5d920f, 0x3ff55556d92600f1, 0x3ff559098bed1bdf, 0x3ff55cbce2cf505b, + 0x3ff56070dde910d2, 0x3ff564257d56d4a2, 0x3ff567dac1351819, 0x3ff56b90a9a05c72, + 0x3ff56f4736b527da, 0x3ff572fe68900573, 0x3ff576b63f4d854c, 0x3ff57a6ebb0a3c6d, + 0x3ff57e27dbe2c4cf, 0x3ff581e1a1f3bd60, 0x3ff5859c0d59ca07, 0x3ff589571e31939f, + 0x3ff58d12d497c7fd, 0x3ff590cf30a919ed, 0x3ff5948c32824135, 0x3ff59849da3ffa96, + 0x3ff59c0827ff07cc, 0x3ff59fc71bdc2f8e, 0x3ff5a386b5f43d92, 0x3ff5a746f664028b, + 0x3ff5ab07dd485429, 0x3ff5aec96abe0d1f, 0x3ff5b28b9ee20d1e, 0x3ff5b64e79d138d8, + 0x3ff5ba11fba87a03, 0x3ff5bdd62484bf56, 0x3ff5c19af482fc8f, 0x3ff5c5606bc02a6d, + 0x3ff5c9268a5946b7, 0x3ff5cced506b543a, 0x3ff5d0b4be135acc, 0x3ff5d47cd36e6747, + 0x3ff5d84590998b93, 0x3ff5dc0ef5b1de9e, 0x3ff5dfd902d47c65, 0x3ff5e3a3b81e85ec, + 0x3ff5e76f15ad2148, 0x3ff5eb3b1b9d799a, 0x3ff5ef07ca0cbf0f, 0x3ff5f2d5211826e8, + 0x3ff5f6a320dceb71, 0x3ff5fa71c9784c0b, 0x3ff5fe411b078d26, 0x3ff6021115a7f849, + 0x3ff605e1b976dc09, 0x3ff609b306918c13, 0x3ff60d84fd15612a, 0x3ff611579d1fb925, + 0x3ff6152ae6cdf6f4, 0x3ff618feda3d829f, 0x3ff61cd3778bc944, 0x3ff620a8bed63d1f, + 0x3ff6247eb03a5585, 0x3ff628554bd58ee5, 0x3ff62c2c91c56acd, 0x3ff6300482276fe8, + 0x3ff633dd1d1929fd, 0x3ff637b662b829f5, 0x3ff63b90532205d8, 0x3ff63f6aee7458cd, + 0x3ff6434634ccc320, 0x3ff647222648ea3d, 0x3ff64afec30678b7, 0x3ff64edc0b231e41, + 0x3ff652b9febc8fb7, 0x3ff656989df08719, 0x3ff65a77e8dcc390, 0x3ff65e57df9f096b, + 0x3ff6623882552225, 0x3ff66619d11cdc5f, 0x3ff669fbcc140be7, 0x3ff66dde735889b8, + 0x3ff671c1c70833f6, 0x3ff675a5c740edf5, 0x3ff6798a7420a036, 0x3ff67d6fcdc5386a, + 0x3ff68155d44ca973, 0x3ff6853c87d4eb62, 0x3ff68923e87bfb7a, 0x3ff68d0bf65fdc34, + 0x3ff690f4b19e9538, 0x3ff694de1a563367, 0x3ff698c830a4c8d4, 0x3ff69cb2f4a86cca, + 0x3ff6a09e667f3bcd, 0x3ff6a48a86475795, 0x3ff6a877541ee718, 0x3ff6ac64d0241683, + 0x3ff6b052fa75173e, 0x3ff6b441d3301fee, 0x3ff6b8315a736c75, 0x3ff6bc21905d3df0, + 0x3ff6c012750bdabf, 0x3ff6c404089d8e7d, 0x3ff6c7f64b30aa09, 0x3ff6cbe93ce38381, + 0x3ff6cfdcddd47645, 0x3ff6d3d12e21e2fb, 0x3ff6d7c62dea2f8a, 0x3ff6dbbbdd4bc720, + 0x3ff6dfb23c651a2f, 0x3ff6e3a94b549e71, 0x3ff6e7a10a38cee8, 0x3ff6eb9979302bdd, + 0x3ff6ef9298593ae5, 0x3ff6f38c67d286dd, 0x3ff6f786e7ba9fef, 0x3ff6fb8218301b90, + 0x3ff6ff7df9519484, 0x3ff7037a8b3daadb, 0x3ff70777ce1303f6, 0x3ff70b75c1f04a84, + 0x3ff70f7466f42e87, 0x3ff71373bd3d6551, 0x3ff71773c4eaa988, 0x3ff71b747e1abb24, + 0x3ff71f75e8ec5f74, 0x3ff72378057e611a, 0x3ff7277ad3ef9011, 0x3ff72b7e545ec1a8, + 0x3ff72f8286ead08a, 0x3ff733876bb29cb8, 0x3ff7378d02d50b8f, 0x3ff73b934c7107c7, + 0x3ff73f9a48a58174, 0x3ff743a1f7916e05, 0x3ff747aa5953c849, 0x3ff74bb36e0b906d, + 0x3ff74fbd35d7cbfd, 0x3ff753c7b0d785e8, 0x3ff757d2df29ce7c, 0x3ff75bdec0edbb6b, + 0x3ff75feb564267c9, 0x3ff763f89f46f40f, 0x3ff768069c1a861d, 0x3ff76c154cdc4937, + 0x3ff77024b1ab6e09, 0x3ff77434caa72aa7, 0x3ff7784597eeba8f, 0x3ff77c5719a15ea6, + 0x3ff780694fde5d3f, 0x3ff7847c3ac50219, 0x3ff7888fda749e5d, 0x3ff78ca42f0c88a5, + 0x3ff790b938ac1cf6, 0x3ff794cef772bcc9, 0x3ff798e56b7fcf03, 0x3ff79cfc94f2bfff, + 0x3ff7a11473eb0187, 0x3ff7a52d08880ad9, 0x3ff7a94652e958aa, 0x3ff7ad60532e6d20, + 0x3ff7b17b0976cfdb, 0x3ff7b59675e20def, 0x3ff7b9b2988fb9ec, 0x3ff7bdcf719f6bd7, + 0x3ff7c1ed0130c132, 0x3ff7c60b47635cf9, 0x3ff7ca2a4456e7a3, 0x3ff7ce49f82b0f24, + 0x3ff7d26a62ff86f0, 0x3ff7d68b84f407f8, 0x3ff7daad5e2850ac, 0x3ff7decfeebc24fe, + 0x3ff7e2f336cf4e62, 0x3ff7e71736819bcd, 0x3ff7eb3bedf2e1b9, 0x3ff7ef615d42fa24, + 0x3ff7f3878491c491, 0x3ff7f7ae63ff260a, 0x3ff7fbd5fbab091f, 0x3ff7fffe4bb55dec, + 0x3ff80427543e1a12, 0x3ff80851156538be, 0x3ff80c7b8f4abaa9, 0x3ff810a6c20ea617, + 0x3ff814d2add106d9, 0x3ff818ff52b1ee50, 0x3ff81d2cb0d1736a, 0x3ff8215ac84fb2a6, + 0x3ff82589994cce13, 0x3ff829b923e8ed53, 0x3ff82de968443d9a, 0x3ff8321a667ef1b2, + 0x3ff8364c1eb941f7, 0x3ff83a7e91136c5d, 0x3ff83eb1bdadb46d, 0x3ff842e5a4a8634a, + 0x3ff8471a4623c7ad, 0x3ff84b4fa24035ea, 0x3ff84f85b91e07f1, 0x3ff853bc8add9d4c, + 0x3ff857f4179f5b21, 0x3ff85c2c5f83ac35, 0x3ff8606562ab00ec, 0x3ff8649f2135cf48, + 0x3ff868d99b4492ed, 0x3ff86d14d0f7cd1d, 0x3ff87150c27004c2, 0x3ff8758d6fcdc666, + 0x3ff879cad931a436, 0x3ff87e08febc3608, 0x3ff88247e08e1957, 0x3ff886877ec7f144, + 0x3ff88ac7d98a6699, 0x3ff88f08f0f627cb, 0x3ff8934ac52be8f7, 0x3ff8978d564c63e7, + 0x3ff89bd0a478580f, 0x3ff8a014afd08a94, 0x3ff8a4597875c644, 0x3ff8a89efe88dba1, + 0x3ff8ace5422aa0db, 0x3ff8b12c437bf1d4, 0x3ff8b574029db01e, 0x3ff8b9bc7fb0c302, + 0x3ff8be05bad61778, 0x3ff8c24fb42ea033, 0x3ff8c69a6bdb5598, 0x3ff8cae5e1fd35c4, + 0x3ff8cf3216b5448c, 0x3ff8d37f0a248b7f, 0x3ff8d7ccbc6c19e6, 0x3ff8dc1b2dad04c4, + 0x3ff8e06a5e0866d9, 0x3ff8e4ba4d9f60a1, 0x3ff8e90afc931857, 0x3ff8ed5c6b04b9f6, + 0x3ff8f1ae99157736, 0x3ff8f60186e68793, 0x3ff8fa553499284b, 0x3ff8fea9a24e9c5c, + 0x3ff902fed0282c8a, 0x3ff90754be472760, 0x3ff90bab6ccce12c, 0x3ff91002dbdab403, + 0x3ff9145b0b91ffc6, 0x3ff918b3fc142a19, 0x3ff91d0dad829e70, 0x3ff921681ffece05, + 0x3ff925c353aa2fe2, 0x3ff92a1f48a640dc, 0x3ff92e7bff148396, 0x3ff932d977168083, + 0x3ff93737b0cdc5e5, 0x3ff93b96ac5be7d1, 0x3ff93ff669e2802b, 0x3ff94456e9832ead, + 0x3ff948b82b5f98e5, 0x3ff94d1a2f996a33, 0x3ff9517cf65253d1, 0x3ff955e07fac0ccd, + 0x3ff95a44cbc8520f, 0x3ff95ea9dac8e658, 0x3ff9630faccf9243, 0x3ff9677641fe2446, + 0x3ff96bdd9a7670b3, 0x3ff97045b65a51ba, 0x3ff974ae95cba768, 0x3ff9791838ec57ab, + 0x3ff97d829fde4e50, 0x3ff981edcac37d05, 0x3ff98659b9bddb5b, 0x3ff98ac66cef66c8, + 0x3ff98f33e47a22a2, 0x3ff993a220801829, 0x3ff9981121235681, 0x3ff99c80e685f2b5, + 0x3ff9a0f170ca07ba, 0x3ff9a562c011b66d, 0x3ff9a9d4d47f2598, 0x3ff9ae47ae3481ed, + 0x3ff9b2bb4d53fe0d, 0x3ff9b72fb1ffd285, 0x3ff9bba4dc5a3dd3, 0x3ff9c01acc858463, + 0x3ff9c49182a3f090, 0x3ff9c908fed7d2aa, 0x3ff9cd81414380f2, 0x3ff9d1fa4a09579d, + 0x3ff9d674194bb8d5, 0x3ff9daeeaf2d0cb8, 0x3ff9df6a0bcfc15e, 0x3ff9e3e62f564ad5, + 0x3ff9e86319e32323, 0x3ff9ece0cb98ca4b, 0x3ff9f15f4499c647, 0x3ff9f5de8508a311, + 0x3ff9fa5e8d07f29e, 0x3ff9fedf5cba4ce0, 0x3ffa0360f4424fcb, 0x3ffa07e353c29f50, + 0x3ffa0c667b5de565, 0x3ffa10ea6b36d1fe, 0x3ffa156f23701b15, 0x3ffa19f4a42c7ca9, + 0x3ffa1e7aed8eb8bb, 0x3ffa2301ffb99757, 0x3ffa2789dacfe68c, 0x3ffa2c127ef47a74, + 0x3ffa309bec4a2d33, 0x3ffa352622f3def6, 0x3ffa39b1231475f7, 0x3ffa3e3ceccede7c, + 0x3ffa42c980460ad8, 0x3ffa4756dd9cf36e, 0x3ffa4be504f696b1, 0x3ffa5073f675f924, + 0x3ffa5503b23e255d, 0x3ffa599438722c03, 0x3ffa5e25893523d4, 0x3ffa62b7a4aa29a1, + 0x3ffa674a8af46052, 0x3ffa6bde3c36f0e6, 0x3ffa7072b8950a73, 0x3ffa75080031e22b, + 0x3ffa799e1330b358, 0x3ffa7e34f1b4bf62, 0x3ffa82cc9be14dca, 0x3ffa876511d9ac32, + 0x3ffa8bfe53c12e59, 0x3ffa909861bb2e1d, 0x3ffa95333beb0b7e, 0x3ffa99cee2742c9d, + 0x3ffa9e6b5579fdbf, 0x3ffaa308951ff14d, 0x3ffaa7a6a1897fd2, 0x3ffaac457ada2803, + 0x3ffab0e521356eba, 0x3ffab58594bedefa, 0x3ffaba26d59a09ee, 0x3ffabec8e3ea86ee, + 0x3ffac36bbfd3f37a, 0x3ffac80f6979f340, 0x3ffaccb3e100301e, 0x3ffad159268a5a1c, + 0x3ffad5ff3a3c2774, 0x3ffadaa61c395493, 0x3ffadf4dcca5a413, 0x3ffae3f64ba4dec6, + 0x3ffae89f995ad3ad, 0x3ffaed49b5eb5803, 0x3ffaf1f4a17a4735, 0x3ffaf6a05c2b82e9, + 0x3ffafb4ce622f2ff, 0x3ffafffa3f84858c, 0x3ffb04a868742ee4, 0x3ffb09576115e994, + 0x3ffb0e07298db666, 0x3ffb12b7c1ff9c61, 0x3ffb17692a8fa8cd, 0x3ffb1c1b6361ef31, + 0x3ffb20ce6c9a8952, 0x3ffb2582465d973c, 0x3ffb2a36f0cf3f3a, 0x3ffb2eec6c13addd, + 0x3ffb33a2b84f15fb, 0x3ffb3859d5a5b0b1, 0x3ffb3d11c43bbd62, 0x3ffb41ca843581ba, + 0x3ffb468415b749b1, 0x3ffb4b3e78e56786, 0x3ffb4ff9ade433c6, 0x3ffb54b5b4d80d4a, + 0x3ffb59728de5593a, 0x3ffb5e303930830c, 0x3ffb62eeb6ddfc87, 0x3ffb67ae07123dc3, + 0x3ffb6c6e29f1c52a, 0x3ffb712f1fa1177b, 0x3ffb75f0e844bfc6, 0x3ffb7ab384014f76, + 0x3ffb7f76f2fb5e47, 0x3ffb843b35578a51, 0x3ffb89004b3a7804, 0x3ffb8dc634c8d228, + 0x3ffb928cf22749e4, 0x3ffb9754837a96b7, 0x3ffb9c1ce8e77680, 0x3ffba0e62292ad7d, + 0x3ffba5b030a1064a, 0x3ffbaa7b133751e3, 0x3ffbaf46ca7a67a7, 0x3ffbb413568f255a, + 0x3ffbb8e0b79a6f1f, 0x3ffbbdaeedc12f82, 0x3ffbc27df9285775, 0x3ffbc74dd9f4de4f, + 0x3ffbcc1e904bc1d2, 0x3ffbd0f01c520628, 0x3ffbd5c27e2cb5e5, 0x3ffbda95b600e20b, + 0x3ffbdf69c3f3a207, 0x3ffbe43ea82a13b5, 0x3ffbe91462c95b60, 0x3ffbedeaf3f6a3c2, + 0x3ffbf2c25bd71e09, 0x3ffbf79a9a9001d2, 0x3ffbfc73b0468d30, 0x3ffc014d9d2004aa, + 0x3ffc06286141b33d, 0x3ffc0b03fcd0ea5c, 0x3ffc0fe06ff301f4, 0x3ffc14bdbacd586a, + 0x3ffc199bdd85529c, 0x3ffc1e7ad8405be6, 0x3ffc235aab23e61e, 0x3ffc283b56556999, + 0x3ffc2d1cd9fa652c, 0x3ffc31ff36385e29, 0x3ffc36e26b34e065, 0x3ffc3bc679157e38, + 0x3ffc40ab5fffd07a, 0x3ffc45912019768c, 0x3ffc4a77b9881650, 0x3ffc4f5f2c715c31, + 0x3ffc544778fafb22, 0x3ffc59309f4aac9f, 0x3ffc5e1a9f8630ad, 0x3ffc630579d34ddd, + 0x3ffc67f12e57d14b, 0x3ffc6cddbd398ea4, 0x3ffc71cb269e601f, 0x3ffc76b96aac2686, + 0x3ffc7ba88988c933, 0x3ffc8098835a3611, 0x3ffc8589584661a1, 0x3ffc8a7b087346f4, + 0x3ffc8f6d9406e7b5, 0x3ffc9460fb274c22, 0x3ffc99553dfa8313, 0x3ffc9e4a5ca6a1f8, + 0x3ffca3405751c4db, 0x3ffca8372e220e61, 0x3ffcad2ee13da7cb, 0x3ffcb22770cac0f9, + 0x3ffcb720dcef9069, 0x3ffcbc1b25d25337, 0x3ffcc1164b994d23, 0x3ffcc6124e6ac88b, + 0x3ffccb0f2e6d1675, 0x3ffcd00cebc68e87, 0x3ffcd50b869d8f0f, 0x3ffcda0aff187d02, + 0x3ffcdf0b555dc3fa, 0x3ffce40c8993d63d, 0x3ffce90e9be12cb9, 0x3ffcee118c6c4709, + 0x3ffcf3155b5bab74, 0x3ffcf81a08d5e6ec, 0x3ffcfd1f95018d17, 0x3ffd022600053845, + 0x3ffd072d4a07897c, 0x3ffd0c35732f2870, 0x3ffd113e7ba2c38c, 0x3ffd164863890fee, + 0x3ffd1b532b08c968, 0x3ffd205ed248b287, 0x3ffd256b596f948c, 0x3ffd2a78c0a43f72, + 0x3ffd2f87080d89f2, 0x3ffd34962fd2517a, 0x3ffd39a638197a3c, 0x3ffd3eb72109ef21, + 0x3ffd43c8eacaa1d6, 0x3ffd48db95828ac7, 0x3ffd4def2158a91f, 0x3ffd53038e7402ce, + 0x3ffd5818dcfba487, 0x3ffd5d2f0d16a1c3, 0x3ffd62461eec14be, 0x3ffd675e12a31e7f, + 0x3ffd6c76e862e6d3, 0x3ffd7190a0529c51, 0x3ffd76ab3a99745b, 0x3ffd7bc6b75eab1f, + 0x3ffd80e316c98398, 0x3ffd86005901478f, 0x3ffd8b1e7e2d479d, 0x3ffd903d8674db2b, + 0x3ffd955d71ff6075, 0x3ffd9a7e40f43c89, 0x3ffd9f9ff37adb4a, 0x3ffda4c289baaf6e, + 0x3ffda9e603db3285, 0x3ffdaf0a6203e4f5, 0x3ffdb42fa45c4dfd, 0x3ffdb955cb0bfbb6, + 0x3ffdbe7cd63a8315, 0x3ffdc3a4c60f7fea, 0x3ffdc8cd9ab294e4, 0x3ffdcdf7544b6b92, + 0x3ffdd321f301b460, 0x3ffdd84d76fd269e, 0x3ffddd79e065807d, 0x3ffde2a72f628712, + 0x3ffde7d5641c0658, 0x3ffded047eb9d12d, 0x3ffdf2347f63c159, 0x3ffdf7656641b78c, + 0x3ffdfc97337b9b5f, 0x3ffe01c9e7395b56, 0x3ffe06fd81a2ece1, 0x3ffe0c3202e04c5d, + 0x3ffe11676b197d17, 0x3ffe169dba768949, 0x3ffe1bd4f11f8220, 0x3ffe210d0f3c7fba, + 0x3ffe264614f5a129, 0x3ffe2b8002730c71, 0x3ffe30bad7dcee90, 0x3ffe35f6955b7b78, + 0x3ffe3b333b16ee12, 0x3ffe4070c9378842, 0x3ffe45af3fe592e8, 0x3ffe4aee9f495ddc, + 0x3ffe502ee78b3ff6, 0x3ffe557018d3970b, 0x3ffe5ab2334ac7ee, 0x3ffe5ff537193e75, + 0x3ffe653924676d76, 0x3ffe6a7dfb5dceca, 0x3ffe6fc3bc24e350, 0x3ffe750a66e532eb, + 0x3ffe7a51fbc74c83, 0x3ffe7f9a7af3c60b, 0x3ffe84e3e4933c7e, 0x3ffe8a2e38ce53df, + 0x3ffe8f7977cdb740, 0x3ffe94c5a1ba18bd, 0x3ffe9a12b6bc3181, 0x3ffe9f60b6fcc1c7, + 0x3ffea4afa2a490da, 0x3ffea9ff79dc6d14, 0x3ffeaf503ccd2be5, 0x3ffeb4a1eb9fa9d1, + 0x3ffeb9f4867cca6e, 0x3ffebf480d8d786d, 0x3ffec49c80faa594, 0x3ffec9f1e0ed4ac2, + 0x3ffecf482d8e67f1, 0x3ffed49f67070435, 0x3ffed9f78d802dc2, 0x3ffedf50a122f9e6, + 0x3ffee4aaa2188510, 0x3ffeea059089f2d0, 0x3ffeef616ca06dd6, 0x3ffef4be368527f6, + 0x3ffefa1bee615a27, 0x3ffeff7a945e4487, 0x3fff04da28a52e59, 0x3fff0a3aab5f6609, + 0x3fff0f9c1cb6412a, 0x3fff14fe7cd31c7b, 0x3fff1a61cbdf5be7, 0x3fff1fc60a046a84, + 0x3fff252b376bba97, 0x3fff2a91543ec595, 0x3fff2ff860a70c22, 0x3fff35605cce1613, + 0x3fff3ac948dd7274, 0x3fff403324feb781, 0x3fff459df15b82ac, 0x3fff4b09ae1d78a1, + 0x3fff50765b6e4540, 0x3fff55e3f9779ba5, 0x3fff5b5288633625, 0x3fff60c2085ad652, + 0x3fff6632798844f8, 0x3fff6ba3dc155226, 0x3fff7116302bd526, 0x3fff768975f5ac86, + 0x3fff7bfdad9cbe14, 0x3fff8172d74af6e1, 0x3fff86e8f32a4b45, 0x3fff8c600164b6dc, + 0x3fff91d802243c89, 0x3fff9750f592e677, 0x3fff9ccadbdac61d, 0x3fffa245b525f439, + 0x3fffa7c1819e90d8, 0x3fffad3e416ec354, 0x3fffb2bbf4c0ba54, 0x3fffb83a9bbeabd1, + 0x3fffbdba3692d514, 0x3fffc33ac5677ab8, 0x3fffc8bc4866e8ad, 0x3fffce3ebfbb7237, + 0x3fffd3c22b8f71f1, 0x3fffd9468c0d49cc, 0x3fffdecbe15f6314, 0x3fffe4522bb02e6e, + 0x3fffe9d96b2a23d9, 0x3fffef619ff7c2b3, 0x3ffff4eaca4391b6, 0x3ffffa74ea381efc, +}; + +extern "C" uint64_t __two_to_jby1024_head_table[] = { + 0x3ff0000000000000, 0x3ff002c600000000, 0x3ff0058c80000000, 0x3ff0085380000000, + 0x3ff00b1af0000000, 0x3ff00de2e0000000, 0x3ff010ab50000000, 0x3ff0137440000000, + 0x3ff0163da0000000, 0x3ff0190780000000, 0x3ff01bd1e0000000, 0x3ff01e9cb0000000, + 0x3ff0216810000000, 0x3ff02433e0000000, 0x3ff0270030000000, 0x3ff029ccf0000000, + 0x3ff02c9a30000000, 0x3ff02f67f0000000, 0x3ff0323630000000, 0x3ff03504f0000000, + 0x3ff037d420000000, 0x3ff03aa3e0000000, 0x3ff03d7410000000, 0x3ff04044b0000000, + 0x3ff04315e0000000, 0x3ff045e780000000, 0x3ff048b9b0000000, 0x3ff04b8c50000000, + 0x3ff04e5f70000000, 0x3ff0513300000000, 0x3ff0540720000000, 0x3ff056dbb0000000, + 0x3ff059b0d0000000, 0x3ff05c8660000000, 0x3ff05f5c70000000, 0x3ff0623300000000, + 0x3ff0650a00000000, 0x3ff067e190000000, 0x3ff06ab990000000, 0x3ff06d9220000000, + 0x3ff0706b20000000, 0x3ff07344a0000000, 0x3ff0761ea0000000, 0x3ff078f920000000, + 0x3ff07bd420000000, 0x3ff07eafa0000000, 0x3ff0818ba0000000, 0x3ff0846810000000, + 0x3ff0874510000000, 0x3ff08a2290000000, 0x3ff08d0080000000, 0x3ff08fdf00000000, + 0x3ff092bdf0000000, 0x3ff0959d60000000, 0x3ff0987d60000000, 0x3ff09b5dd0000000, + 0x3ff09e3ec0000000, 0x3ff0a12030000000, 0x3ff0a40230000000, 0x3ff0a6e4a0000000, + 0x3ff0a9c790000000, 0x3ff0acab00000000, 0x3ff0af8f00000000, 0x3ff0b27370000000, + 0x3ff0b55860000000, 0x3ff0b83de0000000, 0x3ff0bb23d0000000, 0x3ff0be0a40000000, + 0x3ff0c0f140000000, 0x3ff0c3d8b0000000, 0x3ff0c6c0b0000000, 0x3ff0c9a930000000, + 0x3ff0cc9220000000, 0x3ff0cf7ba0000000, 0x3ff0d265a0000000, 0x3ff0d55020000000, + 0x3ff0d83b20000000, 0x3ff0db26a0000000, 0x3ff0de12a0000000, 0x3ff0e0ff20000000, + 0x3ff0e3ec30000000, 0x3ff0e6d9b0000000, 0x3ff0e9c7c0000000, 0x3ff0ecb650000000, + 0x3ff0efa550000000, 0x3ff0f294f0000000, 0x3ff0f58500000000, 0x3ff0f87590000000, + 0x3ff0fb66a0000000, 0x3ff0fe5840000000, 0x3ff1014a60000000, 0x3ff1043d00000000, + 0x3ff1073020000000, 0x3ff10a23c0000000, 0x3ff10d17f0000000, 0x3ff1100ca0000000, + 0x3ff11301d0000000, 0x3ff115f780000000, 0x3ff118edb0000000, 0x3ff11be460000000, + 0x3ff11edba0000000, 0x3ff121d360000000, 0x3ff124cba0000000, 0x3ff127c470000000, + 0x3ff12abdc0000000, 0x3ff12db780000000, 0x3ff130b1e0000000, 0x3ff133acb0000000, + 0x3ff136a810000000, 0x3ff139a3f0000000, 0x3ff13ca050000000, 0x3ff13f9d40000000, + 0x3ff1429aa0000000, 0x3ff14598a0000000, 0x3ff1489710000000, 0x3ff14b9610000000, + 0x3ff14e9590000000, 0x3ff1519590000000, 0x3ff1549620000000, 0x3ff1579730000000, + 0x3ff15a98c0000000, 0x3ff15d9ae0000000, 0x3ff1609d80000000, 0x3ff163a0a0000000, + 0x3ff166a450000000, 0x3ff169a880000000, 0x3ff16cad30000000, 0x3ff16fb270000000, + 0x3ff172b830000000, 0x3ff175be80000000, 0x3ff178c550000000, 0x3ff17bcca0000000, + 0x3ff17ed480000000, 0x3ff181dce0000000, 0x3ff184e5d0000000, 0x3ff187ef40000000, + 0x3ff18af930000000, 0x3ff18e03b0000000, 0x3ff1910eb0000000, 0x3ff1941a40000000, + 0x3ff1972650000000, 0x3ff19a32f0000000, 0x3ff19d4010000000, 0x3ff1a04db0000000, + 0x3ff1a35be0000000, 0x3ff1a66aa0000000, 0x3ff1a979e0000000, 0x3ff1ac89a0000000, + 0x3ff1af99f0000000, 0x3ff1b2aac0000000, 0x3ff1b5bc20000000, 0x3ff1b8ce10000000, + 0x3ff1bbe080000000, 0x3ff1bef370000000, 0x3ff1c206f0000000, 0x3ff1c51b00000000, + 0x3ff1c82f90000000, 0x3ff1cb44a0000000, 0x3ff1ce5a50000000, 0x3ff1d17070000000, + 0x3ff1d48730000000, 0x3ff1d79e60000000, 0x3ff1dab630000000, 0x3ff1ddce80000000, + 0x3ff1e0e750000000, 0x3ff1e400c0000000, 0x3ff1e71aa0000000, 0x3ff1ea3520000000, + 0x3ff1ed5020000000, 0x3ff1f06ba0000000, 0x3ff1f387b0000000, 0x3ff1f6a450000000, + 0x3ff1f9c180000000, 0x3ff1fcdf30000000, 0x3ff1fffd70000000, 0x3ff2031c30000000, + 0x3ff2063b80000000, 0x3ff2095b60000000, 0x3ff20c7bc0000000, 0x3ff20f9cb0000000, + 0x3ff212be30000000, 0x3ff215e030000000, 0x3ff21902c0000000, 0x3ff21c25e0000000, + 0x3ff21f4990000000, 0x3ff2226dc0000000, 0x3ff2259280000000, 0x3ff228b7c0000000, + 0x3ff22bdda0000000, 0x3ff22f0400000000, 0x3ff2322af0000000, 0x3ff2355260000000, + 0x3ff2387a60000000, 0x3ff23ba2f0000000, 0x3ff23ecc10000000, 0x3ff241f5c0000000, + 0x3ff2451ff0000000, 0x3ff2484ab0000000, 0x3ff24b7600000000, 0x3ff24ea1e0000000, + 0x3ff251ce40000000, 0x3ff254fb40000000, 0x3ff25828c0000000, 0x3ff25b56d0000000, + 0x3ff25e8570000000, 0x3ff261b490000000, 0x3ff264e450000000, 0x3ff2681490000000, + 0x3ff26b4560000000, 0x3ff26e76c0000000, 0x3ff271a8b0000000, 0x3ff274db20000000, + 0x3ff2780e30000000, 0x3ff27b41c0000000, 0x3ff27e75e0000000, 0x3ff281aaa0000000, + 0x3ff284dfe0000000, 0x3ff28815b0000000, 0x3ff28b4c00000000, 0x3ff28e82f0000000, + 0x3ff291ba70000000, 0x3ff294f270000000, 0x3ff2982b10000000, 0x3ff29b6430000000, + 0x3ff29e9df0000000, 0x3ff2a1d830000000, 0x3ff2a51300000000, 0x3ff2a84e70000000, + 0x3ff2ab8a60000000, 0x3ff2aec6e0000000, 0x3ff2b203f0000000, 0x3ff2b54190000000, + 0x3ff2b87fd0000000, 0x3ff2bbbe90000000, 0x3ff2befde0000000, 0x3ff2c23dc0000000, + 0x3ff2c57e30000000, 0x3ff2c8bf30000000, 0x3ff2cc00c0000000, 0x3ff2cf42f0000000, + 0x3ff2d285a0000000, 0x3ff2d5c8e0000000, 0x3ff2d90cc0000000, 0x3ff2dc5120000000, + 0x3ff2df9610000000, 0x3ff2e2dba0000000, 0x3ff2e621c0000000, 0x3ff2e96860000000, + 0x3ff2ecafa0000000, 0x3ff2eff770000000, 0x3ff2f33fd0000000, 0x3ff2f688c0000000, + 0x3ff2f9d240000000, 0x3ff2fd1c50000000, 0x3ff3006700000000, 0x3ff303b230000000, + 0x3ff306fe00000000, 0x3ff30a4a60000000, 0x3ff30d9750000000, 0x3ff310e4d0000000, + 0x3ff31432e0000000, 0x3ff3178190000000, 0x3ff31ad0c0000000, 0x3ff31e2090000000, + 0x3ff32170f0000000, 0x3ff324c1e0000000, 0x3ff3281370000000, 0x3ff32b6580000000, + 0x3ff32eb830000000, 0x3ff3320b70000000, 0x3ff3355f40000000, 0x3ff338b3b0000000, + 0x3ff33c08b0000000, 0x3ff33f5e40000000, 0x3ff342b460000000, 0x3ff3460b10000000, + 0x3ff3496260000000, 0x3ff34cba40000000, 0x3ff35012b0000000, 0x3ff3536bc0000000, + 0x3ff356c550000000, 0x3ff35a1f90000000, 0x3ff35d7a50000000, 0x3ff360d5b0000000, + 0x3ff36431a0000000, 0x3ff3678e20000000, 0x3ff36aeb40000000, 0x3ff36e48f0000000, + 0x3ff371a730000000, 0x3ff3750610000000, 0x3ff3786580000000, 0x3ff37bc580000000, + 0x3ff37f2620000000, 0x3ff3828750000000, 0x3ff385e910000000, 0x3ff3894b70000000, + 0x3ff38cae60000000, 0x3ff39011f0000000, 0x3ff3937610000000, 0x3ff396dac0000000, + 0x3ff39a4010000000, 0x3ff39da5f0000000, 0x3ff3a10c70000000, 0x3ff3a47380000000, + 0x3ff3a7db30000000, 0x3ff3ab4370000000, 0x3ff3aeac40000000, 0x3ff3b215b0000000, + 0x3ff3b57fb0000000, 0x3ff3b8ea50000000, 0x3ff3bc5590000000, 0x3ff3bfc150000000, + 0x3ff3c32dc0000000, 0x3ff3c69ab0000000, 0x3ff3ca0850000000, 0x3ff3cd7680000000, + 0x3ff3d0e540000000, 0x3ff3d454a0000000, 0x3ff3d7c490000000, 0x3ff3db3520000000, + 0x3ff3dea640000000, 0x3ff3e21800000000, 0x3ff3e58a60000000, 0x3ff3e8fd50000000, + 0x3ff3ec70d0000000, 0x3ff3efe500000000, 0x3ff3f359b0000000, 0x3ff3f6cf10000000, + 0x3ff3fa4500000000, 0x3ff3fdbb80000000, 0x3ff40132b0000000, 0x3ff404aa60000000, + 0x3ff40822c0000000, 0x3ff40b9bb0000000, 0x3ff40f1530000000, 0x3ff4128f60000000, + 0x3ff4160a20000000, 0x3ff4198570000000, 0x3ff41d0160000000, 0x3ff4207df0000000, + 0x3ff423fb20000000, 0x3ff42778e0000000, 0x3ff42af740000000, 0x3ff42e7640000000, + 0x3ff431f5d0000000, 0x3ff4357600000000, 0x3ff438f6d0000000, 0x3ff43c7830000000, + 0x3ff43ffa30000000, 0x3ff4437cd0000000, 0x3ff4470010000000, 0x3ff44a83e0000000, + 0x3ff44e0860000000, 0x3ff4518d60000000, 0x3ff4551310000000, 0x3ff4589950000000, + 0x3ff45c2040000000, 0x3ff45fa7c0000000, 0x3ff4632fd0000000, 0x3ff466b890000000, + 0x3ff46a41e0000000, 0x3ff46dcbd0000000, 0x3ff4715660000000, 0x3ff474e190000000, + 0x3ff4786d60000000, 0x3ff47bf9c0000000, 0x3ff47f86d0000000, 0x3ff4831470000000, + 0x3ff486a2b0000000, 0x3ff48a3190000000, 0x3ff48dc100000000, 0x3ff4915120000000, + 0x3ff494e1e0000000, 0x3ff4987330000000, 0x3ff49c0520000000, 0x3ff49f97b0000000, + 0x3ff4a32af0000000, 0x3ff4a6bec0000000, 0x3ff4aa5320000000, 0x3ff4ade830000000, + 0x3ff4b17de0000000, 0x3ff4b51430000000, 0x3ff4b8ab20000000, 0x3ff4bc42a0000000, + 0x3ff4bfdad0000000, 0x3ff4c37390000000, 0x3ff4c70d00000000, 0x3ff4caa700000000, + 0x3ff4ce41b0000000, 0x3ff4d1dd00000000, 0x3ff4d578e0000000, 0x3ff4d91570000000, + 0x3ff4dcb290000000, 0x3ff4e05060000000, 0x3ff4e3eec0000000, 0x3ff4e78dd0000000, + 0x3ff4eb2d80000000, 0x3ff4eecdc0000000, 0x3ff4f26eb0000000, 0x3ff4f61040000000, + 0x3ff4f9b270000000, 0x3ff4fd5540000000, 0x3ff500f8b0000000, 0x3ff5049cc0000000, + 0x3ff5084170000000, 0x3ff50be6d0000000, 0x3ff50f8cc0000000, 0x3ff5133360000000, + 0x3ff516daa0000000, 0x3ff51a8280000000, 0x3ff51e2b00000000, 0x3ff521d420000000, + 0x3ff5257de0000000, 0x3ff5292840000000, 0x3ff52cd350000000, 0x3ff5307f00000000, + 0x3ff5342b50000000, 0x3ff537d840000000, 0x3ff53b85d0000000, 0x3ff53f3410000000, + 0x3ff542e2f0000000, 0x3ff5469270000000, 0x3ff54a4290000000, 0x3ff54df350000000, + 0x3ff551a4c0000000, 0x3ff55556d0000000, 0x3ff5590980000000, 0x3ff55cbce0000000, + 0x3ff56070d0000000, 0x3ff5642570000000, 0x3ff567dac0000000, 0x3ff56b90a0000000, + 0x3ff56f4730000000, 0x3ff572fe60000000, 0x3ff576b630000000, 0x3ff57a6eb0000000, + 0x3ff57e27d0000000, 0x3ff581e1a0000000, 0x3ff5859c00000000, 0x3ff5895710000000, + 0x3ff58d12d0000000, 0x3ff590cf30000000, 0x3ff5948c30000000, 0x3ff59849d0000000, + 0x3ff59c0820000000, 0x3ff59fc710000000, 0x3ff5a386b0000000, 0x3ff5a746f0000000, + 0x3ff5ab07d0000000, 0x3ff5aec960000000, 0x3ff5b28b90000000, 0x3ff5b64e70000000, + 0x3ff5ba11f0000000, 0x3ff5bdd620000000, 0x3ff5c19af0000000, 0x3ff5c56060000000, + 0x3ff5c92680000000, 0x3ff5cced50000000, 0x3ff5d0b4b0000000, 0x3ff5d47cd0000000, + 0x3ff5d84590000000, 0x3ff5dc0ef0000000, 0x3ff5dfd900000000, 0x3ff5e3a3b0000000, + 0x3ff5e76f10000000, 0x3ff5eb3b10000000, 0x3ff5ef07c0000000, 0x3ff5f2d520000000, + 0x3ff5f6a320000000, 0x3ff5fa71c0000000, 0x3ff5fe4110000000, 0x3ff6021110000000, + 0x3ff605e1b0000000, 0x3ff609b300000000, 0x3ff60d84f0000000, 0x3ff6115790000000, + 0x3ff6152ae0000000, 0x3ff618fed0000000, 0x3ff61cd370000000, 0x3ff620a8b0000000, + 0x3ff6247eb0000000, 0x3ff6285540000000, 0x3ff62c2c90000000, 0x3ff6300480000000, + 0x3ff633dd10000000, 0x3ff637b660000000, 0x3ff63b9050000000, 0x3ff63f6ae0000000, + 0x3ff6434630000000, 0x3ff6472220000000, 0x3ff64afec0000000, 0x3ff64edc00000000, + 0x3ff652b9f0000000, 0x3ff6569890000000, 0x3ff65a77e0000000, 0x3ff65e57d0000000, + 0x3ff6623880000000, 0x3ff66619d0000000, 0x3ff669fbc0000000, 0x3ff66dde70000000, + 0x3ff671c1c0000000, 0x3ff675a5c0000000, 0x3ff6798a70000000, 0x3ff67d6fc0000000, + 0x3ff68155d0000000, 0x3ff6853c80000000, 0x3ff68923e0000000, 0x3ff68d0bf0000000, + 0x3ff690f4b0000000, 0x3ff694de10000000, 0x3ff698c830000000, 0x3ff69cb2f0000000, + 0x3ff6a09e60000000, 0x3ff6a48a80000000, 0x3ff6a87750000000, 0x3ff6ac64d0000000, + 0x3ff6b052f0000000, 0x3ff6b441d0000000, 0x3ff6b83150000000, 0x3ff6bc2190000000, + 0x3ff6c01270000000, 0x3ff6c40400000000, 0x3ff6c7f640000000, 0x3ff6cbe930000000, + 0x3ff6cfdcd0000000, 0x3ff6d3d120000000, 0x3ff6d7c620000000, 0x3ff6dbbbd0000000, + 0x3ff6dfb230000000, 0x3ff6e3a940000000, 0x3ff6e7a100000000, 0x3ff6eb9970000000, + 0x3ff6ef9290000000, 0x3ff6f38c60000000, 0x3ff6f786e0000000, 0x3ff6fb8210000000, + 0x3ff6ff7df0000000, 0x3ff7037a80000000, 0x3ff70777c0000000, 0x3ff70b75c0000000, + 0x3ff70f7460000000, 0x3ff71373b0000000, 0x3ff71773c0000000, 0x3ff71b7470000000, + 0x3ff71f75e0000000, 0x3ff7237800000000, 0x3ff7277ad0000000, 0x3ff72b7e50000000, + 0x3ff72f8280000000, 0x3ff7338760000000, 0x3ff7378d00000000, 0x3ff73b9340000000, + 0x3ff73f9a40000000, 0x3ff743a1f0000000, 0x3ff747aa50000000, 0x3ff74bb360000000, + 0x3ff74fbd30000000, 0x3ff753c7b0000000, 0x3ff757d2d0000000, 0x3ff75bdec0000000, + 0x3ff75feb50000000, 0x3ff763f890000000, 0x3ff7680690000000, 0x3ff76c1540000000, + 0x3ff77024b0000000, 0x3ff77434c0000000, 0x3ff7784590000000, 0x3ff77c5710000000, + 0x3ff7806940000000, 0x3ff7847c30000000, 0x3ff7888fd0000000, 0x3ff78ca420000000, + 0x3ff790b930000000, 0x3ff794cef0000000, 0x3ff798e560000000, 0x3ff79cfc90000000, + 0x3ff7a11470000000, 0x3ff7a52d00000000, 0x3ff7a94650000000, 0x3ff7ad6050000000, + 0x3ff7b17b00000000, 0x3ff7b59670000000, 0x3ff7b9b290000000, 0x3ff7bdcf70000000, + 0x3ff7c1ed00000000, 0x3ff7c60b40000000, 0x3ff7ca2a40000000, 0x3ff7ce49f0000000, + 0x3ff7d26a60000000, 0x3ff7d68b80000000, 0x3ff7daad50000000, 0x3ff7decfe0000000, + 0x3ff7e2f330000000, 0x3ff7e71730000000, 0x3ff7eb3be0000000, 0x3ff7ef6150000000, + 0x3ff7f38780000000, 0x3ff7f7ae60000000, 0x3ff7fbd5f0000000, 0x3ff7fffe40000000, + 0x3ff8042750000000, 0x3ff8085110000000, 0x3ff80c7b80000000, 0x3ff810a6c0000000, + 0x3ff814d2a0000000, 0x3ff818ff50000000, 0x3ff81d2cb0000000, 0x3ff8215ac0000000, + 0x3ff8258990000000, 0x3ff829b920000000, 0x3ff82de960000000, 0x3ff8321a60000000, + 0x3ff8364c10000000, 0x3ff83a7e90000000, 0x3ff83eb1b0000000, 0x3ff842e5a0000000, + 0x3ff8471a40000000, 0x3ff84b4fa0000000, 0x3ff84f85b0000000, 0x3ff853bc80000000, + 0x3ff857f410000000, 0x3ff85c2c50000000, 0x3ff8606560000000, 0x3ff8649f20000000, + 0x3ff868d990000000, 0x3ff86d14d0000000, 0x3ff87150c0000000, 0x3ff8758d60000000, + 0x3ff879cad0000000, 0x3ff87e08f0000000, 0x3ff88247e0000000, 0x3ff8868770000000, + 0x3ff88ac7d0000000, 0x3ff88f08f0000000, 0x3ff8934ac0000000, 0x3ff8978d50000000, + 0x3ff89bd0a0000000, 0x3ff8a014a0000000, 0x3ff8a45970000000, 0x3ff8a89ef0000000, + 0x3ff8ace540000000, 0x3ff8b12c40000000, 0x3ff8b57400000000, 0x3ff8b9bc70000000, + 0x3ff8be05b0000000, 0x3ff8c24fb0000000, 0x3ff8c69a60000000, 0x3ff8cae5e0000000, + 0x3ff8cf3210000000, 0x3ff8d37f00000000, 0x3ff8d7ccb0000000, 0x3ff8dc1b20000000, + 0x3ff8e06a50000000, 0x3ff8e4ba40000000, 0x3ff8e90af0000000, 0x3ff8ed5c60000000, + 0x3ff8f1ae90000000, 0x3ff8f60180000000, 0x3ff8fa5530000000, 0x3ff8fea9a0000000, + 0x3ff902fed0000000, 0x3ff90754b0000000, 0x3ff90bab60000000, 0x3ff91002d0000000, + 0x3ff9145b00000000, 0x3ff918b3f0000000, 0x3ff91d0da0000000, 0x3ff9216810000000, + 0x3ff925c350000000, 0x3ff92a1f40000000, 0x3ff92e7bf0000000, 0x3ff932d970000000, + 0x3ff93737b0000000, 0x3ff93b96a0000000, 0x3ff93ff660000000, 0x3ff94456e0000000, + 0x3ff948b820000000, 0x3ff94d1a20000000, 0x3ff9517cf0000000, 0x3ff955e070000000, + 0x3ff95a44c0000000, 0x3ff95ea9d0000000, 0x3ff9630fa0000000, 0x3ff9677640000000, + 0x3ff96bdd90000000, 0x3ff97045b0000000, 0x3ff974ae90000000, 0x3ff9791830000000, + 0x3ff97d8290000000, 0x3ff981edc0000000, 0x3ff98659b0000000, 0x3ff98ac660000000, + 0x3ff98f33e0000000, 0x3ff993a220000000, 0x3ff9981120000000, 0x3ff99c80e0000000, + 0x3ff9a0f170000000, 0x3ff9a562c0000000, 0x3ff9a9d4d0000000, 0x3ff9ae47a0000000, + 0x3ff9b2bb40000000, 0x3ff9b72fb0000000, 0x3ff9bba4d0000000, 0x3ff9c01ac0000000, + 0x3ff9c49180000000, 0x3ff9c908f0000000, 0x3ff9cd8140000000, 0x3ff9d1fa40000000, + 0x3ff9d67410000000, 0x3ff9daeea0000000, 0x3ff9df6a00000000, 0x3ff9e3e620000000, + 0x3ff9e86310000000, 0x3ff9ece0c0000000, 0x3ff9f15f40000000, 0x3ff9f5de80000000, + 0x3ff9fa5e80000000, 0x3ff9fedf50000000, 0x3ffa0360f0000000, 0x3ffa07e350000000, + 0x3ffa0c6670000000, 0x3ffa10ea60000000, 0x3ffa156f20000000, 0x3ffa19f4a0000000, + 0x3ffa1e7ae0000000, 0x3ffa2301f0000000, 0x3ffa2789d0000000, 0x3ffa2c1270000000, + 0x3ffa309be0000000, 0x3ffa352620000000, 0x3ffa39b120000000, 0x3ffa3e3ce0000000, + 0x3ffa42c980000000, 0x3ffa4756d0000000, 0x3ffa4be500000000, 0x3ffa5073f0000000, + 0x3ffa5503b0000000, 0x3ffa599430000000, 0x3ffa5e2580000000, 0x3ffa62b7a0000000, + 0x3ffa674a80000000, 0x3ffa6bde30000000, 0x3ffa7072b0000000, 0x3ffa750800000000, + 0x3ffa799e10000000, 0x3ffa7e34f0000000, 0x3ffa82cc90000000, 0x3ffa876510000000, + 0x3ffa8bfe50000000, 0x3ffa909860000000, 0x3ffa953330000000, 0x3ffa99cee0000000, + 0x3ffa9e6b50000000, 0x3ffaa30890000000, 0x3ffaa7a6a0000000, 0x3ffaac4570000000, + 0x3ffab0e520000000, 0x3ffab58590000000, 0x3ffaba26d0000000, 0x3ffabec8e0000000, + 0x3ffac36bb0000000, 0x3ffac80f60000000, 0x3ffaccb3e0000000, 0x3ffad15920000000, + 0x3ffad5ff30000000, 0x3ffadaa610000000, 0x3ffadf4dc0000000, 0x3ffae3f640000000, + 0x3ffae89f90000000, 0x3ffaed49b0000000, 0x3ffaf1f4a0000000, 0x3ffaf6a050000000, + 0x3ffafb4ce0000000, 0x3ffafffa30000000, 0x3ffb04a860000000, 0x3ffb095760000000, + 0x3ffb0e0720000000, 0x3ffb12b7c0000000, 0x3ffb176920000000, 0x3ffb1c1b60000000, + 0x3ffb20ce60000000, 0x3ffb258240000000, 0x3ffb2a36f0000000, 0x3ffb2eec60000000, + 0x3ffb33a2b0000000, 0x3ffb3859d0000000, 0x3ffb3d11c0000000, 0x3ffb41ca80000000, + 0x3ffb468410000000, 0x3ffb4b3e70000000, 0x3ffb4ff9a0000000, 0x3ffb54b5b0000000, + 0x3ffb597280000000, 0x3ffb5e3030000000, 0x3ffb62eeb0000000, 0x3ffb67ae00000000, + 0x3ffb6c6e20000000, 0x3ffb712f10000000, 0x3ffb75f0e0000000, 0x3ffb7ab380000000, + 0x3ffb7f76f0000000, 0x3ffb843b30000000, 0x3ffb890040000000, 0x3ffb8dc630000000, + 0x3ffb928cf0000000, 0x3ffb975480000000, 0x3ffb9c1ce0000000, 0x3ffba0e620000000, + 0x3ffba5b030000000, 0x3ffbaa7b10000000, 0x3ffbaf46c0000000, 0x3ffbb41350000000, + 0x3ffbb8e0b0000000, 0x3ffbbdaee0000000, 0x3ffbc27df0000000, 0x3ffbc74dd0000000, + 0x3ffbcc1e90000000, 0x3ffbd0f010000000, 0x3ffbd5c270000000, 0x3ffbda95b0000000, + 0x3ffbdf69c0000000, 0x3ffbe43ea0000000, 0x3ffbe91460000000, 0x3ffbedeaf0000000, + 0x3ffbf2c250000000, 0x3ffbf79a90000000, 0x3ffbfc73b0000000, 0x3ffc014d90000000, + 0x3ffc062860000000, 0x3ffc0b03f0000000, 0x3ffc0fe060000000, 0x3ffc14bdb0000000, + 0x3ffc199bd0000000, 0x3ffc1e7ad0000000, 0x3ffc235aa0000000, 0x3ffc283b50000000, + 0x3ffc2d1cd0000000, 0x3ffc31ff30000000, 0x3ffc36e260000000, 0x3ffc3bc670000000, + 0x3ffc40ab50000000, 0x3ffc459120000000, 0x3ffc4a77b0000000, 0x3ffc4f5f20000000, + 0x3ffc544770000000, 0x3ffc593090000000, 0x3ffc5e1a90000000, 0x3ffc630570000000, + 0x3ffc67f120000000, 0x3ffc6cddb0000000, 0x3ffc71cb20000000, 0x3ffc76b960000000, + 0x3ffc7ba880000000, 0x3ffc809880000000, 0x3ffc858950000000, 0x3ffc8a7b00000000, + 0x3ffc8f6d90000000, 0x3ffc9460f0000000, 0x3ffc995530000000, 0x3ffc9e4a50000000, + 0x3ffca34050000000, 0x3ffca83720000000, 0x3ffcad2ee0000000, 0x3ffcb22770000000, + 0x3ffcb720d0000000, 0x3ffcbc1b20000000, 0x3ffcc11640000000, 0x3ffcc61240000000, + 0x3ffccb0f20000000, 0x3ffcd00ce0000000, 0x3ffcd50b80000000, 0x3ffcda0af0000000, + 0x3ffcdf0b50000000, 0x3ffce40c80000000, 0x3ffce90e90000000, 0x3ffcee1180000000, + 0x3ffcf31550000000, 0x3ffcf81a00000000, 0x3ffcfd1f90000000, 0x3ffd022600000000, + 0x3ffd072d40000000, 0x3ffd0c3570000000, 0x3ffd113e70000000, 0x3ffd164860000000, + 0x3ffd1b5320000000, 0x3ffd205ed0000000, 0x3ffd256b50000000, 0x3ffd2a78c0000000, + 0x3ffd2f8700000000, 0x3ffd349620000000, 0x3ffd39a630000000, 0x3ffd3eb720000000, + 0x3ffd43c8e0000000, 0x3ffd48db90000000, 0x3ffd4def20000000, 0x3ffd530380000000, + 0x3ffd5818d0000000, 0x3ffd5d2f00000000, 0x3ffd624610000000, 0x3ffd675e10000000, + 0x3ffd6c76e0000000, 0x3ffd7190a0000000, 0x3ffd76ab30000000, 0x3ffd7bc6b0000000, + 0x3ffd80e310000000, 0x3ffd860050000000, 0x3ffd8b1e70000000, 0x3ffd903d80000000, + 0x3ffd955d70000000, 0x3ffd9a7e40000000, 0x3ffd9f9ff0000000, 0x3ffda4c280000000, + 0x3ffda9e600000000, 0x3ffdaf0a60000000, 0x3ffdb42fa0000000, 0x3ffdb955c0000000, + 0x3ffdbe7cd0000000, 0x3ffdc3a4c0000000, 0x3ffdc8cd90000000, 0x3ffdcdf750000000, + 0x3ffdd321f0000000, 0x3ffdd84d70000000, 0x3ffddd79e0000000, 0x3ffde2a720000000, + 0x3ffde7d560000000, 0x3ffded0470000000, 0x3ffdf23470000000, 0x3ffdf76560000000, + 0x3ffdfc9730000000, 0x3ffe01c9e0000000, 0x3ffe06fd80000000, 0x3ffe0c3200000000, + 0x3ffe116760000000, 0x3ffe169db0000000, 0x3ffe1bd4f0000000, 0x3ffe210d00000000, + 0x3ffe264610000000, 0x3ffe2b8000000000, 0x3ffe30bad0000000, 0x3ffe35f690000000, + 0x3ffe3b3330000000, 0x3ffe4070c0000000, 0x3ffe45af30000000, 0x3ffe4aee90000000, + 0x3ffe502ee0000000, 0x3ffe557010000000, 0x3ffe5ab230000000, 0x3ffe5ff530000000, + 0x3ffe653920000000, 0x3ffe6a7df0000000, 0x3ffe6fc3b0000000, 0x3ffe750a60000000, + 0x3ffe7a51f0000000, 0x3ffe7f9a70000000, 0x3ffe84e3e0000000, 0x3ffe8a2e30000000, + 0x3ffe8f7970000000, 0x3ffe94c5a0000000, 0x3ffe9a12b0000000, 0x3ffe9f60b0000000, + 0x3ffea4afa0000000, 0x3ffea9ff70000000, 0x3ffeaf5030000000, 0x3ffeb4a1e0000000, + 0x3ffeb9f480000000, 0x3ffebf4800000000, 0x3ffec49c80000000, 0x3ffec9f1e0000000, + 0x3ffecf4820000000, 0x3ffed49f60000000, 0x3ffed9f780000000, 0x3ffedf50a0000000, + 0x3ffee4aaa0000000, 0x3ffeea0590000000, 0x3ffeef6160000000, 0x3ffef4be30000000, + 0x3ffefa1be0000000, 0x3ffeff7a90000000, 0x3fff04da20000000, 0x3fff0a3aa0000000, + 0x3fff0f9c10000000, 0x3fff14fe70000000, 0x3fff1a61c0000000, 0x3fff1fc600000000, + 0x3fff252b30000000, 0x3fff2a9150000000, 0x3fff2ff860000000, 0x3fff356050000000, + 0x3fff3ac940000000, 0x3fff403320000000, 0x3fff459df0000000, 0x3fff4b09a0000000, + 0x3fff507650000000, 0x3fff55e3f0000000, 0x3fff5b5280000000, 0x3fff60c200000000, + 0x3fff663270000000, 0x3fff6ba3d0000000, 0x3fff711630000000, 0x3fff768970000000, + 0x3fff7bfda0000000, 0x3fff8172d0000000, 0x3fff86e8f0000000, 0x3fff8c6000000000, + 0x3fff91d800000000, 0x3fff9750f0000000, 0x3fff9ccad0000000, 0x3fffa245b0000000, + 0x3fffa7c180000000, 0x3fffad3e40000000, 0x3fffb2bbf0000000, 0x3fffb83a90000000, + 0x3fffbdba30000000, 0x3fffc33ac0000000, 0x3fffc8bc40000000, 0x3fffce3eb0000000, + 0x3fffd3c220000000, 0x3fffd94680000000, 0x3fffdecbe0000000, 0x3fffe45220000000, + 0x3fffe9d960000000, 0x3fffef6190000000, 0x3ffff4eac0000000, 0x3ffffa74e0000000, +}; + +extern "C" uint64_t __two_to_jby1024_tail_table[] = { + 0x0, 0x3e578ba33b141b48, 0x3e5b687027a87fc6, 0x3e47d77c18ed49fd, + 0x3e64b5797dac2535, 0x3e6a1dc1e9ebf954, 0x3e66597a22e0e833, 0x3e5326d6d3b52545, + 0x3e63f6666adb094d, 0x3e65ad433ddfee20, 0x3e5dc5c2d0579d8a, 0x3e6fc227dd8fb82b, + 0x3e50ec0a036a0678, 0x3e5252dd52ceb55f, 0x3e303b10def7d10b, 0x3e633ae4140b265e, + 0x3e6cef00c1dcdef9, 0x3e6f4ecbcb91c93c, 0x3e6a85604eff546b, 0x3e5d7bc1c5bc2ee9, + 0x3e6c237798156812, 0x3e370aafd8395b10, 0x3e3915a8a6df003a, 0x3e6d12d56ccee1d7, + 0x3e60dcff097ae71f, 0x3e6eac817226b791, 0x3e4ab2cec0487355, 0x3e5211e89f8619b7, + 0x3e47b2a5894c3794, 0x3e6d83407ebcd45f, 0x3e5ff05d8654351e, 0x3e6d76f0d641b21d, + 0x3e48ac2ba1d73e2a, 0x3e5480116aa51f2f, 0x3e53c2fb09996d50, 0x3e44ec10b242a8b7, + 0x3e6c783f1151a425, 0x3e5f89b050324159, 0x3e6f4c80f79685bf, 0x3e5675e532de0a3f, + 0x3e63bbedbb8db880, 0x3e68fb3aa173f7e8, 0x3e6b24a92589ea67, 0x3e6a6410ba6f5125, + 0x3e66e5506c4c8cd1, 0x3e60d44ee223dd7a, 0x3e50b9f4be45b9bf, 0x3e6dab48c3f43342, + 0x3e60eb37901186be, 0x3e32465f18ad29db, 0x3e61f0127e0ee8f9, 0x3dda3f89a3af8986, + 0x3e59981f7e97f9c8, 0x3e6859061ad6fdb9, 0x3e3701715c5f4984, 0x3e591b75db2d8400, + 0x3e658de7068a43c1, 0x3e6e0cf4c6b3e2ee, 0x3e48dcb8a9c01f5a, 0x3e5c71c9b6fd090b, + 0x3e663e72325745b2, 0x3e6e7437377f3ebc, 0x3e4c1a7293764302, 0x3e602212e710ecd7, + 0x3e69f3121ec53172, 0x3e42986888250c15, 0x3e6067b27da51fde, 0x3e6d646a76702f53, + 0x3e5791b2154f9890, 0x3e6bc19cf3460b11, 0x3e5af6b94ab1757f, 0x3e222c65358a1e6f, + 0x3e66e48fee80f6e1, 0x3e5ddaee504e2734, 0x3e52d482e624c9ea, 0x3e4a1ef01352572a, + 0x3e49caef5c87d643, 0x3e52b03b52543578, 0x3e5ec98c01e181a9, 0x3e68c5a12ca6e25d, + 0x3e469e8d10103a17, 0x3e6637c8299ffabc, 0x3e5546271898a049, 0x3e38b4874375a83b, + 0x3e6fbf53895b1232, 0x3e194ed155c28cc4, 0x3e499473669fa755, 0x3e60bc7136873bb9, + 0x3e6ffda635e46412, 0x3e6455f6420cdf93, 0x3e5be54738bdf791, 0x3e5a01f0bd4b8312, + 0x3e61ae467c751bac, 0x3e6c27e7c4863a25, 0x3e59367bc42862ec, 0x3e39ad92f1c6b500, + 0x3df25b50a4ebbf1b, 0x3e3cae1fa1b07d74, 0x3e5b6cb703c63407, 0x3e6eb406588b1e90, + 0x3e66bc556b1add58, 0x3e65fce1928ff5aa, 0x3e6ca34b8f576a36, 0x3e55ba781558c3c6, + 0x3e1b0c72fee4aeb5, 0x3e6ec27ab62c5a0b, 0x3e43250744b1e1dc, 0x3e631a8143238190, + 0x3e53c812abd1dee1, 0x3e52a76488bfc77b, 0x3e61975c3bd792f7, 0x3e36e77aeb5f66f2, + 0x3e6d525bbf668203, 0x3e225996e9fa677c, 0x3e5d0950dfbfa37c, 0x3e4676430504efdf, + 0x3e4a79896e46e17c, 0x3e61b53533b4cd1a, 0x3e4c40a4f01821b0, 0x3e4b759996ee4d58, + 0x3e614b1ca24901ab, 0x3e4a1e0f93097e9e, 0x3e4b03708cfdf453, 0x3e62256d583f7602, + 0x3e51c70f0818f23c, 0x3e5653055c3f9782, 0x3e6925bee6860ba8, 0x3e6306a44743ae75, + 0x3e68faa2f5b9bef9, 0x3e5660664815b0ae, 0x3e53abaa2500be0f, 0x3e651a1110eff7c7, + 0x3e5a56ef00427900, 0x3e6238a0d333af2f, 0x3e41c0b64413ab6a, 0x3e400319565c4a82, + 0x3e61191bd3777ee1, 0x3e57cfcdaa4b513b, 0x3e649be83e7a5306, 0x3e56c7d21c1de6ab, + 0x3e606eba5ea556ec, 0x3e3f59ab447c3e7f, 0x3e4820ee0c5fbe16, 0x3e66f4b625e9b85d, + 0x3e66df96ea796d32, 0x3e47df5e35b75ed4, 0x3e41b1e7c02474f4, 0x3e626c8819921a35, + 0x3e60271438bdfc2d, 0x3e6dcb38a51a1a99, 0x3e6b8817e0760e4b, 0x3e5319b9309c0f58, + 0x3e5011734e6ac79d, 0x3e672aea1641804f, 0x3e6722b11e74ce25, 0x3e503eb4545446b1, + 0x3e54a071ad009778, 0x3e6de4a8f4c5d8a8, 0x3e3860745f297e2f, 0x3e69f5d5d9d0d8fa, + 0x3e368b9aa7805b80, 0x3e6dce63ad8b79de, 0x3e5638579e74bbfb, 0x3e55d4b1c49f86a5, + 0x3e6d68804d481140, 0x3e3631fdb1b6a3de, 0x3e6b333d0434c7ec, 0x3e4b7c99833873ca, + 0x3e47e6c8e5c40d00, 0x3e68b29f40dc7026, 0x3e6f39b4708f2585, 0x3e69bec10a36f854, + 0x3e50e3393240adb6, 0x3e57044de74c1d2d, 0x3e390241e50a8f3e, 0x3e5ef7e1c9b3fb10, + 0x3e60c519ac771dd6, 0x3e4caf0e91bed019, 0x3e62dff82ffbbb3c, 0x3e6411c906056d9d, + 0x3e55e2a0653592d3, 0x3e67aeb0185f561b, 0x3e6a7a1371fe29a8, 0x3e6383ad539c2ddf, + 0x3e37ddc962552fd3, 0x3e5224f58ef3e8d7, 0x3e47e0f939b283a8, 0x3e69dd5849aa9ed4, + 0x3e43c89689d34fb5, 0x3e4d9c2e90e37e0b, 0x3e26c77fe0521ff5, 0x3e6332e0c3fd0501, + 0x3e6ceac470cd83f6, 0x3e6ec4a9e721f548, 0x3e68f12073191430, 0x3e57417f9774965a, + 0x3e670428146b3f32, 0x3e6b4c01de659b96, 0x3e68a8fe2a2d1ecb, 0x3e5e97acd20bcfe9, + 0x3e6f654c7e6b0557, 0x3e524c55830a8778, 0x3e597e87fd447d94, 0x3e54c2e6f15764c6, + 0x3e31ece754f86893, 0x3e6484ac89054394, 0x3e26797036ae5806, 0x3e522eb30bb0e65e, + 0x3e5789f37495e99d, 0x3e53430b9459a58e, 0x3e36f0a2fe777b95, 0x3e67abc4a7e20230, + 0x3e50777ca5e067c0, 0x3e64bf3196d6fcdb, 0x3e6d675730414460, 0x3e332b83210e0cc1, + 0x3e3f5638096cf15d, 0x3e31456b0abad3c9, 0x3e6d507e6b49f37d, 0x3e65939d93e44a73, + 0x3e5646edbf699c6f, 0x3e6e317ee475667e, 0x3e5dde65950f41c2, 0x3e6d8e184e711fd8, + 0x3e547f7b84b09745, 0x3e6535ba0f81452c, 0x3e6ea1acb7cb1afd, 0x3e4ad4f75cb50100, + 0x3e5b443c4a6a8bce, 0x3e639a06f684d5fa, 0x3e68ceba3e4ff11e, 0x3e6d72028fdb6e5f, + 0x3e2b5b31ffbbd48d, 0x3e472e9f1a4fa958, 0x3e53cb8a0029cb8e, 0x3e5c6befddfa19d0, + 0x3e62ee365d57f5d3, 0x3e68407ebe3e7dba, 0x3e6e5ed82f5719c6, 0x3e45ed49e959aa30, + 0x3e5b900c2d002475, 0x3e6777142a27cd70, 0x3e35d534619676be, 0x3e5f89df8b32bb28, + 0x3e6ec82b12e8b680, 0x3e5fed38cb8a60a7, 0x3e3c1483336515dc, 0x3e699e5c75391066, + 0x3e627c5eac23941f, 0x3e5c9dfbc08f21e4, 0x3e5a915346cc4af5, 0x3e5f37b48ad3c49f, + 0x3e657b10d5eac3ab, 0x3e6f18d725b26e52, 0x3e594f7f90815f95, 0x3e6e5a66155041e4, + 0x3e64636e2a5bd1ab, 0x3e5deb09d8469390, 0x3e5c86c01062c0b4, 0x3e627fbdf661685a, + 0x3e6bdd65fa656690, 0x3e551e504a98d44b, 0x3e6ec7dd570928e5, 0x3e68ba673ff8df2b, + 0x3e6899b0626a739e, 0x3e6e98ac1425deaf, 0x3e55d4acffe7abed, 0x3e6dc1b4a725bb73, + 0x3e6751d4631dd0be, 0x3e67cdcc66d7ae36, 0x3e6f68bc4070fe38, 0x3e5cab98b564f8c7, + 0x3e4320b7fa64e431, 0x3e3798daa7010649, 0x3e5213aecf139089, 0x3e673fae236a7c4b, + 0x3e5b8fe8b3652c53, 0x3e59ac0f82f228d7, 0x3e649d4ef94677f7, 0x3e4544e6227f9687, + 0x3e6f253fe1928c47, 0x3e32671b11fa7ae7, 0x3e5df75caccd6c5d, 0x3e4594cfe3d47eae, + 0x3e46f441d63cebb6, 0x3e6036e8ea1ec475, 0x3e4419ada17e20a7, 0x3e417d3bddb2a0d0, + 0x3e5ceaa72a9c5154, 0x3e3be211c4360175, 0x3e3d3f668d0f6c10, 0x3e5e585c9984a42b, + 0x3e48f3aa4cc146ac, 0x3e521c1d19d1ee21, 0x3e67d390222d1dff, 0x3e62c16e3d10e22c, + 0x3e6a0bb0cb0b5396, 0x3e5bccd17d0ce041, 0x3e5d0b6020dec4fb, 0x3e6c1da9c1c7067e, + 0x3e66e281dd32b2d0, 0x3e6f086d788d4831, 0x3e64c3aab678862e, 0x3e684880c7eea56a, + 0x3e53967fdba86f25, 0x3e530082f51499d4, 0x3e679be7d380df9b, 0x3e64529e72c984bd, + 0x3e6fd8d9e8aa6337, 0x3e6a6317dd31706d, 0x3e40977c471fcb75, 0x3e6d55bf62c64ab0, + 0x3e489d47242000f9, 0x3e6ecf385b8018ad, 0x3e4e08794336c259, 0x3e0d2e00343736bd, + 0x3e53b785cc7fa342, 0x3e3f602d01e27c72, 0x3e5db49fe7d2ae92, 0x3e55b6f59c02469c, + 0x3e682468446b6824, 0x3e66ea0397d3daff, 0x3e4d8504d503fb5b, 0x3e537e3d6f567009, + 0x3e6e38a2e9942672, 0x3e440b771a791993, 0x3e6e52e87d24d7f0, 0x3e54bbcadfa81a3e, + 0x3e52b2006e82fdc0, 0x3e6b796da384e8be, 0x3e1e8d77ba256df3, 0x3e69ff41ca0d9656, + 0x3e4b3d0121bddf8b, 0x3e4e6703dc4fd424, 0x3e6c9426d39a27ae, 0x3e47cf7872f610ea, + 0x3e3f72e29f84325c, 0x3e66b9203ef7a494, 0x3e6e89b1e9848bfb, 0x3e6b95a2a6d1a206, + 0x3e5c251a267b9d24, 0x3e66361515e88cf6, 0x3e6435e7e24e448d, 0x3e508f77f3c9d17b, + 0x3e62a1512db8e088, 0x3e637870a00a35aa, 0x3e5605d98bd416b5, 0x3e6976a168d85cbb, + 0x3e6f0973a86202fa, 0x3e6bf151fbbf0341, 0x3e6064343371246a, 0x3e6c981b7ae2cca0, + 0x3e18624b40c4dbd0, 0x3e6d1b2cb6f4906b, 0x3e61d687d78e4e57, 0x3e6f2b4a631a8b08, + 0x3e453e918f9e6f9a, 0x3e41e73d23ae3cab, 0x3e6ce00de76501e8, 0x3e5d7158f8f87ca8, + 0x3e6a3a00aee4a25f, 0x3e6f9a69907e4ea2, 0x3e6f104f9ff81dc1, 0x3e68d224ca71e42c, + 0x3e5a2cc8da3df0f1, 0x3e6c139356e90433, 0x3e4800ff284c755b, 0x3e562602fbba50d4, + 0x3e5704f3404f068f, 0x3e4e154b5c5be2af, 0x3e6f524142b8fc8e, 0x3e6320027ea83152, + 0x3e392aed1d89aed4, 0x3e5f324692ef792a, 0x3e68b22d881beb7d, 0x3e6ea75ff9e00531, + 0x3e2afa7bcce5b17a, 0x3e300fdba2fc457c, 0x3e6fd55b4b20f80e, 0x3e6b60d0f45baf9d, + 0x3e64db6fadbb691e, 0x3e58f8a881ebe41b, 0x3e33d5282b96ab17, 0x3e670d91e1f34ec2, + 0x3e54d8a89c750e5f, 0x3e6cce2f54b61b46, 0x3e5cd4df284dd61c, 0x3e6f786b414a336c, + 0x3e602f822882f14b, 0x3e18e3b5f071cfb7, 0x3e6176b0d6f7d869, 0x3e33adc1e17a0458, + 0x3e63fbba1ac766de, 0x3e490119395bb8c9, 0x3e697af654189a82, 0x3e5bc6da992d729d, + 0x3e3d8abfeab6a0b4, 0x3e6b1c6cd285acef, 0x3e645c6be0a3854c, 0x3e5f523dcc615e0e, + 0x3e5a74b29ab4cf63, 0x3e5a8ff05b4ffc78, 0x3e6009e24da84302, 0x3e65b808249f4248, + 0x3e6e8a63dc344937, 0x3e5571f2a4406abb, 0x3e6a7bd619dc0ed4, 0x3e5c1622fc9fd9f4, + 0x3e467b320e0897a9, 0x3e26f31e846c8ad6, 0x3e2b47627ef62368, 0x3e4a9b5defec34e6, + 0x3e607e9dddc6cce5, 0x3e6f741b083e3293, 0x3e63bfaa798c4e6f, 0x3e5b3362e999d66d, + 0x3e5a753e077c2a0f, 0x3e62daebf871eb59, 0x3e6eb31aef00be29, 0x3e60fbb84f3b7669, + 0x3e53dab49cbc9369, 0x3e538141e18772d7, 0x3e60ae360b97dd2a, 0x3e6eeecd468bf8bc, + 0x3e64bb241d8a5d8c, 0x3e624c01e26a97ab, 0x3e67da37bea5e667, 0x3e467a82d4300257, + 0x3e6bd221a378248f, 0x3e6aada9448673ef, 0x3e3351818a4cd91b, 0x3e6340b8e300c4dc, + 0x3e5ad49f699bb2c0, 0x3e61200ae56c09e3, 0x3e6e9b0a98e6a7d7, 0x3e661478da504852, + 0x3e67c5899d7a339c, 0x3e3f3bd6056106d3, 0x3e6ab3940e5c3e04, 0x3e6c63273ee78411, + 0x3e525f1ff494af0b, 0x3e25233d9d9755bb, 0x3e441209a7ecb170, 0x3e647ff52be0e2f1, + 0x3e5ffc1f2e81d312, 0x3e67b85f1c109984, 0x3e57d0f6487d81a5, 0x3e59900a2adcb475, + 0x3e6a90a852b19260, 0x3e657c1a3e45199a, 0x3e6dc41a3b4bc29b, 0x3e63a271af8a6e06, + 0x3e6750f4052442f6, 0x3e5212fd58ae68fc, 0x3e520bf23a71a88f, 0x3e678054d973723c, + 0x3e64b28d6e038963, 0x3e1ad50e9eaf3e01, 0x3e6c26b597239097, 0x3e4b733a37d16cc4, + 0x3e2331725194ac2c, 0x3e56c77a789b45d2, 0x3e46a3e32456db08, 0x3e603d0bd87e7360, + 0x3e56b48521ba6f93, 0x3e673af3338ffaa3, 0x3e64197e1ebdbd81, 0x3e31826e78ba6fd8, + 0x3e2b9d6e19854887, 0x3e62f0981548b132, 0x3e660f1a4cfe262a, 0x3e569fe1223ca0b3, + 0x3e62edb81160edeb, 0x3e5a46304d24e5c3, 0x3e6a2ac25456ebce, 0x3e6a3f724aed2eac, + 0x3e5b37dbd1e4b3e5, 0x3e647b053d25a1ee, 0x3e5e2f251058d8d0, 0x3e6dac7a3e56baa9, + 0x3e0d2ac258f87d03, 0x3e67ab1dca47926d, 0x3e3c56acd779649f, 0x3e413b7f401d952a, + 0x3e6a3253fac23886, 0x3e45c14faa74aaac, 0x3e49102ebc9f62ad, 0x3e6ce8b199cad6ed, + 0x3e53330c7f1dbe1c, 0x3e5923a8f5c89918, 0x3e4833c5b5aba188, 0x3e66463c81ba03ab, + 0x3e6d791f6d28e152, 0x3e6be10e31976ede, 0x3e61b9871f374c72, 0x3e6f3e12d65523fc, + 0x3e42a91124893ecf, 0x3e31cdc5ebf67f3e, 0x3e682817cec39032, 0x3e4ac44dbe33f068, + 0x3e5c20cfd70bc66d, 0x3e5d03b7d26559b6, 0x3e508280d779b6ba, 0x3e6b8a70d4bedf04, + 0x3e5132a5cc20715d, 0x3e5f53ad8723d869, 0x3e60f7f6f4fb42a5, 0x3e597f70cf4db8b0, + 0x3e39e953830097b3, 0x3e64ac66cd30ab74, 0x3e24991a72ed817c, 0x3e52a1b328971532, + 0x3e59fcef32422cbf, 0x3e591d5e558445ea, 0x3e507b9c6111dd77, 0x3e020b4179b87a6a, + 0x3e64ea2e7c3471ea, 0x3e4980ff72055486, 0x3e64e6d8e965072a, 0x3e174f7c19f3b303, + 0x3e542f6afbb5daa6, 0x3e613b1cfa9c008b, 0x3e66615411f4dd60, 0x3e69c70701669d4c, + 0x3e6ba8ec8ae3d54e, 0x3e6c43c5f6a34ef8, 0x3e6bd45f14f31260, 0x3e6a978e400bc107, + 0x3e68ca345de441c6, 0x3e66a93ce205bdc4, 0x3e64719dcf5fee9c, 0x3e626057ba1dbd9e, + 0x3e60b275c97a345b, 0x3e5f4a1b732b7cde, 0x3e5eea7fba97795b, 0x3e606037200869ac, + 0x3e62a329079f0fc3, 0x3e667b55b6209097, 0x3e6c2607ebb23e26, 0x3e3f04a843282bff, + 0x3e5bd0ba1c19d645, 0x3e6a7acaa218d916, 0x3e53aaa61ed57da4, 0x3e6c3576483002f4, + 0x3e61d8bee7ba46e2, 0x3e55f98468b0f8c0, 0x3e4f7c8084c13489, 0x3e517b06a02fa8ea, + 0x3e5bab4226df55fd, 0x3e6765396ffd44b2, 0x3e46a85c7b1683da, 0x3e68e20f8ee84d1f, + 0x3e614b02e77ab935, 0x3e5e45b812c7be47, 0x3e62a79091383c65, 0x3e6c1720d9161e22, + 0x3e575f2ff5047fd6, 0x3e2af0bd044bd0fc, 0x3e6e539cf846549f, 0x3e2db76d56e0024f, + 0x3e59099f22fdba6b, 0x3e6e8de81ef669c8, 0x3e68350c3aeb1382, 0x3e69b8926eeb19ed, + 0x3e3ab6e096de1dc6, 0x3e654e554ed8e709, 0x3e5fbaea3a2989ca, 0x3e6342bd4bb837d6, + 0x3e6fbcba7ec335c0, 0x3e658a0431eda50d, 0x3e64e93cba888524, 0x3e6e1911495f6a58, + 0x3e615839ec9a4d43, 0x3e5dcaf3233f5b53, 0x3e66ff9e06f708f1, 0x3e53cafffc57486f, + 0x3e4f580c36bea881, 0x3e611015b2bf9c58, 0x3e474ac54d1863af, 0x3e497368feffcded, + 0x3e62ed9fb520a254, 0x3e578837bd6dff0e, 0x3e611f73d8125e06, 0x3e39f6bd773f96ab, + 0x3e330c1327c49334, 0x3e5d8d73e3ed8441, 0x3e515b9e8ada3c5e, 0x3e60561e48a513a0, + 0x3e47fc378237bb7f, 0x3e53d01fdf487d4e, 0x3e6c50a157d98b5e, 0x3e6d7849fc7c6314, + 0x3e5b3d398841740b, 0x3e5a066f35113fae, 0x3e6be5c3728d497f, 0x3e6a85f448086ff4, + 0x3e524712437c0772, 0x3e4ff9304d18d508, 0x3e6756123ef7d252, 0x3e676abbd7d2f855, + 0x3e50f86846d8379a, 0x3e5594e2f7aec9b5, 0x3e6e9575519460f3, 0x3e407530b5e82748, + 0x3e6ba20db2a321b8, 0x3e458f72816b93f9, 0x3e2a2e6d40a11129, 0x3e609f654b2440ef, + 0x3e62999c25159f11, 0x3e4f476a94c3b42e, 0x3e60887b349de0b3, 0x3e59fbc6c88fae0d, + 0x3e6d7283eeccdcd2, 0x3e3136c5d368690a, 0x3e6b5b68dafa4598, 0x3e52a18d2790615b, + 0x3e588f1eb3394bdb, 0x3e4201af528180fd, 0x3e623c0fe2500a49, 0x3e65bb3a976da0fd, + 0x3e5e7d6c83e458b7, 0x3e6f07586affce83, 0x3e4558076350a430, 0x3e335cf485d8c6ab, + 0x3e668925d901c83b, 0x3e2ef9a3aea17d5b, 0x3e43802612797726, 0x3e6f9b8ccb257bb8, + 0x3e6263486c574b5f, 0x3e6d786c10d161fb, 0x3e21c32adec2a736, 0x3e6d8fe287b05664, + 0x3e6314cd32cca618, 0x3e2ec4f968c07787, 0x3e54afa3dd98181a, 0x3e59318f9be76c1f, + 0x3e51e1603dd53954, 0x3e6fa11527106770, 0x3e60eb8c8834a11b, 0x3e6d11b7428ee199, + 0x3e415506dadd3e2b, 0x3e4bdf8e9e7de4b7, 0x3e44ed80f22e1327, 0x3e6f6186030bb8b5, + 0x3e65ac2ef0f65af8, 0x3e50ba80ccc3d13f, 0x3e67b6ab2f9fa4d4, 0x3e3fd35c39b3fded, + 0x3e5ad5122fbcaa87, 0x3e644916fe7b83bf, 0x3e68d833cc1adaa9, 0x3e6b5a0987ede14f, + 0x3e6c10cdb14775ad, 0x3e6b3ec14198c36a, 0x3e692630ae6e9315, 0x3e660973eb6ef1a3, + 0x3e622aee6c57304f, 0x3e5b9a1e4df479b3, 0x3e5264a12a7ea491, 0x3e4274e2dc840895, + 0x3e0416452b25950c, 0x3e6c8e4ec001cb92, 0x3e6999c25752e4a7, 0x3e67b56806e51659, + 0x3e6723ff8b114c37, 0x3e68285432454643, 0x3e6b053cdf050f94, 0x3e6ffd9c09eccdf0, + 0x3e4d517f0ecbaa06, 0x3e614c81b72a93a7, 0x3e6e29072b4697f5, 0x3e5c5a020a3934ea, + 0x3e29b8bc9e8a0388, 0x3e68b7cfa110f744, 0x3e63c500562a76ed, 0x3e63065d5afd19b3, + 0x3e66bf31c988f0a6, 0x3e6f32d4660b7068, 0x3e59494f420a2fbb, 0x3e6f5819993f7097, + 0x3e6790a41dd36907, 0x3e6591ccb0300890, 0x3e699f2486217d82, 0x3e3fe2445ec42850, + 0x3e64ece165f22d35, 0x3e596946e6ffe201, 0x3e572e9da0205d3d, 0x3e61d8af55b6f7e9, + 0x3e6fbc9c9f173d24, 0x3e6586fa096c5211, 0x3e637bb6b693cd70, 0x3e69decd8f17c2f2, + 0x3e51e88a8872af6b, 0x3e2003051fbb1575, 0x3e3235680979fd56, 0x3e5a17cad2fac24b, + 0x3e2940f737462137, 0x3df1b66d49eb4e60, 0x3e51fc965eb29f67, 0x3e6c6903d94d6af5, + 0x3e6aa7fc19113d8e, 0x3e3ffd285360d19d, 0x3e68b47ba659b245, 0x3e690b08c5189217, + 0x3e451f8480e3e236, 0x3e6dafa554ac0a01, 0x3e34380f269af45d, 0x3e6412af3a90ebc6, + 0x3e629771a9574a0b, 0x3e6e5a19703a5548, 0x3e679f82bc002979, 0x3e6eac95a9327acd, + 0x3e63c64646304995, 0x3e673194953ff1ff, 0x3e5267191d432f73, 0x3e54228c4543db09, + 0x3e6a0fe53bad58c5, 0x3e697499c063712f, 0x3e51093f2b55b910, 0x3e4e14fa83161aa3, + 0x3e66bbcac96535b5, 0x3e666da3fbc07aac, 0x3e4b80d8aa9ff964, 0x3e50b1f2a3385567, + 0x3e6b1d7176e330c7, 0x3e6f732ead9f6b29, 0x3e659fcd17e61d0e, 0x3e6de8f4e8d68e18, + 0x3e68945a66b182e4, 0x3e479ef7b3c44996, 0x3e48a3afb98360ad, 0x3e699dbcf7368393, + 0x3e1182b5e5587fa7, 0x3e6b39e6db92921c, 0x3e53da5ac2f1acb5, 0x3e59d7e48f70d8fc, + 0x3e41f12ae45a1225, 0x3e60e458065d60f0, 0x3e626a47a8777233, 0x3e52a8a685159fd3, + 0x3e65e8c0a4150f56, 0x3e686de1cb077789, 0x3e612a14e5e39328, 0x3e08f1157607fc1c, + 0x3e49859ac3796fd9, 0x3e3b4bf61ebd85e7, 0x3e67c29b94abbc34, 0x3e3d9ac32335bd49, + 0x3e4e0972c560f30a, 0x3e3bb2e1c9934455, 0x3e67d616fb295ca7, 0x3e43a164e84c7b13, + 0x3e55e7f6fd0fac91, 0x3e547fc53204d0b8, 0x3e3897fd200b92f6, 0x3e65b4500628a2d1, + 0x3e3356eba313863b, 0x3e52fb7be80463ea, 0x3e566827b9cd1ec4, 0x3e4f54376e716370, + 0x3e6fa7e6f381b72d, 0x3e62f3e680e9bd30, 0x3e300301da02be90, 0x3e5a29686e5d3a12, + 0x3e64784ee8bf79de, 0x3e6872a92584bf8c, 0x3e694b4826bc8fd5, 0x3e6749bd8b77288a, + 0x3e62b5a75abd0e6a, 0x3e57ad600b6b2eb3, 0x3e37a4734e6ea06b, 0x3e685705d2dfd931, + 0x3e588bcbfab4d03f, 0x3e6f090b1868f73d, 0x3e60e85dc81c1a02, 0x3e315e993c924619, + 0x3e631b6ccb210856, 0x3e3ff9c613f38c66, 0x3e651f519aeb18b0, 0x3e4b0f79857153db, + 0x3e693512a4a6e812, 0x3e59765cef540bcc, 0x3e29e7e737abc6fa, 0x3e68275bb98fbbf9, + 0x3e609e2bf5ed7fa2, 0x3e5696c2c2a5ac9c, 0x3e50eef586cb9828, 0x3e50d606e9c1e858, + 0x3e56dd26c3822708, 0x3e61cacf0b732bf5, 0x3e6bc8678b02e839, 0x3e5360352692d162, + 0x3e6bcab2731c7102, 0x3e626106177df6a4, 0x3e5b77f21b9820df, 0x3e5c48f70be28e76, + 0x3e63e38a5495479b, 0x3e6f422ef54df4cd, 0x3e60897f8cd0dcf0, 0x3e50053dd64a1d0e, + 0x3e47daf237553d84, 0x3e555e29444569f7, 0x3e6674f007379e66, 0x3e532348a0b61f79, + 0x3e413a4f1c91bd35, 0x3e4bd4b5b6be91ce, 0x3e61ceed00d1983d, 0x3e44956be9345fb8, + 0x3e2420c930819679, 0x3e49ba8f15058656, 0x3e64f4cf4ec68ce2, 0x3e5a3c956654f396, + 0x3e5e69bc7bf82b4c, 0x3e6b825f04fd8ba5, 0x3e6250aeea5bd62f, 0x3e63e9bc9ee6b295, + 0x3e12f074891ee83d, 0x3e68a40c4f414c6b, 0x3e6c596bc9db4757, 0x3e5803882b51d09b, + 0x3e4f9d1037f1ecee, 0x3e6054276a22db24, 0x3e464adafe7861a8, 0x3e4fb51e1182080f, + 0x3e67ae3c110811ae, 0x3e652003a31a3b2b, 0x3e11a34be803d426, 0x3e6a400953831e27, + 0x3e341b33cc4eb4ac, 0x3e69a1d4b8d57ba8, 0x3e6fe603e8ff9783, 0x3e659ab0d3f82daf, + 0x3e6b0aa538444196, 0x3e6080b7cb3cc0a0, 0x3e6647cc3b4dcff1, 0x3e5955a6646cfbc7, + 0x3e63f4ca5748d74f, 0x3e58e178a354c157, 0x3e6669c0ca94f31f, 0x3e622afc6f97fd8f, + 0x3e6fffa0f4da29bf, 0x3df9768badb2c9a1, 0x3e63102c9f375085, 0x3e68e2b861e80d5a, + 0x3e61f5f644897839, 0x3e6e95593e1cc11a, 0x3e6f0c6159cc6aba, 0x3e63a69bb930ae13, + 0x3e6cafa296944270, 0x3e6a731d47398a32, 0x3e5a79807b40489a, 0x3e65584d0bcae29c, + 0x3e63119265862511, 0x3e4ad1b08aba6763, 0x3e608cc341786286, 0x3e60e68de8b69e50, + 0x3e501b9ed446b2f1, 0x3e664e9844a7e1ec, 0x3e6bf50626a5812b, 0x3e694d43f03e9b90, + 0x3e5d47136b406a09, 0x3e6c441cc14bdb33, 0x3e33da7cb30faa43, 0x3e29581f2ec795fe, + 0x3e69df20d22a0798, 0x3e57494cddb2d5e6, 0x3e67329a45858012, 0x3e6cd59116d181d1, + 0x3e6cda2ce9c5bbe1, 0x3e678d1d0e1ca374, 0x3e5a763c3d20abfc, 0x3e6e30fa03287e2a, + 0x3e55770fe7113e25, 0x3e6327ac793ec5c8, 0x3e67c2597212a140, 0x3e68d88e125500bb, + 0x3e66b756e72fb8b2, 0x3e61abcdd8f5ee5b, 0x3e5406345ae993bd, 0x3dd4e114891e8f2d, + 0x3e640f12f71a1e46, 0x3e49794380636337, 0x3e6745871824f0af, 0x3e4c487f6cd870b2, + 0x3e661192d0aab1b1, 0x3e424594366caa9a, 0x3e62df29172e0d8b, 0x3e2487ee4ec3f51f, + 0x3e601b13e315bc24, 0x3e6fa4a2f4f6b790, 0x3e6032f4773d243a, 0x3e309ef212751927, + 0x3e659543ac9eda9e, 0x3e560a2b1a0c69c4, 0x3e358a91e8c83466, 0x3e6ce8059b7f1ce2, + 0x3e69f7490e4bb40b, 0x3e6a2d438555d54c, 0x3e6dd8297c911d51, 0x3e4518f3f99baa82, + 0x3e60c5cda60ff43d, 0x3e14a7143dc91304, 0x3e6532e8b5e7b4d8, 0x3e5d7aac7b812921, + 0x3e5b260e5eee13e7, 0x3e62028f1d9e9e99, 0x3e6c5a8f39bc4ce4, 0x3e59d36cad45e444, + 0x3e3ff60756814b6f, 0x3e2e87912c98f6cd, 0x3e4bd6da4de9bbdc, 0x3e63755edc91d6be, + 0x3e4ed9942b84600d, 0x3e401f27aaeab9c4, 0x3e517137f4a3224c, 0x3e6617f76c18ed08, + 0x3e58ea0c524890e7, 0x3e583dffa710209a, 0x3e656529c8ba8e9a, 0x3e512dae47ea9547, + 0x3e480da3025b4aef, 0x3e5bf49a7909df72, 0x3e19601f51e84699, 0x3e6ec50e24d249a7, + 0x3e5070195e35aad7, 0x3e6d73a25949dfc1, 0x3e6ec782b1b8d2de, 0x3e5906de2f3c704f, + 0x3e4bdcdaf5cb4656, 0x3e5ce56d56ae3acf, 0x3e3a2ece0bca216e, 0x3e470262e9edc4fb, + 0x3e6632fa2dda95ad, 0x3e64ed12925595cb, 0x3e31f82202a70ab7, 0x3e6e78ff74527658, + 0x3e53d684a2849d88, 0x3e4398638bece417, 0x3e5f73ba414036d2, 0x3e556dedde134517, + 0x3e662ddc23305ade, 0x3e626f108497354f, 0x3e6fcb25cfb67724, 0x3e6e92bbb8671525, + 0x3e5e2cffd89cf44c, 0x3e61a72e154ab8f5, 0x3e4a563f6f7ca75c, 0x3e5c64f9d342e723, + 0x3e519db5d74e003c, 0x3e66bb9d94f2dd19, 0x3e6849c6a0e407f8, 0x3e5b94cbab484c52, + 0x3e678e990696a916, 0x3e65e78c16c85e3d, 0x3e524cf1f6bed6a6, 0x3e619ca7be0bb695, + 0x3e5f36dcfeef76b8, 0x3e3ba18bcdce57ae, 0x3e5af0c6058b73d4, 0x3e5bf3071dbdf35d, + 0x3e452486cc2c7b9d, 0x3e63b8da2784d43f, 0x3e699a57ca2f39ed, 0x3e673f53a109b201, + 0x3e59f329b94832f2, 0x3e6b1af0da936e48, 0x3e2f54b27e6e24e0, 0x3e2da95839d5b5cf, + 0x3e6b1ccfe11b6062, 0x3e5c1c10d542e779, 0x3e6b005b83c2dad8, 0x3e322f9e5ee6991b, + 0x3e40c4288238d1b5, 0x3e213e5a02f80c27, 0x3e6940dbac4b61db, 0x3e5a149fd82f2852, + 0x3e6cc2b44eee3fa4, 0x3e5179121d8f7cad, 0x3e614a5cb2b4d0cd, 0x3e66becc11594075, + 0x3e696c825366effd, 0x3e69a638f61959c8, 0x3e67beb7cdb17c92, 0x3e6408d507f23646, + 0x3e5daeea5d3a1a5c, 0x3e50fb1653decef4, 0x3e24e18432031477, 0x3e699c2c26ddf128, + 0x3e61bae4e7cd4b4c, 0x3e53fade020fe6a5, 0x3e35b82ac4e06739, 0x3e6c3af1420bfb2b, + 0x3e66dc8a80ce9f09, 0x3e62ef374ad0048c, 0x3e60c66c4af27f39, 0x3e60b5aca3903595, + 0x3e631089f0fd1bda, 0x3e682aa44c095dfb, 0x3e05ea93210e3f4b, 0x3e57d6b2177e878d, + 0x3e6b397c27122769, 0x3e5d2bdb84bd8e17, 0x3e49525a2a575dcb, 0x3e364b6dc1df327b, + 0x3e4121e447bb455d, 0x3e564b99ddd75a89, 0x3e67b58c39951cc8, 0x3e5497d0e3f42f1a, + 0x3e39e90d82e90a7e, 0x3e36ec353ddf898f, 0x3e5302e950af1290, 0x3e677d57a23cbe87, + 0x3e5a4b544f9a6234, 0x3e559deae0916a68, 0x3e60cdd15a572c7c, 0x3e6f76e46e92d018, + 0x3e671ee3e212eb75, 0x3e681a9398f707d7, 0x3e35f631479446b3, 0x3e67605cdbd8b9bf, + 0x3e665447b2294c07, 0x3e6fef85659d46d9, 0x3e6487236bb467cf, 0x3e64703df842f4ee, +}; diff --git a/src/native/clrmath/src/opt/expf.cpp b/src/native/clrmath/src/opt/expf.cpp new file mode 100644 index 00000000000000..3457a6dfa9d168 --- /dev/null +++ b/src/native/clrmath/src/opt/expf.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + /* + * ISO-IEC-10967-2: Elementary Numerical Functions + * Signature: + * double exp(double x) + * + * Spec: + * exp(1) = e + * exp(x) = 1 if x ∈ F and exp(x) ≠ eË£ + * exp(x) = 1 if x = -0 + * exp(x) = +inf if x = +inf + * exp(x) = 0 if x = -inf + * exp(x) = eË£ + * + * exp(x) overflows if (approximately) x > ln(FLT_MAX) i.e., 88.72.. + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_types.h" +#include "libm/libm_typehelper.h" + +#define EXPF_N 6 +#define EXPF_POLY_DEGREE 4 +#if EXPF_N == 5 +#define EXPF_POLY_DEGREE 3 +#elif EXPF_N == 4 +#define EXPF_POLY_DEGREE 3 +#endif + +#define EXPF_TABLE_SIZE (1 << EXPF_N) +#define EXPF_MAX_POLY_DEGREE 4 + +#define EXP_Y_ZERO 2 +#define EXP_Y_INF 3 + /* + * expf_data.h needs following to be defined before include + * - EXPF_N + * - EXPF_POLY_DEGREE + * - EXPF_TABLE_SIZE + * - EXPF_MAX_POLY_DEGREE + */ + +#include "expf_data.h" + +static const expf_data expf_v2_data = { + /* .tblsz_byln2 = */ 0x1.71547652b82fep+6, + /* .Huge = */ 0x1.8000000000000p+52, + /* .ln2by_tblsz = */ 0x1.62e42fefa39efp-7, + /* .poly = */ { + 1.0, /* 1/1! = 1 */ + 0x1.0000000000000p-1, /* 1/2! = 1/2 */ + 0x1.5555555555555p-3, /* 1/3! = 1/6 */ + 0x1.cacccaa4ba57cp-5, /* 1/4! = 1/24 */ + }, +#if EXPF_N == 6 + /* .table_v3 = */ &__two_to_jby64[0], +#elif EXPF_N == 5 + /* .table_v3 = */ &__two_to_jby32[0], +#endif +}; + +#define C1 expf_v2_data.poly[0] +#define C2 expf_v2_data.poly[1] +#define C3 expf_v2_data.poly[2] +#define C4 expf_v2_data.poly[3] + +#define EXPF_LN2_BY_TBLSZ expf_v2_data.ln2by_tblsz +#define EXPF_TBLSZ_BY_LN2 expf_v2_data.tblsz_byln2 +#define EXPF_HUGE expf_v2_data.Huge +#define EXPF_TABLE expf_v2_data.table_v3 + +#define EXPF_FARG_MIN -0x1.9fe368p6f /* log(0x1p-150) ~= -103.97 */ +#define EXPF_FARG_MAX 0x1.62e42ep6f /* log(0x1p128) ~= 88.72 */ + +float _expf_special(float x, float y, uint32_t code); + +static uint32_t +top12f(float x) +{ + flt32_t f; + f.f = x; + return f.i >> 20; +} + +/****************************************** +* Implementation Notes +* --------------------- +* +* 0. Choose 'N' as 5, EXPF_TBL_SZ = 2^N i.e 32 +* +* 1. Argument Reduction + ******************************************/ +#undef EXPF_N +#define EXPF_N 6 + +#undef EXPF_TABLE_SIZE +#define EXPF_TABLE_SIZE (1 << EXPF_N) + +float +ALM_PROTO_OPT(expf)(float x) +{ + double_t q, dn, r, z; + uint64_t n, j; + + uint32_t top = top12f(x); + + if (unlikely(top > top12f(88.0f))) { + if (_isnan(x)) + return x; + + if (asuint32(x) == asuint32(-INFINITY)) + return 0.0f; + + if (x > EXPF_FARG_MAX) { + if (asuint32(x) == PINFBITPATT_SP32) + return asfloat(PINFBITPATT_SP32); + + /* Raise FE_OVERFLOW, FE_INEXACT */ + return _expf_special(x, asfloat(PINFBITPATT_SP32), EXP_Y_INF); + } + + if (x < EXPF_FARG_MIN) { + return _expf_special(x, 0.0, EXP_Y_ZERO);; + } + } + + z = x * EXPF_TBLSZ_BY_LN2; + + /* + * n = (int) scale(x) + * dn = (double) n + */ +#undef FAST_INTEGER_CONVERSION +#define FAST_INTEGER_CONVERSION 1 +#if FAST_INTEGER_CONVERSION + dn = z + EXPF_HUGE; + + n = asuint64(dn); + + dn -= EXPF_HUGE; +#else + n = z; + dn = cast_i32_to_float(n); + +#endif + + r = x - dn * EXPF_LN2_BY_TBLSZ; + + j = n % EXPF_TABLE_SIZE; + + double_t qtmp = C2 + (C3 * r); + + double_t r2 = r * r; + + double_t tbl = asdouble(asuint64(EXPF_TABLE[j]) + (n << (52 - EXPF_N))); + + q = r + (r2 * qtmp); + + double_t result = tbl + tbl * q; + + return (float_t)(result); +} diff --git a/src/native/clrmath/src/opt/expf_data.h b/src/native/clrmath/src/opt/expf_data.h new file mode 100644 index 00000000000000..f4156753b9b112 --- /dev/null +++ b/src/native/clrmath/src/opt/expf_data.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __AMDLIBM_SINGLE_EXPF_DATA_H__ +#define __AMDLIBM_SINGLE_EXPF_DATA_H__ + +struct expf_data { +#ifdef EXP2F_N + double one_by_64; +#else + double tblsz_byln2; /* 32/ln2 */ +#endif + double Huge; +#ifdef EXP2F_N + double sixtyfour; +#else + double ln2by_tblsz; /* ln2/32 */ +#endif + double poly[EXPF_MAX_POLY_DEGREE]; + const double* table_v3; +}; + + +extern "C" double __two_to_jby64[]; + +#endif diff --git a/src/native/clrmath/src/opt/log_tables.cpp b/src/native/clrmath/src/opt/log_tables.cpp new file mode 100644 index 00000000000000..5cc65410bc8098 --- /dev/null +++ b/src/native/clrmath/src/opt/log_tables.cpp @@ -0,0 +1,621 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" + +extern "C" const uint64_t log_256[] = { + 0x0, + 0x3f6ff00aa2b10bc0, + 0x3f7fe02a6b106789, + 0x3f87dc475f810a77, + 0x3f8fc0a8b0fc03e4, + 0x3f93cea44346a575, + 0x3f97b91b07d5b11b, + 0x3f9b9fc027af9198, + 0x3f9f829b0e783300, + 0x3fa1b0d98923d980, + 0x3fa39e87b9febd60, + 0x3fa58a5bafc8e4d5, + 0x3fa77458f632dcfc, + 0x3fa95c830ec8e3eb, + 0x3fab42dd711971bf, + 0x3fad276b8adb0b52, + 0x3faf0a30c01162a6, + 0x3fb075983598e471, + 0x3fb16536eea37ae1, + 0x3fb253f62f0a1417, + 0x3fb341d7961bd1d1, + 0x3fb42edcbea646f0, + 0x3fb51b073f06183f, + 0x3fb60658a93750c4, + 0x3fb6f0d28ae56b4c, + 0x3fb7da766d7b12cd, + 0x3fb8c345d6319b21, + 0x3fb9ab42462033ad, + 0x3fba926d3a4ad563, + 0x3fbb78c82bb0eda1, + 0x3fbc5e548f5bc743, + 0x3fbd4313d66cb35d, + 0x3fbe27076e2af2e6, + 0x3fbf0a30c01162a6, + 0x3fbfec9131dbeabb, + 0x3fc0671512ca596e, + 0x3fc0d77e7cd08e59, + 0x3fc14785846742ac, + 0x3fc1b72ad52f67a0, + 0x3fc2266f190a5acb, + 0x3fc29552f81ff523, + 0x3fc303d718e47fd3, + 0x3fc371fc201e8f74, + 0x3fc3dfc2b0ecc62a, + 0x3fc44d2b6ccb7d1e, + 0x3fc4ba36f39a55e5, + 0x3fc526e5e3a1b438, + 0x3fc59338d9982086, + 0x3fc5ff3070a793d4, + 0x3fc66acd4272ad51, + 0x3fc6d60fe719d21d, + 0x3fc740f8f54037a5, + 0x3fc7ab890210d909, + 0x3fc815c0a14357eb, + 0x3fc87fa06520c911, + 0x3fc8e928de886d41, + 0x3fc9525a9cf456b4, + 0x3fc9bb362e7dfb83, + 0x3fca23bc1fe2b563, + 0x3fca8becfc882f19, + 0x3fcaf3c94e80bff3, + 0x3fcb5b519e8fb5a4, + 0x3fcbc286742d8cd6, + 0x3fcc2968558c18c1, + 0x3fcc8ff7c79a9a22, + 0x3fccf6354e09c5dc, + 0x3fcd5c216b4fbb91, + 0x3fcdc1bca0abec7d, + 0x3fce27076e2af2e6, + 0x3fce8c0252aa5a60, + 0x3fcef0adcbdc5936, + 0x3fcf550a564b7b37, + 0x3fcfb9186d5e3e2b, + 0x3fd00e6c45ad501d, + 0x3fd0402594b4d041, + 0x3fd071b85fcd590d, + 0x3fd0a324e27390e3, + 0x3fd0d46b579ab74b, + 0x3fd1058bf9ae4ad5, + 0x3fd136870293a8b0, + 0x3fd1675cababa60e, + 0x3fd1980d2dd4236f, + 0x3fd1c898c16999fb, + 0x3fd1f8ff9e48a2f3, + 0x3fd22941fbcf7966, + 0x3fd2596010df763a, + 0x3fd2895a13de86a3, + 0x3fd2b9303ab89d25, + 0x3fd2e8e2bae11d31, + 0x3fd31871c9544185, + 0x3fd347dd9a987d55, + 0x3fd3772662bfd85b, + 0x3fd3a64c556945ea, + 0x3fd3d54fa5c1f710, + 0x3fd404308686a7e4, + 0x3fd432ef2a04e814, + 0x3fd4618bc21c5ec2, + 0x3fd49006804009d1, + 0x3fd4be5f957778a1, + 0x3fd4ec973260026a, + 0x3fd51aad872df82d, + 0x3fd548a2c3add263, + 0x3fd5767717455a6c, + 0x3fd5a42ab0f4cfe2, + 0x3fd5d1bdbf5809ca, + 0x3fd5ff3070a793d4, + 0x3fd62c82f2b9c795, + 0x3fd659b57303e1f3, + 0x3fd686c81e9b14af, + 0x3fd6b3bb2235943e, + 0x3fd6e08eaa2ba1e4, + 0x3fd70d42e2789236, + 0x3fd739d7f6bbd007, + 0x3fd7664e1239dbcf, + 0x3fd792a55fdd47a2, + 0x3fd7bede0a37afc0, + 0x3fd7eaf83b82afc3, + 0x3fd816f41da0d496, + 0x3fd842d1da1e8b17, + 0x3fd86e919a330ba0, + 0x3fd89a3386c1425b, + 0x3fd8c5b7c858b48b, + 0x3fd8f11e873662c7, + 0x3fd91c67eb45a83e, + 0x3fd947941c2116fb, + 0x3fd972a341135158, + 0x3fd99d958117e08b, + 0x3fd9c86b02dc0863, + 0x3fd9f323ecbf984c, + 0x3fda1dc064d5b995, + 0x3fda484090e5bb0a, + 0x3fda72a4966bd9ea, + 0x3fda9cec9a9a084a, + 0x3fdac718c258b0e4, + 0x3fdaf1293247786b, + 0x3fdb1b1e0ebdfc5b, + 0x3fdb44f77bcc8f63, + 0x3fdb6eb59d3cf35e, + 0x3fdb9858969310fb, + 0x3fdbc1e08b0dad0a, + 0x3fdbeb4d9da71b7c, + 0x3fdc149ff115f027, + 0x3fdc3dd7a7cdad4d, + 0x3fdc66f4e3ff6ff8, + 0x3fdc8ff7c79a9a22, + 0x3fdcb8e0744d7aca, + 0x3fdce1af0b85f3eb, + 0x3fdd0a63ae721e64, + 0x3fdd32fe7e00ebd5, + 0x3fdd5b7f9ae2c684, + 0x3fdd83e7258a2f3e, + 0x3fddac353e2c5954, + 0x3fddd46a04c1c4a1, + 0x3fddfc859906d5b5, + 0x3fde24881a7c6c26, + 0x3fde4c71a8687704, + 0x3fde744261d68788, + 0x3fde9bfa659861f5, + 0x3fdec399d2468cc0, + 0x3fdeeb20c640ddf4, + 0x3fdf128f5faf06ed, + 0x3fdf39e5bc811e5c, + 0x3fdf6123fa7028ac, + 0x3fdf884a36fe9ec2, + 0x3fdfaf588f78f31f, + 0x3fdfd64f20f61572, + 0x3fdffd2e0857f498, + 0x3fe011fab125ff8a, + 0x3fe02552a5a5d0ff, + 0x3fe0389eefce633b, + 0x3fe04bdf9da926d2, + 0x3fe05f14bd26459c, + 0x3fe0723e5c1cdf40, + 0x3fe0855c884b450e, + 0x3fe0986f4f573521, + 0x3fe0ab76bece14d2, + 0x3fe0be72e4252a83, + 0x3fe0d163ccb9d6b8, + 0x3fe0e44985d1cc8c, + 0x3fe0f7241c9b497d, + 0x3fe109f39e2d4c97, + 0x3fe11cb81787ccf8, + 0x3fe12f719593efbc, + 0x3fe1422025243d45, + 0x3fe154c3d2f4d5ea, + 0x3fe1675cababa60e, + 0x3fe179eabbd899a1, + 0x3fe18c6e0ff5cf06, + 0x3fe19ee6b467c96f, + 0x3fe1b154b57da29f, + 0x3fe1c3b81f713c25, + 0x3fe1d610fe677003, + 0x3fe1e85f5e7040d0, + 0x3fe1faa34b87094c, + 0x3fe20cdcd192ab6e, + 0x3fe21f0bfc65beec, + 0x3fe23130d7bebf43, + 0x3fe2434b6f483934, + 0x3fe2555bce98f7cb, + 0x3fe26762013430e0, + 0x3fe2795e1289b11b, + 0x3fe28b500df60783, + 0x3fe29d37fec2b08b, + 0x3fe2af15f02640ad, + 0x3fe2c0e9ed448e8c, + 0x3fe2d2b4012edc9e, + 0x3fe2e47436e40268, + 0x3fe2f62a99509546, + 0x3fe307d7334f10be, + 0x3fe3197a0fa7fe6a, + 0x3fe32b1339121d71, + 0x3fe33ca2ba328995, + 0x3fe34e289d9ce1d3, + 0x3fe35fa4edd36ea0, + 0x3fe37117b54747b6, + 0x3fe38280fe58797f, + 0x3fe393e0d3562a1a, + 0x3fe3a5373e7ebdfa, + 0x3fe3b68449fffc23, + 0x3fe3c7c7fff73206, + 0x3fe3d9026a7156fb, + 0x3fe3ea33936b2f5c, + 0x3fe3fb5b84d16f42, + 0x3fe40c7a4880dce9, + 0x3fe41d8fe84672ae, + 0x3fe42e9c6ddf80bf, + 0x3fe43f9fe2f9ce67, + 0x3fe4509a5133bb0a, + 0x3fe4618bc21c5ec2, + 0x3fe472743f33aaad, + 0x3fe48353d1ea88df, + 0x3fe4942a83a2fc07, + 0x3fe4a4f85db03ebb, + 0x3fe4b5bd6956e274, + 0x3fe4c679afccee3a, + 0x3fe4d72d3a39fd00, + 0x3fe4e7d811b75bb1, + 0x3fe4f87a3f5026e9, + 0x3fe50913cc01686b, + 0x3fe519a4c0ba3446, + 0x3fe52a2d265bc5ab, + 0x3fe53aad05b99b7d, + 0x3fe54b2467999498, + 0x3fe55b9354b40bcd, + 0x3fe56bf9d5b3f399, + 0x3fe57c57f336f191, + 0x3fe58cadb5cd7989, + 0x3fe59cfb25fae87e, + 0x3fe5ad404c359f2d, + 0x3fe5bd7d30e71c73, + 0x3fe5cdb1dc6c1765, + 0x3fe5ddde57149923, + 0x3fe5ee02a9241675, + 0x3fe5fe1edad18919, + 0x3fe60e32f44788d9, + 0x3fe61e3efda46467, + 0x3fe62e42fefa39ef, +}; + +struct __log_256_table_interleaved { + uint64_t lead, tail; +}; + +extern "C" const __log_256_table_interleaved log_table_256[] = { + {0x0000000000000000, 0x0000000000000000}, + {0x3f6ff00aa0000000, 0x3db5885e0250435a}, + {0x3f7fe02a60000000, 0x3de620cf11f86ed2}, + {0x3f87dc4750000000, 0x3dff0214edba4a25}, + {0x3f8fc0a8b0000000, 0x3dbf807c79f3db4e}, + {0x3f93cea440000000, 0x3dea352ba779a52b}, + {0x3f97b91b00000000, 0x3dff56c46aa49fd5}, + {0x3f9b9fc020000000, 0x3dfebe465fef5196}, + {0x3f9f829b00000000, 0x3e0cf0660099f1f8}, + {0x3fa1b0d980000000, 0x3e1247b2ff85945d}, + {0x3fa39e87b0000000, 0x3e13fd7abf5202b6}, + {0x3fa58a5ba0000000, 0x3e1f91c9a918d51e}, + {0x3fa77458f0000000, 0x3e08cb73f118d3ca}, + {0x3fa95c8300000000, 0x3e1d91c7d6fad074}, + {0x3fab42dd70000000, 0x3de1971bec28d14c}, + {0x3fad276b80000000, 0x3e15b616a423c78a}, + {0x3faf0a30c0000000, 0x3da162a6617cc971}, + {0x3fb0759830000000, 0x3e166391c4c06d29}, + {0x3fb16536e0000000, 0x3e2d46f5c1d0c4b8}, + {0x3fb253f620000000, 0x3e2e14282df1f6d3}, + {0x3fb341d790000000, 0x3e186f47424a660d}, + {0x3fb42edcb0000000, 0x3e2d4c8de077753e}, + {0x3fb51b0730000000, 0x3e2e0c307ed24f1c}, + {0x3fb60658a0000000, 0x3e226ea18763bdd3}, + {0x3fb6f0d280000000, 0x3e25cad69737c933}, + {0x3fb7da7660000000, 0x3e2af62599088901}, + {0x3fb8c345d0000000, 0x3e18c66c83d6b2d0}, + {0x3fb9ab4240000000, 0x3e1880ceb36fb30f}, + {0x3fba926d30000000, 0x3e2495aac6ca17a4}, + {0x3fbb78c820000000, 0x3e2761db4210878c}, + {0x3fbc5e5480000000, 0x3e2eb78e862bac2f}, + {0x3fbd4313d0000000, 0x3e19b2cd75790dd9}, + {0x3fbe270760000000, 0x3e2c55e5cbd3d50f}, + {0x3fbf0a30c0000000, 0x3db162a6617cc971}, + {0x3fbfec9130000000, 0x3dfdbeabaaa2e519}, + {0x3fc0671510000000, 0x3e1652cb7150c647}, + {0x3fc0d77e70000000, 0x3e39a11cb2cd2ee2}, + {0x3fc1478580000000, 0x3e219d0ab1a28813}, + {0x3fc1b72ad0000000, 0x3e24bd9e80a41811}, + {0x3fc2266f10000000, 0x3e3214b596faa3df}, + {0x3fc29552f0000000, 0x3e303fea46980bb8}, + {0x3fc303d710000000, 0x3e31c8ffa5fd28c7}, + {0x3fc371fc20000000, 0x3dce8f743bcd96c5}, + {0x3fc3dfc2b0000000, 0x3dfd98c5395315c6}, + {0x3fc44d2b60000000, 0x3e3996fa3ccfa7b2}, + {0x3fc4ba36f0000000, 0x3e1cd2af2ad13037}, + {0x3fc526e5e0000000, 0x3e1d0da1bd17200e}, + {0x3fc59338d0000000, 0x3e3330410ba68b75}, + {0x3fc5ff3070000000, 0x3df4f27a790e7c41}, + {0x3fc66acd40000000, 0x3e13956a86f6ff1b}, + {0x3fc6d60fe0000000, 0x3e2c6748723551d9}, + {0x3fc740f8f0000000, 0x3e2500de9326cdfc}, + {0x3fc7ab8900000000, 0x3e1086c848df1b59}, + {0x3fc815c0a0000000, 0x3e04357ead6836ff}, + {0x3fc87fa060000000, 0x3e24832442408024}, + {0x3fc8e928d0000000, 0x3e3d10da8154b13d}, + {0x3fc9525a90000000, 0x3e39e8ad68ec8260}, + {0x3fc9bb3620000000, 0x3e3cfbf706abaf18}, + {0x3fca23bc10000000, 0x3e3fc56ac6326e23}, + {0x3fca8becf0000000, 0x3e39105e3185cf21}, + {0x3fcaf3c940000000, 0x3e3d017fe5b19cc0}, + {0x3fcb5b5190000000, 0x3e3d1f6b48dd13fe}, + {0x3fcbc28670000000, 0x3e20b63358a7e73a}, + {0x3fcc296850000000, 0x3e263063028c211c}, + {0x3fcc8ff7c0000000, 0x3e2e6a6886b09760}, + {0x3fccf63540000000, 0x3e3c138bb891cd03}, + {0x3fcd5c2160000000, 0x3e369f7722b7221a}, + {0x3fcdc1bca0000000, 0x3df57d8fac1a628c}, + {0x3fce270760000000, 0x3e3c55e5cbd3d50f}, + {0x3fce8c0250000000, 0x3e1552d2ff48fe2e}, + {0x3fcef0adc0000000, 0x3e37b8b26ca431bc}, + {0x3fcf550a50000000, 0x3e292decdc1c5f6d}, + {0x3fcfb91860000000, 0x3e3abc7c551aaa8c}, + {0x3fd00e6c40000000, 0x3e36b540731a354b}, + {0x3fd0402590000000, 0x3e32d341036b89ef}, + {0x3fd071b850000000, 0x3e4f9ab21a3a2e0f}, + {0x3fd0a324e0000000, 0x3e239c871afb9fbd}, + {0x3fd0d46b50000000, 0x3e3e6add2c81f640}, + {0x3fd1058bf0000000, 0x3e435c95aa313f41}, + {0x3fd1368700000000, 0x3e249d4582f6cc53}, + {0x3fd1675ca0000000, 0x3e47574c1c07398f}, + {0x3fd1980d20000000, 0x3e4ba846dece9e8d}, + {0x3fd1c898c0000000, 0x3e16999fafbc68e7}, + {0x3fd1f8ff90000000, 0x3e4c9145e51b0103}, + {0x3fd22941f0000000, 0x3e479ef2cb44850a}, + {0x3fd2596010000000, 0x3e0beec73de11275}, + {0x3fd2895a10000000, 0x3e2ef4351af5a498}, + {0x3fd2b93030000000, 0x3e45713a493b4a50}, + {0x3fd2e8e2b0000000, 0x3e45c23a61385992}, + {0x3fd31871c0000000, 0x3e42a88309f57299}, + {0x3fd347dd90000000, 0x3e4530faa9ac8ace}, + {0x3fd3772660000000, 0x3e25fec2d792a758}, + {0x3fd3a64c50000000, 0x3e35a517a71cbcd7}, + {0x3fd3d54fa0000000, 0x3e3707dc3e1cd9a3}, + {0x3fd4043080000000, 0x3e3a1a9f8ef43049}, + {0x3fd432ef20000000, 0x3e4409d0276b3674}, + {0x3fd4618bc0000000, 0x3e20e2f613e85bd9}, + {0x3fd4900680000000, 0x3df0027433001e5f}, + {0x3fd4be5f90000000, 0x3e35dde2836d3265}, + {0x3fd4ec9730000000, 0x3e2300134d7aaf04}, + {0x3fd51aad80000000, 0x3e3cb7e0b42724f5}, + {0x3fd548a2c0000000, 0x3e2d6e93167e6308}, + {0x3fd5767710000000, 0x3e3d1569b1526adb}, + {0x3fd5a42ab0000000, 0x3e0e99fc338a1a41}, + {0x3fd5d1bdb0000000, 0x3e4eb01394a11b1c}, + {0x3fd5ff3070000000, 0x3e04f27a790e7c41}, + {0x3fd62c82f0000000, 0x3e25ce3ca97b7af9}, + {0x3fd659b570000000, 0x3e281f0f940ed857}, + {0x3fd686c810000000, 0x3e4d36295d88857c}, + {0x3fd6b3bb20000000, 0x3e21aca1ec4af526}, + {0x3fd6e08ea0000000, 0x3e445743c7182726}, + {0x3fd70d42e0000000, 0x3e23c491aead337e}, + {0x3fd739d7f0000000, 0x3e3aef401a738931}, + {0x3fd7664e10000000, 0x3e21cede76092a29}, + {0x3fd792a550000000, 0x3e4fba8f44f82bb4}, + {0x3fd7bede00000000, 0x3e446f5f7f3c3e1a}, + {0x3fd7eaf830000000, 0x3e47055f86c9674b}, + {0x3fd816f410000000, 0x3e4b41a92b6b6e1a}, + {0x3fd842d1d0000000, 0x3e443d162e927628}, + {0x3fd86e9190000000, 0x3e4466174013f9b1}, + {0x3fd89a3380000000, 0x3e3b05096ad69c62}, + {0x3fd8c5b7c0000000, 0x3e40b169150faa58}, + {0x3fd8f11e80000000, 0x3e3cd98b1df85da7}, + {0x3fd91c67e0000000, 0x3e468b507b0f8fa8}, + {0x3fd9479410000000, 0x3e48422df57499ba}, + {0x3fd972a340000000, 0x3e11351586970274}, + {0x3fd99d9580000000, 0x3e117e08acba92ee}, + {0x3fd9c86b00000000, 0x3e26e04314dd0229}, + {0x3fd9f323e0000000, 0x3e497f3097e56d1a}, + {0x3fda1dc060000000, 0x3e3356e655901286}, + {0x3fda484090000000, 0x3e0cb761457f94d6}, + {0x3fda72a490000000, 0x3e39af67a85a9dac}, + {0x3fda9cec90000000, 0x3e453410931a909f}, + {0x3fdac718c0000000, 0x3e22c587206058f5}, + {0x3fdaf12930000000, 0x3e223bc358899c22}, + {0x3fdb1b1e00000000, 0x3e4d7bf8b6d223cb}, + {0x3fdb44f770000000, 0x3e47991ec5197ddb}, + {0x3fdb6eb590000000, 0x3e4a79e6bb3a9219}, + {0x3fdb985890000000, 0x3e3a4c43ed663ec5}, + {0x3fdbc1e080000000, 0x3e461b5a1484f438}, + {0x3fdbeb4d90000000, 0x3e4b4e36f7ef0c3a}, + {0x3fdc149ff0000000, 0x3e115f026acd0d1b}, + {0x3fdc3dd7a0000000, 0x3e3f36b535cecf05}, + {0x3fdc66f4e0000000, 0x3e2ffb7fbf3eb5c6}, + {0x3fdc8ff7c0000000, 0x3e3e6a6886b09760}, + {0x3fdcb8e070000000, 0x3e3135eb27f5bbc3}, + {0x3fdce1af00000000, 0x3e470be7d6f6fa57}, + {0x3fdd0a63a0000000, 0x3e4ce43cc84ab338}, + {0x3fdd32fe70000000, 0x3e4c01d7aac3bd91}, + {0x3fdd5b7f90000000, 0x3e45c58d07961060}, + {0x3fdd83e720000000, 0x3e3628bcf941456e}, + {0x3fddac3530000000, 0x3e4c58b2a8461cd2}, + {0x3fddd46a00000000, 0x3e33071282fb989a}, + {0x3fddfc8590000000, 0x3e420dab6a80f09c}, + {0x3fde248810000000, 0x3e44f8d84c397b1e}, + {0x3fde4c71a0000000, 0x3e40d0ee08599e48}, + {0x3fde744260000000, 0x3e1d68787e37da36}, + {0x3fde9bfa60000000, 0x3e366187d591bafc}, + {0x3fdec399d0000000, 0x3e22346600bae772}, + {0x3fdeeb20c0000000, 0x3e390377d0d61b8e}, + {0x3fdf128f50000000, 0x3e4f5e0dd966b907}, + {0x3fdf39e5b0000000, 0x3e49023cb79a00e2}, + {0x3fdf6123f0000000, 0x3e44e05158c28ad8}, + {0x3fdf884a30000000, 0x3e3bfa7b08b18ae4}, + {0x3fdfaf5880000000, 0x3e4ef1e63db35f67}, + {0x3fdfd64f20000000, 0x3e0ec2ae39493d4f}, + {0x3fdffd2e00000000, 0x3e40afe930ab2fa0}, + {0x3fe011fab0000000, 0x3e225ff8a1810dd4}, + {0x3fe02552a0000000, 0x3e469743fb1a71a5}, + {0x3fe0389ee0000000, 0x3e5f9cc676785571}, + {0x3fe04bdf90000000, 0x3e5b524da4cbf982}, + {0x3fe05f14b0000000, 0x3e5a4c8b381535b8}, + {0x3fe0723e50000000, 0x3e5839be809caf2c}, + {0x3fe0855c80000000, 0x3e50968a1cb82c13}, + {0x3fe0986f40000000, 0x3e5eae6a41723fb5}, + {0x3fe0ab76b0000000, 0x3e5d9c29a380a4db}, + {0x3fe0be72e0000000, 0x3e4094aa0ada625e}, + {0x3fe0d163c0000000, 0x3e5973ad6fc108ca}, + {0x3fe0e44980000000, 0x3e4747322fdbab97}, + {0x3fe0f72410000000, 0x3e593692fa9d4221}, + {0x3fe109f390000000, 0x3e5c5a992dfbc7d9}, + {0x3fe11cb810000000, 0x3e4e1f33e102387a}, + {0x3fe12f7190000000, 0x3e464fbef14c048c}, + {0x3fe1422020000000, 0x3e4490f513ca5e3b}, + {0x3fe154c3d0000000, 0x3e37a6af4d4c799d}, + {0x3fe1675ca0000000, 0x3e57574c1c07398f}, + {0x3fe179eab0000000, 0x3e57b133417f8c1c}, + {0x3fe18c6e00000000, 0x3e5feb9e0c176514}, + {0x3fe19ee6b0000000, 0x3e419f25bb3172f7}, + {0x3fe1b154b0000000, 0x3e45f68a7bbfb852}, + {0x3fe1c3b810000000, 0x3e5ee278497929f1}, + {0x3fe1d610f0000000, 0x3e5ccee006109d58}, + {0x3fe1e85f50000000, 0x3e5ce081a07bd8b3}, + {0x3fe1faa340000000, 0x3e570e12981817b8}, + {0x3fe20cdcd0000000, 0x3e292ab6d93503d0}, + {0x3fe21f0bf0000000, 0x3e58cb7dd7c3b61e}, + {0x3fe23130d0000000, 0x3e4efafd0a0b78da}, + {0x3fe2434b60000000, 0x3e5e907267c4288e}, + {0x3fe2555bc0000000, 0x3e5d31ef96780875}, + {0x3fe2676200000000, 0x3e23430dfcd2ad50}, + {0x3fe2795e10000000, 0x3e344d88d75bc1f9}, + {0x3fe28b5000000000, 0x3e5bec0f055e04fc}, + {0x3fe29d37f0000000, 0x3e5d85611590b9ad}, + {0x3fe2af15f0000000, 0x3df320568e583229}, + {0x3fe2c0e9e0000000, 0x3e5a891d1772f538}, + {0x3fe2d2b400000000, 0x3e22edc9dabba74d}, + {0x3fe2e47430000000, 0x3e4b9009a1015086}, + {0x3fe2f62a90000000, 0x3e52a12a8c5b1a19}, + {0x3fe307d730000000, 0x3e3a7885f0fdac85}, + {0x3fe3197a00000000, 0x3e5f4ffcd43ac691}, + {0x3fe32b1330000000, 0x3e52243ae2640aad}, + {0x3fe33ca2b0000000, 0x3e546513299035d3}, + {0x3fe34e2890000000, 0x3e5b39c3a62dd725}, + {0x3fe35fa4e0000000, 0x3e5ba6dd40049f51}, + {0x3fe37117b0000000, 0x3e451d1ed7177409}, + {0x3fe38280f0000000, 0x3e5cb0f2fd7f5216}, + {0x3fe393e0d0000000, 0x3e3ab150cd4e2213}, + {0x3fe3a53730000000, 0x3e5cfd7bf3193844}, + {0x3fe3b68440000000, 0x3e53fff8455f1dbd}, + {0x3fe3c7c7f0000000, 0x3e5fee640b905fc9}, + {0x3fe3d90260000000, 0x3e54e2adf548084c}, + {0x3fe3ea3390000000, 0x3e3b597adc1ecdd2}, + {0x3fe3fb5b80000000, 0x3e4345bd096d3a75}, + {0x3fe40c7a40000000, 0x3e5101b9d2453c8b}, + {0x3fe41d8fe0000000, 0x3e508ce55cc8c979}, + {0x3fe42e9c60000000, 0x3e5bbf017e595f71}, + {0x3fe43f9fe0000000, 0x3e37ce733bd393dc}, + {0x3fe4509a50000000, 0x3e233bb0a503f8a1}, + {0x3fe4618bc0000000, 0x3e30e2f613e85bd9}, + {0x3fe4727430000000, 0x3e5e67555a635b3c}, + {0x3fe48353d0000000, 0x3e2ea88df73d5e8b}, + {0x3fe4942a80000000, 0x3e3d17e03bda18a8}, + {0x3fe4a4f850000000, 0x3e5b607d76044f7e}, + {0x3fe4b5bd60000000, 0x3e52adc4e71bc2fc}, + {0x3fe4c679a0000000, 0x3e5f99dc7362d1d9}, + {0x3fe4d72d30000000, 0x3e5473fa008e6a6a}, + {0x3fe4e7d810000000, 0x3e2b75bb09cb0985}, + {0x3fe4f87a30000000, 0x3e5ea04dd10b9aba}, + {0x3fe50913c0000000, 0x3e5802d0d6979674}, + {0x3fe519a4c0000000, 0x3e174688ccd99094}, + {0x3fe52a2d20000000, 0x3e496f16abb9df22}, + {0x3fe53aad00000000, 0x3e46e66df2aa374f}, + {0x3fe54b2460000000, 0x3e4e66525ea4550a}, + {0x3fe55b9350000000, 0x3e42d02f34f20cbd}, + {0x3fe56bf9d0000000, 0x3e46cfce65047188}, + {0x3fe57c57f0000000, 0x3e39b78c842d58b8}, + {0x3fe58cadb0000000, 0x3e4735e624c24bc9}, + {0x3fe59cfb20000000, 0x3e47eba1f7dd1adf}, + {0x3fe5ad4040000000, 0x3e586b3e59f65355}, + {0x3fe5bd7d30000000, 0x3e1ce38e637f1b4d}, + {0x3fe5cdb1d0000000, 0x3e58d82ec919edc7}, + {0x3fe5ddde50000000, 0x3e4c52648ddcfa37}, + {0x3fe5ee02a0000000, 0x3e52482ceae1ac12}, + {0x3fe5fe1ed0000000, 0x3e55a312311aba4f}, + {0x3fe60e32f0000000, 0x3e411e236329f225}, + {0x3fe61e3ef0000000, 0x3e5b48c8cd2f246c}, + {0x3fe62e42e0000000, 0x3e6efa39ef35793c}, + {0x0000000000000000, 0x0000000000000000}, +}; + +extern "C" const uint64_t log_f_inv_256[] = { + 0x4000000000000000, 0x3fffe01fe01fe020, 0x3fffc07f01fc07f0, 0x3fffa11caa01fa12, + 0x3fff81f81f81f820, 0x3fff6310aca0dbb5, 0x3fff44659e4a4271, 0x3fff25f644230ab5, + 0x3fff07c1f07c1f08, 0x3ffee9c7f8458e02, 0x3ffecc07b301ecc0, 0x3ffeae807aba01eb, + 0x3ffe9131abf0b767, 0x3ffe741aa59750e4, 0x3ffe573ac901e574, 0x3ffe3a9179dc1a73, + 0x3ffe1e1e1e1e1e1e, 0x3ffe01e01e01e01e, 0x3ffde5d6e3f8868a, 0x3ffdca01dca01dca, + 0x3ffdae6076b981db, 0x3ffd92f2231e7f8a, 0x3ffd77b654b82c34, 0x3ffd5cac807572b2, + 0x3ffd41d41d41d41d, 0x3ffd272ca3fc5b1a, 0x3ffd0cb58f6ec074, 0x3ffcf26e5c44bfc6, + 0x3ffcd85689039b0b, 0x3ffcbe6d9601cbe7, 0x3ffca4b3055ee191, 0x3ffc8b265afb8a42, + 0x3ffc71c71c71c71c, 0x3ffc5894d10d4986, 0x3ffc3f8f01c3f8f0, 0x3ffc26b5392ea01c, + 0x3ffc0e070381c0e0, 0x3ffbf583ee868d8b, 0x3ffbdd2b899406f7, 0x3ffbc4fd65883e7b, + 0x3ffbacf914c1bad0, 0x3ffb951e2b18ff23, 0x3ffb7d6c3dda338b, 0x3ffb65e2e3beee05, + 0x3ffb4e81b4e81b4f, 0x3ffb37484ad806ce, 0x3ffb2036406c80d9, 0x3ffb094b31d922a4, + 0x3ffaf286bca1af28, 0x3ffadbe87f94905e, 0x3ffac5701ac5701b, 0x3ffaaf1d2f87ebfd, + 0x3ffa98ef606a63be, 0x3ffa82e65130e159, 0x3ffa6d01a6d01a6d, 0x3ffa574107688a4a, + 0x3ffa41a41a41a41a, 0x3ffa2c2a87c51ca0, 0x3ffa16d3f97a4b02, 0x3ffa01a01a01a01a, + 0x3ff9ec8e951033d9, 0x3ff9d79f176b682d, 0x3ff9c2d14ee4a102, 0x3ff9ae24ea5510da, + 0x3ff999999999999a, 0x3ff9852f0d8ec0ff, 0x3ff970e4f80cb872, 0x3ff95cbb0be377ae, + 0x3ff948b0fcd6e9e0, 0x3ff934c67f9b2ce6, 0x3ff920fb49d0e229, 0x3ff90d4f120190d5, + 0x3ff8f9c18f9c18fa, 0x3ff8e6527af1373f, 0x3ff8d3018d3018d3, 0x3ff8bfce8062ff3a, + 0x3ff8acb90f6bf3aa, 0x3ff899c0f601899c, 0x3ff886e5f0abb04a, 0x3ff87427bcc092b9, + 0x3ff8618618618618, 0x3ff84f00c2780614, 0x3ff83c977ab2bedd, 0x3ff82a4a0182a4a0, + 0x3ff8181818181818, 0x3ff8060180601806, 0x3ff7f405fd017f40, 0x3ff7e225515a4f1d, + 0x3ff7d05f417d05f4, 0x3ff7beb3922e017c, 0x3ff7ad2208e0ecc3, 0x3ff79baa6bb6398b, + 0x3ff78a4c8178a4c8, 0x3ff77908119ac60d, 0x3ff767dce434a9b1, 0x3ff756cac201756d, + 0x3ff745d1745d1746, 0x3ff734f0c541fe8d, 0x3ff724287f46debc, 0x3ff713786d9c7c09, + 0x3ff702e05c0b8170, 0x3ff6f26016f26017, 0x3ff6e1f76b4337c7, 0x3ff6d1a62681c861, + 0x3ff6c16c16c16c17, 0x3ff6b1490aa31a3d, 0x3ff6a13cd1537290, 0x3ff691473a88d0c0, + 0x3ff6816816816817, 0x3ff6719f3601671a, 0x3ff661ec6a5122f9, 0x3ff6524f853b4aa3, + 0x3ff642c8590b2164, 0x3ff63356b88ac0de, 0x3ff623fa77016240, 0x3ff614b36831ae94, + 0x3ff6058160581606, 0x3ff5f66434292dfc, 0x3ff5e75bb8d015e7, 0x3ff5d867c3ece2a5, + 0x3ff5c9882b931057, 0x3ff5babcc647fa91, 0x3ff5ac056b015ac0, 0x3ff59d61f123ccaa, + 0x3ff58ed2308158ed, 0x3ff5805601580560, 0x3ff571ed3c506b3a, 0x3ff56397ba7c52e2, + 0x3ff5555555555555, 0x3ff54725e6bb82fe, 0x3ff5390948f40feb, 0x3ff52aff56a8054b, + 0x3ff51d07eae2f815, 0x3ff50f22e111c4c5, 0x3ff5015015015015, 0x3ff4f38f62dd4c9b, + 0x3ff4e5e0a72f0539, 0x3ff4d843bedc2c4c, 0x3ff4cab88725af6e, 0x3ff4bd3edda68fe1, + 0x3ff4afd6a052bf5b, 0x3ff4a27fad76014a, 0x3ff49539e3b2d067, 0x3ff4880522014880, + 0x3ff47ae147ae147b, 0x3ff46dce34596066, 0x3ff460cbc7f5cf9a, 0x3ff453d9e2c776ca, + 0x3ff446f86562d9fb, 0x3ff43a2730abee4d, 0x3ff42d6625d51f87, 0x3ff420b5265e5951, + 0x3ff4141414141414, 0x3ff40782d10e6566, 0x3ff3fb013fb013fb, 0x3ff3ee8f42a5af07, + 0x3ff3e22cbce4a902, 0x3ff3d5d991aa75c6, 0x3ff3c995a47babe7, 0x3ff3bd60d9232955, + 0x3ff3b13b13b13b14, 0x3ff3a524387ac822, 0x3ff3991c2c187f63, 0x3ff38d22d366088e, + 0x3ff3813813813814, 0x3ff3755bd1c945ee, 0x3ff3698df3de0748, 0x3ff35dce5f9f2af8, + 0x3ff3521cfb2b78c1, 0x3ff34679ace01346, 0x3ff33ae45b57bcb2, 0x3ff32f5ced6a1dfa, + 0x3ff323e34a2b10bf, 0x3ff3187758e9ebb6, 0x3ff30d190130d190, 0x3ff301c82ac40260, + 0x3ff2f684bda12f68, 0x3ff2eb4ea1fed14b, 0x3ff2e025c04b8097, 0x3ff2d50a012d50a0, + 0x3ff2c9fb4d812ca0, 0x3ff2bef98e5a3711, 0x3ff2b404ad012b40, 0x3ff2a91c92f3c105, + 0x3ff29e4129e4129e, 0x3ff293725bb804a5, 0x3ff288b01288b013, 0x3ff27dfa38a1ce4d, + 0x3ff27350b8812735, 0x3ff268b37cd60127, 0x3ff25e22708092f1, 0x3ff2539d7e9177b2, + 0x3ff2492492492492, 0x3ff23eb79717605b, 0x3ff23456789abcdf, 0x3ff22a0122a0122a, + 0x3ff21fb78121fb78, 0x3ff21579804855e6, 0x3ff20b470c67c0d9, 0x3ff2012012012012, + 0x3ff1f7047dc11f70, 0x3ff1ecf43c7fb84c, 0x3ff1e2ef3b3fb874, 0x3ff1d8f5672e4abd, + 0x3ff1cf06ada2811d, 0x3ff1c522fc1ce059, 0x3ff1bb4a4046ed29, 0x3ff1b17c67f2bae3, + 0x3ff1a7b9611a7b96, 0x3ff19e0119e0119e, 0x3ff19453808ca29c, 0x3ff18ab083902bdb, + 0x3ff1811811811812, 0x3ff1778a191bd684, 0x3ff16e0689427379, 0x3ff1648d50fc3201, + 0x3ff15b1e5f75270d, 0x3ff151b9a3fdd5c9, 0x3ff1485f0e0acd3b, 0x3ff13f0e8d344724, + 0x3ff135c81135c811, 0x3ff12c8b89edc0ac, 0x3ff12358e75d3033, 0x3ff11a3019a74826, + 0x3ff1111111111111, 0x3ff107fbbe011080, 0x3ff0fef010fef011, 0x3ff0f5edfab325a2, + 0x3ff0ecf56be69c90, 0x3ff0e40655826011, 0x3ff0db20a88f4696, 0x3ff0d24456359e3a, + 0x3ff0c9714fbcda3b, 0x3ff0c0a7868b4171, 0x3ff0b7e6ec259dc8, 0x3ff0af2f722eecb5, + 0x3ff0a6810a6810a7, 0x3ff09ddba6af8360, 0x3ff0953f39010954, 0x3ff08cabb37565e2, + 0x3ff0842108421084, 0x3ff07b9f29b8eae2, 0x3ff073260a47f7c6, 0x3ff06ab59c7912fb, + 0x3ff0624dd2f1a9fc, 0x3ff059eea0727586, 0x3ff05197f7d73404, 0x3ff04949cc1664c5, + 0x3ff0410410410410, 0x3ff038c6b78247fc, 0x3ff03091b51f5e1a, 0x3ff02864fc7729e9, + 0x3ff0204081020408, 0x3ff0182436517a37, 0x3ff0101010101010, 0x3ff0080402010080, + 0x3ff0000000000000, 0x0000000000000000 +}; diff --git a/src/native/clrmath/src/opt/logf.cpp b/src/native/clrmath/src/opt/logf.cpp new file mode 100644 index 00000000000000..d502bc4be06241 --- /dev/null +++ b/src/native/clrmath/src/opt/logf.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_types.h" +#include "libm/libm_typehelper.h" + +#define MASK_MANT_ALL7 0x007f8000 +#define MASK_MANT8 0x00008000 +#define MASK_SIGN 0x7FFFFFFF +#define LOGF_N 8 +#define LOGF_POLY_DEGREE 2 + +#define FLAG_X_ZERO 0x1 +#define FLAG_X_NEG 0x2 +#define FLAG_X_NAN 0x3 + +#include "logf_data.h" + +extern float_t _logf_special(float_t x, float_t y, uint32_t code); + +extern "C" logf_table logf_lookup[]; + +struct logf_data_t { + float_t log2_head, log2_tail; + float_t poly[LOGF_POLY_DEGREE]; + //const float_t *tab; + float_t poly1[LOGF_POLY_DEGREE]; +}; + +static const logf_data_t logf_data = { + /* .log2_head = */ 0x1.62e3p-1, + /* .log2_tail = */ 0x1.2fefa2p-17, + + /* Polynomial constants */ + + /* .poly = */ { + 0.5f, /* C1= 1/2 */ + 3.333333432674407958984375E-1f, /* C2 = 1/3 */ + }, + + // .tab = logf_lookup, + + /* Polynomial constants for cases near to 1 */ + /* .poly1 = */ { + 8.33333333333317923934e-02f, /* A1 */ + 1.25000000037717509602e-02f, /* A2 */ + }, +}; + +#define LOG2_HEAD logf_data.log2_head +#define LOG2_TAIL logf_data.log2_tail + +static inline float_t +inline_log1pf(float_t x) +{ + float_t r, r2, w; + + r = x - 1.0f; + + w = r / (2.0f + r); + + float_t correction = w * r; + + w += w; + + float_t w2 = w * w; + +#define A1 logf_data.poly1[0] +#define A2 logf_data.poly1[1] + + r2 = (w * w2 * (A1 + A2 * w2)) - correction; + + float_t f = r2 + r; + + return f; +} + + +/* + * ISO-IEC-10967-2: Elementary Numerical Functions + * Signature: + * float logf(float x) + * + * Spec: + * logf(x) + * = logf(x) if x ∈ F and x > 0 + * = x if x = qNaN + * = 0 if x = 1 + * = -inf if x = (-0, 0} + * = NaN otherwise + * + * Implementation Notes: + * x = 2^m * (1 + A) where 1 <= A < 2 + * + * x = 2^m * (1 + (G + g)) where 1 <= 1+G < 2 and g < 2^(-8) + * + * Let F = (1 + G) and f = g + * x = 2^m*(F + f), so 1 <= F < 2, f < 2^(-8) + * + * x = (2^m) * 2 * (F/2+f/2) + * So, 0.5 <= F/2 < 1, f/2 < 2^-9 + * + * logf(x) = logf(2^m) + logf(2) + logf(F/2 + f/2) + * => A + B + C + * + * A = logf(2^m) = m*logf(2) .. (1) + * B = logf(2) .. (2) => Constant can be precalculated + * C = logf(F/2*(1 + f/F)) .. (3) + * => logf(F/2*(1 + f/F)) + * => logf(F/2) + logf(1 + f/F) + * + * logf(x) = logf(2^m) + logf(2) + logf(F/2) + logf(1 + f/F) + * + * (from log(a) + log(b) <=> log(a*b)) + * + * => m*logf(2) + logf(F) + logf(1 + r) where r = 1+f/F + */ + +float +ALM_PROTO_OPT(logf)(float x) +{ + uint32_t ux = asuint32(x); + + if (unlikely(ux - 0x00800000 >= 0x7f800000 - 0x00800000)) + { + /* x < 0x1p-126 or inf or nan. */ + if (ux * 2 == 0) /* log(0) = -inf */ + return -INFINITY; + if (ux == 0x7f800000) /* log(inf) = inf */ + return x; + if ((ux & 0x80000000) || ux * 2 >= 0xff000000) + return (float)FN_PROTOTYPE(sqrt)(x); /* Return NaN */ + + /* + * 'x' has to be denormal, Normalize it + * there is a possibility that only the last (23'rd) bit is set + * Hence multiply by 2^23 to bring to 1.xxxxx format. + */ + ux = asuint32(x * 0x1p23f); + ux -= 23 << 23; + } + + int32_t expo = (ux >> EXPSHIFTBITS_SP32) - EMAX_SP32; + float_t f_expo = (float_t)expo; + +#define NEAR_ONE_LO asuint32(1 - 0x1.0p-4) +#define NEAR_ONE_HI asuint32(1 + 0x1.1p-4) + + /* Values very close to 1, e^(-1/16) <= x <= e^(1/16)*/ + if (unlikely(ux - NEAR_ONE_LO < NEAR_ONE_HI - NEAR_ONE_LO)) { + return inline_log1pf(x); + } + + /* + * Here onwards, 'x' is neither -ve, nor close to 1 + */ + uint32_t mant, mant1, idx; + float_t y, f, finv, r, r2, q, w; + + mant = ux & MANTBITS_SP32; + mant1 = ux & MASK_MANT_ALL7; + /*This step is needed for more accuracy */ +/* mant1 += ((ux & MASK_MANT8) << 1); */ + + idx = mant1 >> (EXPSHIFTBITS_SP32 - LOGF_N); + + y = asfloat(mant |= HALFEXPBITS_SP32); + f = asfloat(mant1 |= HALFEXPBITS_SP32); + + logf_table* tbl = &logf_lookup[idx]; + + finv = tbl->f_inv; + + r = (f - y) * finv; + +#define C1 logf_data.poly[0] +#define C2 logf_data.poly[1] + + r2 = r * r; /* r^2 */ + q = r + (r2 * (C1 + r * C2)); + + q = (f_expo * LOG2_TAIL) - q; + + w = (LOG2_HEAD * f_expo) + tbl->f_128_head; + + q = (tbl->f_128_tail + q) + w; + + return q; +} diff --git a/src/native/clrmath/src/opt/logf_data.h b/src/native/clrmath/src/opt/logf_data.h new file mode 100644 index 00000000000000..fe3c75ad10d659 --- /dev/null +++ b/src/native/clrmath/src/opt/logf_data.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +struct logf_table { + float_t f_inv, f_128_head, f_128_tail; +}; diff --git a/src/native/clrmath/src/opt/pow.cpp b/src/native/clrmath/src/opt/pow.cpp new file mode 100644 index 00000000000000..73fef7f936f437 --- /dev/null +++ b/src/native/clrmath/src/opt/pow.cpp @@ -0,0 +1,448 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + /* Contains implementation of double pow(double x, double y) + * x^y = 2^(y*log2(x)) + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_typehelper.h" + +#define L__exp_bias 0x00000000000003ff /* 1023 */ +#define L__mant_mask 0x000fffffffffffff +#define N 10 +#define TABLE_SIZE (1ULL << N) +#define ABSOLUTE_VALUE 0x7FFFFFFFFFFFFFFF +#define TOP12_EXP_MAX 0x40862E42 +#define MANTISSA_10_BITS 0x000FFC0000000000 +#define MANTISSA_11_BIT 0x0000020000000000 + +#define EXP_X_NAN 1 +#define EXP_Y_ZERO 2 +#define EXP_Y_INF 3 + +double _exp_special(double x, double y, uint32_t code); + +struct log_data { + uint64_t head; + uint64_t tail; +}; + +struct exp_data { + uint64_t head; + uint64_t tail; +}; + +typedef union { + uint64_t value; + uint32_t split[2]; +} doubleword; + +extern "C" log_data log_Finv[]; +extern "C" log_data log_f_256[]; +extern "C" exp_data exp_lookup[]; + +struct pow_data_t { + double ALIGN(16) poly_log[8]; + double ALIGN(16) poly_exp[8]; + double_t L__real_log2_head, + L__real_log2_tail, + log2_by_N_head, + log2_by_N_tail, + N_by_log2; +}; + +static const pow_data_t pow_data = { + /* + * Polynomial constants, 1/x! (reciprocal x) + * To make better use of cache line, + * we dont store 0! and 1! + */ + + /* .poly_log = */ { /* skip for 0/1 and 1/1 */ + 0x1.0000000000000p-1, /* 1/2 */ + 0x1.5555555555555p-2, /* 1/3 */ + 0x1.0000000000000p-2, /* 1/4 */ + 0x1.999999999999ap-3, /* 1/5 */ + 0x1.5555555555555p-3, /* 1/6 */ + 0x1.2492492492492p-3, /* 1/7 */ + 0x1.0000000000000p-3, /* 1/8 */ + 0x1.c71c71c71c71cp-4, /* 1/9 */ + }, + /* .poly_exp = */ { + 0x1.5555555555555p-3, /* 1/3! * 3 */ + 0x1.5555555555555p-5, /* 1/4! * 5 */ + 0x1.1111111111111p-7, /* 1/5! * 7 */ + 0x1.6c16c16c16c17p-10 /* 1/6! * 9 */ + }, + + /* .L__real_log2_head = */ 0x1.62e42e0000000p-1, + /* .L__real_log2_tail = */ 0x1.efa39ef35793cp-25, + /* .log2_by_N_head = */ 0x1.62e42f0000000p-11, + /* .log2_by_N_tail = */ 0x1.DF473DE6AF279p-36, + /* .N_by_log2 = */ 0x1.71547652b82fep10, +}; + +#define C1 pow_data.poly_log[0] +#define C2 pow_data.poly_log[1] +#define C3 pow_data.poly_log[2] +#define C4 pow_data.poly_log[3] + +#define LOG2_HEAD pow_data.L__real_log2_head +#define LOG2_TAIL pow_data.L__real_log2_tail +#define LOG2_BY_N_HEAD pow_data.log2_by_N_head +#define LOG2_BY_N_TAIL pow_data.log2_by_N_tail +#define N_BY_LOG2 pow_data.N_by_log2 + +#define a0 0.5 +#define a1 pow_data.poly_exp[0] +#define a2 pow_data.poly_exp[1] +#define a3 pow_data.poly_exp[2] + +#define POW_X_ONE_Y_SNAN 1 +#define POW_X_ZERO_Z_INF 2 +#define POW_X_NAN 3 +#define POW_Y_NAN 4 +#define POW_X_NAN_Y_NAN 5 +#define POW_X_NEG_Y_NOTINT 6 +#define POW_Z_ZERO 7 +#define POW_Z_DENORMAL 8 +#define POW_Z_INF 9 + +double _pow_special(double x, double y, double z, uint32_t code); + +static inline double_t +compute_log(uint64_t ux, double_t* log_lo, int32_t expadjust) +{ + /* + * Calculate log(x) in higher precision and store as log_hi and log_lo + * + * x very close to 1.0 is handled differently, for x everywhere else + * a brief explanation is given below + * + * x = (2 ^ m) * A + * x = (2 ^ m) * (G + g) with (1 <= G < 2) and (g <= 2 ^ (-9)) + * x = (2 ^ m) * 2 * (G/2 + g/2) + * x = (2 ^ m)* 2* (F + f) with (0.5 <= F < 1) and (f <= 2 ^ (-10)) + * + * Y = (2 ^ (-1)) * (2 ^ (-m)) * (2 ^ m) * A + * Now, range of Y is: 0.5 <= Y < 1 + * F = 0x100 + (first 8 mantissa bits) + (9th mantissa bit) + * Now, range of F is: 256 <= F <= 512 + * F = F / 512 + * Now, range of F is: 0.5 <= F <= 1 + * f = -(Y - F), with (f <= 2^(-10)) + * log(x) = m * log(2) + log(2) + log(F - f) + * log(x) = m * log(2) + log(2) + log(F) + log(1 -(f / F)) + * log(x) = m * log(2) + log(2 * F) + log(1 - r) + * r = (f / F), with (r <= 2^(-9)) + * r = f * (1 / F) with (1 / F) precomputed to avoid division + * log(x) = m * log(2) + log(G) - poly + * log(G) is precomputed + * poly = (r + (r ^ 2) / 2 + (r ^ 3) / 3 + (r ^ 4) / 4) + (r ^ 5) / 5) + (r ^ 6) / 6)) + * log(2) and log(G) need to be maintained in extra precision + * to avoid losing precision in the calculations + * Store the exponent of x in xexp and put + * f into the range [0.5, 1) + */ + int32_t xexp; + double_t r, r1, w, z, w1, resT_t, resT, resH; + double_t u, f, z1, q, f1, f2, poly; + xexp = ((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64 - expadjust; + double_t exponent_x = (double_t)xexp; + f1 = asdouble((ux & MANTBITS_DP64) | HALFEXPBITS_DP64); + uint64_t index = (ux & MANTISSA_10_BITS); + index += ((ux & MANTISSA_11_BIT) << 1); + f = asdouble(index | HALFEXPBITS_DP64); + index = index >> 42; + f2 = f - f1; + /* + * At this point, x = 2**xexp * ( f1 + f2 ) where + * f1 = j/128, j = 64, 65, ..., 128 and |f2| <= 1/256. + * Compute 'u' from Taylor series of log2(1+f1/f2) + */ + z1 = asdouble(log_Finv[index].tail); + q = asdouble(log_Finv[index].head); + w = asdouble(log_f_256[index].head); + w1 = asdouble(log_f_256[index].tail); + r = f2 * z1; + r1 = f2 * q; + u = r + r1; + z = r1 - u; + + /* + * Polynomial evaluation + * For N=10, + * poly = u * (u * (C1 + u * (C2 + u * (C3 + u * (C4))))) + */ + + double_t A1, B0, usquare; + + /* Estrin Scheme */ + A1 = C1 + u * C2; + double_t A2 = C3 + u * C4; + usquare = u * u; + B0 = usquare * A1; /* u^2 * C1 + u^3 * C2 */ + double ufour = usquare * usquare; + poly = B0 + ufour * A2; + poly = (z + r) + poly; + resT_t = (LOG2_TAIL * exponent_x - poly) + w1; + resT = resT_t - u; + resH = LOG2_HEAD * exponent_x + w; + double log_hi = resT + resH; + *log_lo = resH - log_hi + resT; + return log_hi; +} + +static inline double_t +compute_exp(double_t v, double_t vt, uint64_t result_sign) +{ + double_t A1, A2, z, r, usquare, w, w1, B0, poly; + const double_t EXP_HUGE = 0x1.8000000000000p52; + int64_t n; + int64_t i; + doubleword xword; + double temp = v; + v = v * N_BY_LOG2; + xword.value = asuint64(temp); + int32_t abs_ylogx = (xword.value & ABSOLUTE_VALUE) >> 32; + + /* check if x > 1024 * ln(2) */ + if (unlikely(abs_ylogx >= TOP12_EXP_MAX)) + { + /* if abs(y * log(x)) > 709.7822265625 */ + if (xword.value >= EXP_MIN) + { + /* if y * log(x) < -745.133219101941222106688655913 */ + v = asdouble(0x0 | result_sign); + return _exp_special((double)xword.value, v, EXP_Y_ZERO); + + } + if (temp > EXP_MAX_DOUBLE) + { + /* if y * log(x) > 709.7822265625 */ + v = asdouble(EXPBITS_DP64 | result_sign); + return _exp_special((double)xword.value, v, EXP_Y_INF); + + } + abs_ylogx = 0xfff; + } + double_t fastconvert = v + EXP_HUGE; + n = asuint64(fastconvert); + double_t dn = fastconvert - EXP_HUGE; + + /* Table size = 1024. Here N = 10 */ + int32_t index = n % (1 << N); + r = temp - (dn * LOG2_BY_N_HEAD); + int64_t m = ((n - index) << (EXPSHIFTBITS_DP64 - N)) + 0x3ff0000000000000; + r = (r - (LOG2_BY_N_TAIL * dn)) + vt; + /* + * Taylor's series to evaluate exp(r) + * For N = 11 + * polynomial = r * (1.0 + r * (0.5 + r * (1/3! + r * (1/4!))) + * for N = 10 + * polynomial =r * (1.0 + r * (0.5 + r * (1/3! + r * (1/4! + r * (1/5!)))) + */ + /*Estrin's approach used here for polynomial evaluation + * + * N = 10 + * + */ + A1 = a0 + r * a1; /* A1 = 0.5 + r ^ (1/3!) */ + usquare = r * r; + A2 = a2 + r * a3; + B0 = r + usquare * A1; /* r + 0.5 * r ^ 2 + r ^ 3 * (1 / 3!) */ + poly = B0 + usquare * usquare * A2; + w = asdouble(exp_lookup[index].head); + w1 = asdouble(exp_lookup[index].tail); + temp = w1 + poly * w1; + z = poly * w; + double_t result = w + (z + temp); + + /* Process denormals */ + if (unlikely(abs_ylogx == 0xfff)) + { + int32_t m2 = (int32_t)((n - index) >> N); + if (result < 1.0 || m2 < EMIN_DP64) + { + m2 = m2 + 1074; + i = 1ULL << m2; + dn = asdouble(i); + n = asuint64(result * dn); + result = asdouble(n | result_sign); + return result; + } + } + + z = asdouble(m | result_sign); + return result * z; +} + +static inline uint32_t checkint(uint64_t u) +{ + int32_t u_exp = ((u & ABSOLUTE_VALUE) >> EXPSHIFTBITS_DP64); + /* + * See whether u is an integer. + * status = 0 means not an integer. + * status = 1 means odd integer. + * status = 2 means even integer. + */ + if (u_exp < 0x3ff) + return 0; + if (u_exp > 0x3ff + EXPSHIFTBITS_DP64) + return 2; + if (u & ((1ULL << (0x3ff + EXPSHIFTBITS_DP64 - u_exp)) - 1)) + return 0; + if (u & (1ULL << (0x3ff + EXPSHIFTBITS_DP64 - u_exp))) + return 1; /* odd integer */ + return 2; +} + +/* Returns 1 if input is the bit representation of 0, infinity or nan. */ +static inline int checkzeroinfnan(uint64_t i) +{ + return 2 * i - 1 >= 2 * EXPBITS_DP64 - 1; +} + +static inline int issignaling_inline(double x) +{ + uint64_t ix; + ix = asuint64(x); + return 2 * (ix ^ QNAN_MASK_64) > 2 * QNANBITPATT_DP64; +} + +static inline double _pow_inexact(double x) +{ + double_t a = 0x1.0p+0; /* a = 1.0 */ + double_t b = 0x1.4000000000000p+3; /* b = 10.0 */ + + // Managed code doesn't support FP exceptions + //__asm __volatile("divsd %1, %0" : "+x" (a) : "x" (b)); + + return x; +} + +double +ALM_PROTO_OPT(pow)(double x, double y) +{ + double_t log_lo; + double_t f; + int32_t expadjust = 0; + uint64_t ux, uy, result_sign; + uint64_t infinity = EXPBITS_DP64; + uint64_t one = ONEEXPBITS_DP64; + ux = asuint64(x); + uy = asuint64(y); + uint32_t xhigh = ux >> EXPSHIFTBITS_DP64; /* Top 12 bits of x */ + uint32_t yhigh = uy >> EXPSHIFTBITS_DP64; /* Top 12 bits of y */ + result_sign = 0; /* Hold the sign of the result */ + + if (unlikely(xhigh - 0x001 >= 0x7ff - 0x001 + || (yhigh & 0x7ff) - 0x3be >= 0x43e - 0x3be)) + { + if (unlikely(checkzeroinfnan(uy))) + { + if (2 * uy == 0) + return issignaling_inline(x) ? x + y : 1.0; + if (ux == one) + return issignaling_inline(y) ? x + y : 1.0; + if (2 * ux > 2 * infinity || 2 * uy > 2 * infinity) + return x + y; + if (2 * ux == 2 * one) + return 1.0; + if ((2 * ux < 2 * one) == !(uy >> 63)) + return 0.0; /* |x| < 1 && y = inf or |x| > 1 && y = -inf */ + return y * y; + } + if (unlikely(checkzeroinfnan(ux))) + { + + double x2 = x * x; + /* x is negative , y is odd*/ + if (ux >> 63 && checkint(uy) == 1) + { + result_sign = SIGNBIT_DP64; + } + if (2 * ux == 0 && uy >> 63) + { + x2 = INFINITY; + x2 = asdouble(ux | result_sign); + return x2; + } + x2 = asdouble(asuint64(x2) | result_sign); + return uy >> 63 ? (1 / x2) : x2; + } + /* Here x and y are non-zero finite. */ + if (ux >> 63) + { + /* Finite x < 0 */ + uint32_t yint = checkint(uy); + if (yint == 0) + return sqrt(x); + if (yint == 1) + result_sign = SIGNBIT_DP64; + ux &= ABSOLUTE_VALUE; + xhigh &= 0x7ff; + } + if ((yhigh & 0x7ff) - 0x3be >= 0x43e - 0x3be) { + /* Note: sign_bias = 0 here because y is not odd. */ + if (ux == one) + { + return _pow_inexact(1.0); + } + if ((yhigh & 0x7ff) < 0x3be) + { + /* |y| < 2 ^ -65, x ^ y ~= 1 + y * log(x) */ + return ux > one ? 1.0 + y : 1.0 - y; + } + return (ux > one) == (yhigh < 0x800) ? + (DBL_MAX * DBL_MAX) : + _pow_special(x, y, 0.0, POW_Z_ZERO); + } + + if (xhigh == 0) + { + /* subnormal x */ + uint64_t mant = ux & MANTBITS_DP64; + f = (double)asuint64((double)(mant | ONEEXPBITS_DP64)); + double_t temp = f - 1.0; + ux = asuint64(temp); + expadjust = 1022; + } + } + + double_t log_hi = compute_log(ux, &log_lo, expadjust); + + /* Multiplication of log_hi and log_lo with y */ + double_t v = log_hi * y; + double_t vt = y * log_lo + fma(y, log_hi, -v); + + double_t result = compute_exp(v, vt, result_sign); + return result; +} diff --git a/src/native/clrmath/src/opt/pow_data.cpp b/src/native/clrmath/src/opt/pow_data.cpp new file mode 100644 index 00000000000000..e5c05a8f17250e --- /dev/null +++ b/src/native/clrmath/src/opt/pow_data.cpp @@ -0,0 +1,3122 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" + +struct log_data { + uint64_t head; + uint64_t tail; +}; + +struct exp_data { + uint64_t head; + uint64_t tail; +}; + +extern "C" log_data log_Finv[1025] = { + {0x4000000000000000,0x0,}, + {0x3ffff00000000000,0x3f6003ff003ff004,}, + {0x3ffff00000000000,0x3edff007fc01ff00,}, + {0x3fffe00000000000,0x3f6023e51430db5b,}, + {0x3fffe00000000000,0x3effe01fe01fe020,}, + {0x3fffd00000000000,0x3f6063839b7da2f4,}, + {0x3fffd00000000000,0x3f11e528439a981c,}, + {0x3fffc00000000000,0x3f60c2ab542cb1c9,}, + {0x3fffc00000000000,0x3f1fc07f01fc07f0,}, + {0x3fffb00000000000,0x3f61412d59f5976b,}, + {0x3fffb00000000000,0x3f28c21abd271e34,}, + {0x3fffa00000000000,0x3f61dedb25594a73,}, + {0x3fffa00000000000,0x3f31caa01fa11caa,}, + {0x3fff900000000000,0x3f629b868abd196d,}, + {0x3fff900000000000,0x3f382b6813baf1b2,}, + {0x3fff800000000000,0x3f637701b988410c,}, + {0x3fff800000000000,0x3f3f81f81f81f820,}, + {0x3fff700000000000,0x3f64711f3b441e7e,}, + {0x3fff700000000000,0x3f43e672fa98528d,}, + {0x3fff600000000000,0x3f6589b1f2bef4f4,}, + {0x3fff600000000000,0x3f48856506ddaba6,}, + {0x3fff500000000000,0x3f66c08d1b313d7d,}, + {0x3fff500000000000,0x3f4d9d1fd102728a,}, + {0x3fff400000000000,0x3f6815844765788b,}, + {0x3fff400000000000,0x3f5196792909c560,}, + {0x3fff300000000000,0x3f69886b60e2788f,}, + {0x3fff300000000000,0x3f549a166e33b008,}, + {0x3fff200000000000,0x3f6b1916a7181d3b,}, + {0x3fff200000000000,0x3f57d9108c2ad433,}, + {0x3fff100000000000,0x3f6cc75aae8e7720,}, + {0x3fff100000000000,0x3f5b5311007c5b53,}, + {0x3fff000000000000,0x3f6e930c60174b77,}, + {0x3fff000000000000,0x3f5f07c1f07c1f08,}, + {0x3fff000000000000,0x3f0f003e007c00f8,}, + {0x3ffef00000000000,0x3f617b6713d75987,}, + {0x3ffef00000000000,0x3f3410702a8bb96a,}, + {0x3ffee00000000000,0x3f638ff08b1c03dd,}, + {0x3ffee00000000000,0x3f429425a3d491bc,}, + {0x3ffed00000000000,0x3f65c15367a74aba,}, + {0x3ffed00000000000,0x3f4b9325540c85e6,}, + {0x3ffec00000000000,0x3f680f6603d980f6,}, + {0x3ffec00000000000,0x3f52824897ead8d2,}, + {0x3ffeb00000000000,0x3f6a79ff0a161804,}, + {0x3ffeb00000000000,0x3f5773e23fd1ef35,}, + {0x3ffea00000000000,0x3f6d00f57403d5d0,}, + {0x3ffea00000000000,0x3f5c9e0de3bde793,}, + {0x3ffe900000000000,0x3f6fa42089cf3149,}, + {0x3ffe900000000000,0x3f61003d31003d31,}, + {0x3ffe900000000000,0x3f331abf0b7672a0,}, + {0x3ffe800000000000,0x3f63cd6b99e2e490,}, + {0x3ffe800000000000,0x3f44f9cd77a84876,}, + {0x3ffe700000000000,0x3f66b66a35d1cd0a,}, + {0x3ffe700000000000,0x3f506a965d43919b,}, + {0x3ffe600000000000,0x3f69bb115a1657f3,}, + {0x3ffe600000000000,0x3f568f6f9d35ab75,}, + {0x3ffe500000000000,0x3f6cdb39a74417ba,}, + {0x3ffe500000000000,0x3f5ceb240795ceb2,}, + {0x3ffe500000000000,0x3ee6bc0886833271,}, + {0x3ffe400000000000,0x3f61beb2de672839,}, + {0x3ffe400000000000,0x3f3b6b8d9785150a,}, + {0x3ffe300000000000,0x3f6522f3b834e67f,}, + {0x3ffe300000000000,0x3f4b7cd0933ac00f,}, + {0x3ffe200000000000,0x3f68a22e33dc2b60,}, + {0x3ffe200000000000,0x3f54d7ba49f3484d,}, + {0x3ffe100000000000,0x3f6c3c3c3c3c3c3c,}, + {0x3ffe100000000000,0x3f5c268d84595465,}, + {0x3ffe000000000000,0x3f6ff0f803c1ff10,}, + {0x3ffe000000000000,0x3f61d54b525c7372,}, + {0x3ffe000000000000,0x3f3e01e01e01e01e,}, + {0x3ffdf00000000000,0x3f65b1c57210652f,}, + {0x3ffdf00000000000,0x3f4ea78bef26d838,}, + {0x3ffde00000000000,0x3f69a89003bd9a89,}, + {0x3ffde00000000000,0x3f575b8fe21a291c,}, + {0x3ffdd00000000000,0x3f6db9862f23b464,}, + {0x3ffdd00000000000,0x3f5f978c5b653007,}, + {0x3ffdd00000000000,0x3f2e48360ab71710,}, + {0x3ffdc00000000000,0x3f6403b9403b9404,}, + {0x3ffdc00000000000,0x3f48a58d231c226a,}, + {0x3ffdb00000000000,0x3f68557cfae3a8a7,}, + {0x3ffdb00000000000,0x3f551003b6a8801e,}, + {0x3ffda00000000000,0x3f6cc0ed7303b5cc,}, + {0x3ffda00000000000,0x3f5e00769e00769e,}, + {0x3ffda00000000000,0x3f245e70076828bd,}, + {0x3ffd900000000000,0x3f6391ec1cacfaae,}, + {0x3ffd900000000000,0x3f479118f3fc4da2,}, + {0x3ffd800000000000,0x3f683cf0fed886cf,}, + {0x3ffd800000000000,0x3f5537d00761537d,}, + {0x3ffd700000000000,0x3f6d0126f105c2b5,}, + {0x3ffd700000000000,0x3f5ed952e0b0ce46,}, + {0x3ffd700000000000,0x3f2de6b2f26df1bd,}, + {0x3ffd600000000000,0x3f645667dee88f66,}, + {0x3ffd600000000000,0x3f4b526cd425a760,}, + {0x3ffd500000000000,0x3f695900eae56404,}, + {0x3ffd500000000000,0x3f57c7297b87e82a,}, + {0x3ffd400000000000,0x3f6e74526ed393ec,}, + {0x3ffd400000000000,0x3f610b35c3254a5a,}, + {0x3ffd400000000000,0x3f3d41d41d41d41d,}, + {0x3ffd300000000000,0x3f664b5c7d253952,}, + {0x3ffd300000000000,0x3f51e92f0074d1e9,}, + {0x3ffd200000000000,0x3f6ba3e76156da63,}, + {0x3ffd200000000000,0x3f5cb28ff16c69ae,}, + {0x3ffd200000000000,0x3f214b5225c6336d,}, + {0x3ffd100000000000,0x3f63d62abe114764,}, + {0x3ffd100000000000,0x3f4a7692bd71cd93,}, + {0x3ffd000000000000,0x3f696b1edd80e866,}, + {0x3ffd000000000000,0x3f587d2a66f1b6fd,}, + {0x3ffcf00000000000,0x3f6f18039ff1803a,}, + {0x3ffcf00000000000,0x3f61f7661546d8d7,}, + {0x3ffcf00000000000,0x3f4372e225fe30d9,}, + {0x3ffce00000000000,0x3f67c7f6f648c16a,}, + {0x3ffce00000000000,0x3f55723ab1e401ce,}, + {0x3ffcd00000000000,0x3f6db027b2691b4b,}, + {0x3ffcd00000000000,0x3f60ad12073615a2,}, + {0x3ffcd00000000000,0x3f3d7ec2fbb8d9f3,}, + {0x3ffcc00000000000,0x3f66b876c6dc74fa,}, + {0x3ffcc00000000000,0x3f538dd299490bea,}, + {0x3ffcb00000000000,0x3f6cdb2c0397cdb3,}, + {0x3ffcb00000000000,0x3f5fea760409df3e,}, + {0x3ffcb00000000000,0x3f38a8930de5ff1a,}, + {0x3ffca00000000000,0x3f663aae400e558f,}, + {0x3ffca00000000000,0x3f52cc157b864407,}, + {0x3ffc900000000000,0x3f6c9723ff1b0da3,}, + {0x3ffc900000000000,0x3f5f9bec57913361,}, + {0x3ffc900000000000,0x3f3853eb77683aec,}, + {0x3ffc800000000000,0x3f664cb5f7148404,}, + {0x3ffc800000000000,0x3f532937ec64b4ea,}, + {0x3ffc700000000000,0x3f6ce22ba19d2968,}, + {0x3ffc700000000000,0x3f603561320b1eea,}, + {0x3ffc700000000000,0x3f3c71c71c71c71c,}, + {0x3ffc600000000000,0x3f66ecaef5908a8c,}, + {0x3ffc600000000000,0x3f54a17f55a10dc1,}, + {0x3ffc500000000000,0x3f6dba67495d5004,}, + {0x3ffc500000000000,0x3f6129a21a930b84,}, + {0x3ffc500000000000,0x3f4279b1ac5cee14,}, + {0x3ffc400000000000,0x3f6818c28ad51cbd,}, + {0x3ffc400000000000,0x3f57314199f4128e,}, + {0x3ffc300000000000,0x3f6f1e0387f1e038,}, + {0x3ffc300000000000,0x3f62a8e715637200,}, + {0x3ffc300000000000,0x3f48e51f48b3c5d7,}, + {0x3ffc200000000000,0x3f69cf221e6069a8,}, + {0x3ffc200000000000,0x3f5ad4e4ba80709b,}, + {0x3ffc200000000000,0x3f20b34f53b8cdae,}, + {0x3ffc100000000000,0x3f64b1664feaec3d,}, + {0x3ffc100000000000,0x3f50ba05b419724a,}, + {0x3ffc000000000000,0x3f6c0e070381c0e0,}, + {0x3ffc000000000000,0x3f5f88de7e939983,}, + {0x3ffc000000000000,0x3f3c01c01c01c01c,}, + {0x3ffbf00000000000,0x3f67415dc9588a2a,}, + {0x3ffbf00000000000,0x3f560fba1a362bb0,}, + {0x3ffbe00000000000,0x3f6ed3b24e219c0b,}, + {0x3ffbe00000000000,0x3f62a4da0ed3f3ca,}, + {0x3ffbe00000000000,0x3f49ed435292d891,}, + {0x3ffbd00000000000,0x3f6a5713280dee96,}, + {0x3ffbd00000000000,0x3f5c703b291b9f6e,}, + {0x3ffbd00000000000,0x3f30f365451b61cb,}, + {0x3ffbc00000000000,0x3f6609fcf5cb742b,}, + {0x3ffbc00000000000,0x3f53f59620f9ece9,}, + {0x3ffbb00000000000,0x3f6df0d390262696,}, + {0x3ffbb00000000000,0x3f61ec130f29268d,}, + {0x3ffbb00000000000,0x3f47b218ab6353bf,}, + {0x3ffba00000000000,0x3f69f22983759f23,}, + {0x3ffba00000000000,0x3f5bf9f37854af6b,}, + {0x3ffba00000000000,0x3f30679bd84886b1,}, + {0x3ffb900000000000,0x3f6622136907fad3,}, + {0x3ffb900000000000,0x3f5478ac63fc8d5c,}, + {0x3ffb800000000000,0x3f6e5bb884a10cb4,}, + {0x3ffb800000000000,0x3f62803712803713,}, + {0x3ffb800000000000,0x3f4aa73a400dc1aa,}, + {0x3ffb700000000000,0x3f6ad87bb4671656,}, + {0x3ffb700000000000,0x3f5e187673725fb4,}, + {0x3ffb700000000000,0x3f3a284ee6b33e2d,}, + {0x3ffb600000000000,0x3f6782e45d670aed,}, + {0x3ffb600000000000,0x3f578b8efbb8148c,}, + {0x3ffb600000000000,0x3edb6006d801b600,}, + {0x3ffb500000000000,0x3f645a9ab6103d8b,}, + {0x3ffb500000000000,0x3f515908c103a133,}, + {0x3ffb400000000000,0x3f6d0369d0369d03,}, + {0x3ffb400000000000,0x3f615f47d55e6d90,}, + {0x3ffb400000000000,0x3f47006d0b803686,}, + {0x3ffb300000000000,0x3f6a25e0ee5665b8,}, + {0x3ffb300000000000,0x3f5d212b601b3748,}, + {0x3ffb300000000000,0x3f3801b31801b318,}, + {0x3ffb200000000000,0x3f6774bfe4d445a0,}, + {0x3ffb200000000000,0x3f57dc5e2bb119aa,}, + {0x3ffb200000000000,0x3f0b2036406c80d9,}, + {0x3ffb100000000000,0x3f64efb213e77003,}, + {0x3ffb100000000000,0x3f52ef7f5d8398c1,}, + {0x3ffb000000000000,0x3f6e04a6946650c1,}, + {0x3ffb000000000000,0x3f629663b24547d1,}, + {0x3ffb000000000000,0x3f4cb3cfe19bf6b7,}, + {0x3ffaf00000000000,0x3f6bc854596903cc,}, + {0x3ffaf00000000000,0x3f606881ca7b784f,}, + {0x3ffaf00000000000,0x3f4435e50d79435e,}, + {0x3ffae00000000000,0x3f69b737be5ea8b4,}, + {0x3ffae00000000000,0x3f5ccb7470a824fe,}, + {0x3ffae00000000000,0x3f38c7ed84ef68cb,}, + {0x3ffad00000000000,0x3f67d0ff2920bc03,}, + {0x3ffad00000000000,0x3f591b774c870615,}, + {0x3ffad00000000000,0x3f24f302eed254a3,}, + {0x3ffac00000000000,0x3f661559cc81c77c,}, + {0x3ffac00000000000,0x3f55c06b15c06b16,}, + {0x3ffab00000000000,0x3f6fafc0785f4b71,}, + {0x3ffab00000000000,0x3f6483f7a5cb614e,}, + {0x3ffab00000000000,0x3f52b9b04cc77577,}, + {0x3ffaa00000000000,0x3f6e3a5f0fd7f954,}, + {0x3ffaa00000000000,0x3f631c897a45926f,}, + {0x3ffaa00000000000,0x3f5006a9006a9007,}, + {0x3ffa900000000000,0x3f6ceebd3e98a4b5,}, + {0x3ffa900000000000,0x3f61dec0d4c77b03,}, + {0x3ffa900000000000,0x3f4b4d7191f59e6b,}, + {0x3ffa800000000000,0x3f6bcc8d11d756b7,}, + {0x3ffa800000000000,0x3f60ca5003510ca5,}, + {0x3ffa800000000000,0x3f473289870ac52e,}, + {0x3ffa700000000000,0x3f6ad381585e5ec9,}, + {0x3ffa700000000000,0x3f5fbdd4295b6627,}, + {0x3ffa700000000000,0x3f43bb671a3d927e,}, + {0x3ffa600000000000,0x3f6a034da034da03,}, + {0x3ffa600000000000,0x3f5e3885ac3f892e,}, + {0x3ffa600000000000,0x3f40e6da7c7ef82b,}, + {0x3ffa500000000000,0x3f695ba6344fe8ef,}, + {0x3ffa500000000000,0x3f5d041da2292856,}, + {0x3ffa500000000000,0x3f3d676d98c70ae6,}, + {0x3ffa400000000000,0x3f68dc401a4c6e20,}, + {0x3ffa400000000000,0x3f5c200691c20069,}, + {0x3ffa400000000000,0x3f3a41a41a41a41a,}, + {0x3ffa300000000000,0x3f6884d1103130fd,}, + {0x3ffa300000000000,0x3f5b8bac710cb296,}, + {0x3ffa300000000000,0x3f385a0a3b5832c0,}, + {0x3ffa200000000000,0x3f68550f8a39409d,}, + {0x3ffa200000000000,0x3f5b467ca0fefa7c,}, + {0x3ffa200000000000,0x3f37ae575ff2ef43,}, + {0x3ffa100000000000,0x3f684cb2b0a67374,}, + {0x3ffa100000000000,0x3f5b4fe5e92c0686,}, + {0x3ffa100000000000,0x3f383c4880b67a9a,}, + {0x3ffa000000000000,0x3f686b725d9be112,}, + {0x3ffa000000000000,0x3f5ba758737eada6,}, + {0x3ffa000000000000,0x3f3a01a01a01a01a,}, + {0x3ff9f00000000000,0x3f68b1071b0033f9,}, + {0x3ff9f00000000000,0x3f5c4c45c8033ee2,}, + {0x3ff9f00000000000,0x3f3cfc261b29257f,}, + {0x3ff9e00000000000,0x3f691d2a2067b23a,}, + {0x3ff9e00000000000,0x3f5d3e20c8c0a860,}, + {0x3ff9e00000000000,0x3f4094d3eaf850e2,}, + {0x3ff9d00000000000,0x3f69af955105dc09,}, + {0x3ff9d00000000000,0x3f5e7c5dada0b4e5,}, + {0x3ff9d00000000000,0x3f4343fbf71fac14,}, + {0x3ff9c00000000000,0x3f6a680339a68034,}, + {0x3ff9c00000000000,0x3f60033900339003,}, + {0x3ff9c00000000000,0x3f468a7725080ce1,}, + {0x3ff9b00000000000,0x3f6b462f0eae2703,}, + {0x3ff9b00000000000,0x3f60edea4c5ba128,}, + {0x3ff9b00000000000,0x3f4a673400cd9a67,}, + {0x3ff9a00000000000,0x3f6c49d4aa21b490,}, + {0x3ff9a00000000000,0x3f61fdfecc140c07,}, + {0x3ff9a00000000000,0x3f4ed923a7dcbeb3,}, + {0x3ff9900000000000,0x3f6d72b089b5243a,}, + {0x3ff9900000000000,0x3f63333333333333,}, + {0x3ff9900000000000,0x3f51ef9ce09fe006,}, + {0x3ff9800000000000,0x3f6ec07fcce13f80,}, + {0x3ff9800000000000,0x3f648d44d6b261c5,}, + {0x3ff9800000000000,0x3f54bc363b03fccf,}, + {0x3ff9800000000000,0x3ef980198019801a,}, + {0x3ff9700000000000,0x3f660bf1aacca408,}, + {0x3ff9700000000000,0x3f57d1da34e92006,}, + {0x3ff9700000000000,0x3f2c9f01970e4f81,}, + {0x3ff9600000000000,0x3f67aef84124582e,}, + {0x3ff9600000000000,0x3f5b300659b30066,}, + {0x3ff9600000000000,0x3f3c2873ce078906,}, + {0x3ff9500000000000,0x3f697617c6ef5b25,}, + {0x3ff9500000000000,0x3f5ed6396ab75685,}, + {0x3ff9500000000000,0x3f45906b9f74b92d,}, + {0x3ff9400000000000,0x3f6b61100329b611,}, + {0x3ff9400000000000,0x3f6161f9add3c0ca,}, + {0x3ff9400000000000,0x3f4d9b5641228a8f,}, + {0x3ff9300000000000,0x3f6d6fa154ceb181,}, + {0x3ff9300000000000,0x3f637c5aa78372e5,}, + {0x3ff9300000000000,0x3f5319fe6cb39806,}, + {0x3ff9200000000000,0x3f6fa18cb11833f3,}, + {0x3ff9200000000000,0x3f65ba00c956e803,}, + {0x3ff9200000000000,0x3f57acb264fc445f,}, + {0x3ff9200000000000,0x3f2f693a1c451ab3,}, + {0x3ff9100000000000,0x3f681aadce2c5588,}, + {0x3ff9100000000000,0x3f5c854ae10772de,}, + {0x3ff9100000000000,0x3f41b9e10d83d1c6,}, + {0x3ff9000000000000,0x3f6a9e240321a9e2,}, + {0x3ff9000000000000,0x3f60d1a66de8ec3f,}, + {0x3ff9000000000000,0x3f4c23f50e760899,}, + {0x3ff8f00000000000,0x3f6d442645e82d4e,}, + {0x3ff8f00000000000,0x3f63831f3831f383,}, + {0x3ff8f00000000000,0x3f538bcbbf44d35a,}, + {0x3ff8f00000000000,0x3ed8f0063c018f00,}, + {0x3ff8e00000000000,0x3f6656d36b4454e1,}, + {0x3ff8e00000000000,0x3f5949ebc4dcfc1c,}, + {0x3ff8e00000000000,0x3f37b6e9a56b1aa1,}, + {0x3ff8d00000000000,0x3f694c872fc80f8a,}, + {0x3ff8d00000000000,0x3f5f4be34674104e,}, + {0x3ff8d00000000000,0x3f480c6980c6980c,}, + {0x3ff8c00000000000,0x3f6c63ff398e7003,}, + {0x3ff8c00000000000,0x3f62c89e03df77ac,}, + {0x3ff8c00000000000,0x3f5261e92ac36f43,}, + {0x3ff8b00000000000,0x3f6f9d00c5fe7403,}, + {0x3ff8b00000000000,0x3f660cc06f499cb1,}, + {0x3ff8b00000000000,0x3f590062d90062d9,}, + {0x3ff8b00000000000,0x3f37ba8cd4353eb3,}, + {0x3ff8a00000000000,0x3f69721ed7e75347,}, + {0x3ff8a00000000000,0x3f5fe12e09a19cfd,}, + {0x3ff8a00000000000,0x3f49cae00c519cae,}, + {0x3ff8900000000000,0x3f6cf87fb6248b40,}, + {0x3ff8900000000000,0x3f6381ec0313381f,}, + {0x3ff8900000000000,0x3f541df5a120d718,}, + {0x3ff8900000000000,0x3f13f540dd12ce7d,}, + {0x3ff8800000000000,0x3f6733f790031173,}, + {0x3ff8800000000000,0x3f5b97c2aec12653,}, + {0x3ff8800000000000,0x3f419d952866a138,}, + {0x3ff8700000000000,0x3f6b068156dd2d89,}, + {0x3ff8700000000000,0x3f61a9336deecb0b,}, + {0x3ff8700000000000,0x3f509ef3024ae3ba,}, + {0x3ff8600000000000,0x3f6ef95183e9daf7,}, + {0x3ff8600000000000,0x3f65a6b96b350803,}, + {0x3ff8600000000000,0x3f58af5e5b1d8bb9,}, + {0x3ff8600000000000,0x3f38618618618618,}, + {0x3ff8500000000000,0x3f69c43c254e3a3e,}, + {0x3ff8500000000000,0x3f607fcf4f8030b0,}, + {0x3ff8500000000000,0x3f4cfba0f9592266,}, + {0x3ff8400000000000,0x3f6e0184f00c2780,}, + {0x3ff8400000000000,0x3f64c7a364637089,}, + {0x3ff8400000000000,0x3f5722833944a55b,}, + {0x3ff8400000000000,0x3f32f2ecdc90c512,}, + {0x3ff8300000000000,0x3f692ef5657dba52,}, + {0x3ff8300000000000,0x3f60030700307003,}, + {0x3ff8300000000000,0x3f4b6a41cbd11c5c,}, + {0x3ff8200000000000,0x3f6db58fc690b865,}, + {0x3ff8200000000000,0x3f64940305494030,}, + {0x3ff8200000000000,0x3f56ebd075b7ef66,}, + {0x3ff8200000000000,0x3f32d9eba4018213,}, + {0x3ff8100000000000,0x3f694400c0e51003,}, + {0x3ff8100000000000,0x3f60303030303030,}, + {0x3ff8100000000000,0x3f4c7f274ff0f3c6,}, + {0x3ff8000000000000,0x3f6e12cbbf5796be,}, + {0x3ff8000000000000,0x3f65093406c2f54b,}, + {0x3ff8000000000000,0x3f58060180601806,}, + {0x3ff8000000000000,0x3f38018018018018,}, + {0x3ff7f00000000000,0x3f6a00bfe802ffa0,}, + {0x3ff7f00000000000,0x3f6104ae89750b6c,}, + {0x3ff7f00000000000,0x3f5017f405fd017f,}, + {0x3ff7e00000000000,0x3f6f16a071b1d5bd,}, + {0x3ff7e00000000000,0x3f66249ff40a76d8,}, + {0x3ff7e00000000000,0x3f5a6bed53d6eba6,}, + {0x3ff7e00000000000,0x3f412a8ad278e8dd,}, + {0x3ff7d00000000000,0x3f6b62a236d13346,}, + {0x3ff7d00000000000,0x3f627df354968b5e,}, + {0x3ff7d00000000000,0x3f53392866c5b9a0,}, + {0x3ff7d00000000000,0x3f17d05f417d05f4,}, + {0x3ff7c00000000000,0x3f67e3bdd0c74c0a,}, + {0x3ff7c00000000000,0x3f5e1885c2527c19,}, + {0x3ff7c00000000000,0x3f48e041588d1676,}, + {0x3ff7b00000000000,0x3f6d67245c02f7d6,}, + {0x3ff7b00000000000,0x3f64997d2070b4ed,}, + {0x3ff7b00000000000,0x3f579e31a4dccdfc,}, + {0x3ff7b00000000000,0x3f383fad12b21224,}, + {0x3ff7a00000000000,0x3f6a4411c1d986a9,}, + {0x3ff7a00000000000,0x3f61836b63ff42ba,}, + {0x3ff7a00000000000,0x3f518c017a463006,}, + {0x3ff7a00000000000,0x3ed7a005e8017a00,}, + {0x3ff7900000000000,0x3f6754d76c7316df,}, + {0x3ff7900000000000,0x3f5d422a63e4b90b,}, + {0x3ff7900000000000,0x3f47c21e344e16d6,}, + {0x3ff7800000000000,0x3f6d432cb8c6c373,}, + {0x3ff7800000000000,0x3f649902f149902f,}, + {0x3ff7800000000000,0x3f57e410e84afb0a,}, + {0x3ff7800000000000,0x3f3a71dc01781a72,}, + {0x3ff7700000000000,0x3f6aad9a55845003,}, + {0x3ff7700000000000,0x3f621023358c1a68,}, + {0x3ff7700000000000,0x3f52eba8c5e8e918,}, + {0x3ff7700000000000,0x3f1bd58436340177,}, + {0x3ff7600000000000,0x3f684aa8b6fce3a3,}, + {0x3ff7600000000000,0x3f5f7390d2a6c406,}, + {0x3ff7600000000000,0x3f4cb02601d3c7b8,}, + {0x3ff7500000000000,0x3f6ea16a4562f79a,}, + {0x3ff7500000000000,0x3f6619e9025f3f51,}, + {0x3ff7500000000000,0x3f5b2b0805d5b2b1,}, + {0x3ff7500000000000,0x3f4450e64f13dc4a,}, + {0x3ff7400000000000,0x3f6c960802e9c961,}, + {0x3ff7400000000000,0x3f641aed9f916040,}, + {0x3ff7400000000000,0x3f5745d1745d1746,}, + {0x3ff7400000000000,0x3f396fbd236dec04,}, + {0x3ff7300000000000,0x3f6abc18b133ed1e,}, + {0x3ff7300000000000,0x3f624d4a349d7b8e,}, + {0x3ff7300000000000,0x3f53c31507fa32c4,}, + {0x3ff7300000000000,0x3f278d7f5daad90c,}, + {0x3ff7200000000000,0x3f691330e1f23d8e,}, + {0x3ff7200000000000,0x3f60b093a132d692,}, + {0x3ff7200000000000,0x3f50a1fd1b7af017,}, + {0x3ff7100000000000,0x3f6ff47002e3ff47,}, + {0x3ff7100000000000,0x3f679ae65d281438,}, + {0x3ff7100000000000,0x3f5e88bff4742ee8,}, + {0x3ff7100000000000,0x3f4bc36ce3e0453a,}, + {0x3ff7000000000000,0x3f6ea056796ca224,}, + {0x3ff7000000000000,0x3f6652d01ccdf3c2,}, + {0x3ff7000000000000,0x3f5c108d0af957f9,}, + {0x3ff7000000000000,0x3f4702e05c0b8170,}, + {0x3ff6f00000000000,0x3f6d7c2336130af5,}, + {0x3ff6f00000000000,0x3f653a864887005c,}, + {0x3ff6f00000000000,0x3f59f7bf6abdcd69,}, + {0x3ff6f00000000000,0x3f4300b79300b793,}, + {0x3ff6e00000000000,0x3f6c876f3ff488de,}, + {0x3ff6e00000000000,0x3f6451a23168e803,}, + {0x3ff6e00000000000,0x3f583d8a4958e948,}, + {0x3ff6e00000000000,0x3f3f76b4337c6cb1,}, + {0x3ff6d00000000000,0x3f6bc1d4c482c4de,}, + {0x3ff6d00000000000,0x3f6397be4dd5de70,}, + {0x3ff6d00000000000,0x3f56e12324eda006,}, + {0x3ff6d00000000000,0x3f3a62681c860fb0,}, + {0x3ff6c00000000000,0x3f6b2aef136b1148,}, + {0x3ff6c00000000000,0x3f630c763568529b,}, + {0x3ff6c00000000000,0x3f55e1c1bc0aac90,}, + {0x3ff6c00000000000,0x3f36c16c16c16c17,}, + {0x3ff6b00000000000,0x3f6ac25a9a8f3080,}, + {0x3ff6b00000000000,0x3f62af669cf005ae,}, + {0x3ff6b00000000000,0x3f553ea005ad53ea,}, + {0x3ff6b00000000000,0x3f3490aa31a3cfc7,}, + {0x3ff6a00000000000,0x3f6a87b4e20f3c6a,}, + {0x3ff6a00000000000,0x3f62802d52802d53,}, + {0x3ff6a00000000000,0x3f54f6fa296614e0,}, + {0x3ff6a00000000000,0x3f33cd153729043e,}, + {0x3ff6900000000000,0x3f6a7a9c886459c0,}, + {0x3ff6900000000000,0x3f627e69398e4cfa,}, + {0x3ff6900000000000,0x3f550a0e779e9c51,}, + {0x3ff6900000000000,0x3f3473a88d0bfd2e,}, + {0x3ff6800000000000,0x3f6a9ab13e8be484,}, + {0x3ff6800000000000,0x3f62a9ba472173da,}, + {0x3ff6800000000000,0x3f55771d62005a15,}, + {0x3ff6800000000000,0x3f36816816816817,}, + {0x3ff6700000000000,0x3f6ae793c442c470,}, + {0x3ff6700000000000,0x3f6301c17e118eed,}, + {0x3ff6700000000000,0x3f563d6973fb1649,}, + {0x3ff6700000000000,0x3f39f36016719f36,}, + {0x3ff6600000000000,0x3f6b60e5e4509a32,}, + {0x3ff6600000000000,0x3f638620eb56802d,}, + {0x3ff6600000000000,0x3f575c374b6aea21,}, + {0x3ff6600000000000,0x3f3ec6a5122f9016,}, + {0x3ff6500000000000,0x3f6c064a70e277e0,}, + {0x3ff6500000000000,0x3f64367ba266aded,}, + {0x3ff6500000000000,0x3f58d2cd915d02f7,}, + {0x3ff6500000000000,0x3f427c29da5519cf,}, + {0x3ff6400000000000,0x3f6cd7653ff4d8ca,}, + {0x3ff6400000000000,0x3f651275b9a4bede,}, + {0x3ff6400000000000,0x3f5aa074f2f2997f,}, + {0x3ff6400000000000,0x3f4642c8590b2164,}, + {0x3ff6300000000000,0x3f6dd3db27cc8e83,}, + {0x3ff6300000000000,0x3f6619b446dc38f7,}, + {0x3ff6300000000000,0x3f5cc4781a618a54,}, + {0x3ff6300000000000,0x3f4ab5c45606f00b,}, + {0x3ff6200000000000,0x3f6efb51fb7e5a7a,}, + {0x3ff6200000000000,0x3f674bdd5bccbb10,}, + {0x3ff6200000000000,0x3f5f3e23a8120059,}, + {0x3ff6200000000000,0x3f4fd3b80b11fd3c,}, + {0x3ff6200000000000,0x3f035c21e13b4a28,}, + {0x3ff6100000000000,0x3f68a89802c38a8a,}, + {0x3ff6100000000000,0x3f61066315ec522b,}, + {0x3ff6100000000000,0x3f52cda0c6ba4eaa,}, + {0x3ff6100000000000,0x3f2c9de8e6505581,}, + {0x3ff6000000000000,0x3f6a2f8c3b432fe4,}, + {0x3ff6000000000000,0x3f6297d80f266432,}, + {0x3ff6000000000000,0x3f56058160581606,}, + {0x3ff6000000000000,0x3f3b82262afb5ba3,}, + {0x3ff5f00000000000,0x3f6be062f6b8deab,}, + {0x3ff5f00000000000,0x3f645319ed1d044b,}, + {0x3ff5f00000000000,0x3f5990d0a4b7ef87,}, + {0x3ff5f00000000000,0x3f45013344c219b8,}, + {0x3ff5e00000000000,0x3f6dbac6153f6678,}, + {0x3ff5e00000000000,0x3f6637d2cb166e9f,}, + {0x3ff5e00000000000,0x3f5d6ee340579d6f,}, + {0x3ff5e00000000000,0x3f4ce6850b752415,}, + {0x3ff5d00000000000,0x3f6fbe60626f6c59,}, + {0x3ff5d00000000000,0x3f6845adaf0ccefc,}, + {0x3ff5d00000000000,0x3f60cf87d9c54a69,}, + {0x3ff5d00000000000,0x3f52b7db291a6f8b,}, + {0x3ff5d00000000000,0x3f2eadd923cad2aa,}, + {0x3ff5c00000000000,0x3f6a7c56868ebbb3,}, + {0x3ff5c00000000000,0x3f6310572620ae4c,}, + {0x3ff5c00000000000,0x3f574dbc4ce292a0,}, + {0x3ff5c00000000000,0x3f40ffa8f7802b84,}, + {0x3ff5b00000000000,0x3f6cdb7a23ac6c0a,}, + {0x3ff5b00000000000,0x3f65798c8ff522a2,}, + {0x3ff5b00000000000,0x3f5c3440776ec7d9,}, + {0x3ff5b00000000000,0x3f4af4cf8338a00b,}, + {0x3ff5a00000000000,0x3f6f62c639f16df5,}, + {0x3ff5a00000000000,0x3f680ad602b580ad,}, + {0x3ff5a00000000000,0x3f60b561f78a3c93,}, + {0x3ff5a00000000000,0x3f52c4d1ab74abcb,}, + {0x3ff5a00000000000,0x3f308f4adb54fed1,}, + {0x3ff5900000000000,0x3f6ac3e24799546f,}, + {0x3ff5900000000000,0x3f6378525a1d5cfc,}, + {0x3ff5900000000000,0x3f585e70a74b36fa,}, + {0x3ff5900000000000,0x3f43a24bd6e0d254,}, + {0x3ff5800000000000,0x3f6da46102b1da46,}, + {0x3ff5800000000000,0x3f6662a13dc51765,}, + {0x3ff5800000000000,0x3f5e46a4d5f33782,}, + {0x3ff5800000000000,0x3f4f99cd3cae23f9,}, + {0x3ff5800000000000,0x3f15805601580560,}, + {0x3ff5700000000000,0x3f6973ff541a3003,}, + {0x3ff5700000000000,0x3f623e6802af23e7,}, + {0x3ff5700000000000,0x3f56167707e12710,}, + {0x3ff5700000000000,0x3f3ed3c506b39a23,}, + {0x3ff5600000000000,0x3f6cac1e23290531,}, + {0x3ff5600000000000,0x3f65802ad5802ad6,}, + {0x3ff5600000000000,0x3f5cad3b06856f32,}, + {0x3ff5600000000000,0x3f4cbdd3e2970f60,}, + {0x3ff5600000000000,0x3ed5600558015600,}, + {0x3ff5500000000000,0x3f68e84d6f250c59,}, + {0x3ff5500000000000,0x3f61c84c0cacc777,}, + {0x3ff5500000000000,0x3f55555555555555,}, + {0x3ff5500000000000,0x3f3c7b40ca88e92e,}, + {0x3ff5400000000000,0x3f6c7683299ccbbc,}, + {0x3ff5400000000000,0x3f655ffaad5400aa,}, + {0x3ff5400000000000,0x3f5c979aee0bf805,}, + {0x3ff5400000000000,0x3f4ce7e968293300,}, + {0x3ff5400000000000,0x3ef5401540154015,}, + {0x3ff5300000000000,0x3f691d5dbd4dcfe3,}, + {0x3ff5300000000000,0x3f621291e81fd58e,}, + {0x3ff5300000000000,0x3f56143702d11bac,}, + {0x3ff5300000000000,0x3f400fe5817d8424,}, + {0x3ff5200000000000,0x3f6d002a5d002a5d,}, + {0x3ff5200000000000,0x3f65fead500a9580,}, + {0x3ff5200000000000,0x3f5dff022602f98e,}, + {0x3ff5200000000000,0x3f50054900549005,}, + {0x3ff5200000000000,0x3f20816728c4bece,}, + {0x3ff5100000000000,0x3f6a0fd5c5f02a3a,}, + {0x3ff5100000000000,0x3f6319e156df3247,}, + {0x3ff5100000000000,0x3f584c70054584c7,}, + {0x3ff5100000000000,0x3f44d3629d0ea6ef,}, + {0x3ff5000000000000,0x3f6e45c223898adc,}, + {0x3ff5000000000000,0x3f6758f356fa3ecf,}, + {0x3ff5000000000000,0x3f606e6b21d938da,}, + {0x3ff5000000000000,0x3f530c50ca4dd5a2,}, + {0x3ff5000000000000,0x3f35015015015015,}, + {0x3ff4f00000000000,0x3f6bbc6edcbd94bf,}, + {0x3ff4f00000000000,0x3f64daf5d6b2f876,}, + {0x3ff4f00000000000,0x3f5bf77ba8dd70da,}, + {0x3ff4f00000000000,0x3f4c7b16ea64d422,}, + {0x3ff4f00000000000,0x3f01031ba50cec35,}, + {0x3ff4e00000000000,0x3f696b90d67a4746,}, + {0x3ff4e00000000000,0x3f629551d91e392e,}, + {0x3ff4e00000000000,0x3f57829cbc14e5e1,}, + {0x3ff4e00000000000,0x3f43be153601a1b1,}, + {0x3ff4d00000000000,0x3f6e1ff59078029c,}, + {0x3ff4d00000000000,0x3f67529e109f0aeb,}, + {0x3ff4d00000000000,0x3f60877db8589720,}, + {0x3ff4d00000000000,0x3f537d26e578eba8,}, + {0x3ff4d00000000000,0x3f37bef15cb4dbe5,}, + {0x3ff4c00000000000,0x3f6c335ccf669003,}, + {0x3ff4c00000000000,0x3f65710e4b5edcea,}, + {0x3ff4c00000000000,0x3f5d61e31ac8f80c,}, + {0x3ff4c00000000000,0x3f4fcc1610391aee,}, + {0x3ff4c00000000000,0x3f237491ea465d10,}, + {0x3ff4b00000000000,0x3f6a7dbb4d1fc1c8,}, + {0x3ff4b00000000000,0x3f63c65b002973c6,}, + {0x3ff4b00000000000,0x3f5a224e52346e0a,}, + {0x3ff4b00000000000,0x3f49787ae7e76b38,}, + {0x3ff4a00000000000,0x3f6fad40a57eb503,}, + {0x3ff4a00000000000,0x3f68fe8bdf0d1529,}, + {0x3ff4a00000000000,0x3f6251ff5ab6b803,}, + {0x3ff4a00000000000,0x3f574f341a74775f,}, + {0x3ff4a00000000000,0x3f43fd6bb00a5140,}, + {0x3ff4900000000000,0x3f6e5940ed268135,}, + {0x3ff4900000000000,0x3f67b54b07680293,}, + {0x3ff4900000000000,0x3f6113783233cfba,}, + {0x3ff4900000000000,0x3f54e78ecb419ba9,}, + {0x3ff4900000000000,0x3f3eb1bcd37c3936,}, + {0x3ff4800000000000,0x3f6d3ac7ca09a2da,}, + {0x3ff4800000000000,0x3f66a176ee815d40,}, + {0x3ff4800000000000,0x3f600a44029100a4,}, + {0x3ff4800000000000,0x3f52ea5c0334bd28,}, + {0x3ff4800000000000,0x3f37119f3d324d89,}, + {0x3ff4700000000000,0x3f6c5154b1641003,}, + {0x3ff4700000000000,0x3f65c28f5c28f5c3,}, + {0x3ff4700000000000,0x3f5e6bc5cbdf6161,}, + {0x3ff4700000000000,0x3f51569c9aafc7c0,}, + {0x3ff4700000000000,0x3f3116848d2ce038,}, + {0x3ff4600000000000,0x3f6b9c68b2c0cc4a,}, + {0x3ff4600000000000,0x3f651815b134cb86,}, + {0x3ff4600000000000,0x3f5d2bad1c5fa42f,}, + {0x3ff4600000000000,0x3f502b549704f03b,}, + {0x3ff4600000000000,0x3f2978feb9f34381,}, + {0x3ff4500000000000,0x3f6b1b867199dac5,}, + {0x3ff4500000000000,0x3f64a18ce1271d93,}, + {0x3ff4500000000000,0x3f5c53447d381827,}, + {0x3ff4500000000000,0x3f4ecf163bb6500a,}, + {0x3ff4500000000000,0x3f23ff5d7b0028a1,}, + {0x3ff4400000000000,0x3f6ace321f1685de,}, + {0x3ff4400000000000,0x3f645e796bf2af51,}, + {0x3ff4400000000000,0x3f5be1958b67ebb9,}, + {0x3ff4400000000000,0x3f4e1494d19ce49c,}, + {0x3ff4400000000000,0x3f21b87c0b644fbe,}, + {0x3ff4300000000000,0x3f6ab3f173e7553a,}, + {0x3ff4300000000000,0x3f644e6157dc9a3b,}, + {0x3ff4300000000000,0x3f5bd5acee277b57,}, + {0x3ff4300000000000,0x3f4e253f72959f68,}, + {0x3ff4300000000000,0x3f229cc9444c57b3,}, + {0x3ff4200000000000,0x3f6acc4baa3f0ddf,}, + {0x3ff4200000000000,0x3f6470cc2b7b099c,}, + {0x3ff4200000000000,0x3f5c2e9a4af13353,}, + {0x3ff4200000000000,0x3f4eff369940fbc0,}, + {0x3ff4200000000000,0x3f26a4cbcb2a247b,}, + {0x3ff4100000000000,0x3f6b16c977e81cea,}, + {0x3ff4100000000000,0x3f64c542e7d04156,}, + {0x3ff4100000000000,0x3f5ceb7039c2c939,}, + {0x3ff4100000000000,0x3f50505050505050,}, + {0x3ff4100000000000,0x3f2dc921b4703eb5,}, + {0x3ff4000000000000,0x3f6b92f50875d100,}, + {0x3ff4000000000000,0x3f654b50028154b5,}, + {0x3ff4000000000000,0x3f5e0b4439959819,}, + {0x3ff4000000000000,0x3f5183d4d68eef44,}, + {0x3ff4000000000000,0x3f34014014014014,}, + {0x3ff3f00000000000,0x3f6c4059f790ca6d,}, + {0x3ff3f00000000000,0x3f66027f6027f602,}, + {0x3ff3f00000000000,0x3f5f8d2ea50cf2bd,}, + {0x3ff3f00000000000,0x3f531941cafdd13a,}, + {0x3ff3f00000000000,0x3f3aa4d983a95e44,}, + {0x3ff3e00000000000,0x3f6d1e854b5e0db4,}, + {0x3ff3e00000000000,0x3f66ea5e4ebecb3e,}, + {0x3ff3e00000000000,0x3f60b82553aca2fe,}, + {0x3ff3e00000000000,0x3f550fb2e798cab0,}, + {0x3ff3e00000000000,0x3f4165e7254813e2,}, + {0x3ff3d00000000000,0x3f6e2d056f0027be,}, + {0x3ff3d00000000000,0x3f68027b8027b802,}, + {0x3ff3d00000000000,0x3f61d9db18a7764f,}, + {0x3ff3d00000000000,0x3f576646a9d716ef,}, + {0x3ff3d00000000000,0x3f46394d47b46c69,}, + {0x3ff3c00000000000,0x3f6f6b6a2d31d685,}, + {0x3ff3c00000000000,0x3f694a6704cb9002,}, + {0x3ff3c00000000000,0x3f632b48f757ce88,}, + {0x3ff3c00000000000,0x3f5a1c1e47fec398,}, + {0x3ff3c00000000000,0x3f4bcae2a9d7daf1,}, + {0x3ff3c00000000000,0x3f1b28955f358ba7,}, + {0x3ff3b00000000000,0x3f6ac1b24652a906,}, + {0x3ff3b00000000000,0x3f64ac009dd2b002,}, + {0x3ff3b00000000000,0x3f5d305da6a96f36,}, + {0x3ff3b00000000000,0x3f510c781278feec,}, + {0x3ff3b00000000000,0x3f33b13b13b13b14,}, + {0x3ff3a00000000000,0x3f6c67f00275c67f,}, + {0x3ff3a00000000000,0x3f665b950d3702c4,}, + {0x3ff3a00000000000,0x3f605115a73ca8ed,}, + {0x3ff3a00000000000,0x3f5490e1eb208984,}, + {0x3ff3a00000000000,0x3f4106987706e700,}, + {0x3ff3900000000000,0x3f6e3cb445e6dc21,}, + {0x3ff3900000000000,0x3f68399a949b0a44,}, + {0x3ff3900000000000,0x3f62385830fec66e,}, + {0x3ff3900000000000,0x3f5871d8856ea1e5,}, + {0x3ff3900000000000,0x3f48ed57c7b90ab4,}, + {0x3ff3900000000000,0x3effca33a893f1f0,}, + {0x3ff3800000000000,0x3f6a45a6cc111b7e,}, + {0x3ff3800000000000,0x3f644d8c49e2629d,}, + {0x3ff3800000000000,0x3f5cae8815f81116,}, + {0x3ff3800000000000,0x3f50c59a742ef617,}, + {0x3ff3800000000000,0x3f33813813813814,}, + {0x3ff3700000000000,0x3f6c7f508fc31579,}, + {0x3ff3700000000000,0x3f6690490e4e88fb,}, + {0x3ff3700000000000,0x3f60a30faad19b4e,}, + {0x3ff3700000000000,0x3f556f472517b708,}, + {0x3ff3700000000000,0x3f43380fccf3b19b,}, + {0x3ff3600000000000,0x3f6ee62ffb24233a,}, + {0x3ff3600000000000,0x3f690026d90026d9,}, + {0x3ff3600000000000,0x3f631be7bc0e8f2a,}, + {0x3ff3600000000000,0x3f5a72e3a81709da,}, + {0x3ff3600000000000,0x3f4d631144c5876c,}, + {0x3ff3600000000000,0x3f279de643851251,}, + {0x3ff3500000000000,0x3f6b9cbf3e55f044,}, + {0x3ff3500000000000,0x3f65c166113cf01f,}, + {0x3ff3500000000000,0x3f5fcfa41e396d1c,}, + {0x3ff3500000000000,0x3f542004d542004d,}, + {0x3ff3500000000000,0x3f40e7d95bc609a9,}, + {0x3ff3400000000000,0x3f6e65ad07b18e41,}, + {0x3ff3400000000000,0x3f689325b0ffb2cf,}, + {0x3ff3400000000000,0x3f62c25f87756095,}, + {0x3ff3400000000000,0x3f59e6b3804d19e7,}, + {0x3ff3400000000000,0x3f4c984e428557be,}, + {0x3ff3400000000000,0x3f25a8c2eeda65ae,}, + {0x3ff3300000000000,0x3f6b90c2d18cda45,}, + {0x3ff3300000000000,0x3f65c8b6af7963c2,}, + {0x3ff3300000000000,0x3f60026700267002,}, + {0x3ff3300000000000,0x3f547ba5f6ff1983,}, + {0x3ff3300000000000,0x3f41ebe767a137f0,}, + {0x3ff3200000000000,0x3f6eb9dad43bf402,}, + {0x3ff3200000000000,0x3f68fa7523cd11d3,}, + {0x3ff3200000000000,0x3f633cc8026533cd,}, + {0x3ff3200000000000,0x3f5b01a554890d51,}, + {0x3ff3200000000000,0x3f4f1a515885fb37,}, + {0x3ff3200000000000,0x3f3070620943ff67,}, + {0x3ff3100000000000,0x3f6c5739a6fb84ee,}, + {0x3ff3100000000000,0x3f66a21bc3b1c82c,}, + {0x3ff3100000000000,0x3f60eeb1d3d76c02,}, + {0x3ff3100000000000,0x3f5679f628da4745,}, + {0x3ff3100000000000,0x3f4633db0b9f70f3,}, + {0x3ff3000000000000,0x3f6fdea41d306676,}, + {0x3ff3000000000000,0x3f6a320261a32026,}, + {0x3ff3000000000000,0x3f648710cf0f9e6b,}, + {0x3ff3000000000000,0x3f5dbb9d4970b005,}, + {0x3ff3000000000000,0x3f526c7644a49fdf,}, + {0x3ff3000000000000,0x3f3c82ac40260390,}, + {0x3ff2f00000000000,0x3f6dec1d1668c645,}, + {0x3ff2f00000000000,0x3f6849910e890c2a,}, + {0x3ff2f00000000000,0x3f62a8b0b1e176bc,}, + {0x3ff2f00000000000,0x3f5a12f684bda12f,}, + {0x3ff2f00000000000,0x3f4dafc00979dafc,}, + {0x3ff2f00000000000,0x3f2d00e34ae0553c,}, + {0x3ff2e00000000000,0x3f6c35d51c8b0496,}, + {0x3ff2e00000000000,0x3f669d43fda2962c,}, + {0x3ff2e00000000000,0x3f61065a1c1122b7,}, + {0x3ff2e00000000000,0x3f56e22d78c40f5b,}, + {0x3ff2e00000000000,0x3f4775e48e3d15fc,}, + {0x3ff2e00000000000,0x3f02e025c04b8097,}, + {0x3ff2d00000000000,0x3f6abb2c5c8e1329,}, + {0x3ff2d00000000000,0x3f652c7bba79f5fc,}, + {0x3ff2d00000000000,0x3f5f3edbeeec6bc2,}, + {0x3ff2d00000000000,0x3f542804b542804b,}, + {0x3ff2d00000000000,0x3f4228e0ae18ff44,}, + {0x3ff2c00000000000,0x3f6f020eb21ccdbe,}, + {0x3ff2c00000000000,0x3f697b8536c8a0f9,}, + {0x3ff2c00000000000,0x3f63f69b02593f6a,}, + {0x3ff2c00000000000,0x3f5ce69ebc135d73,}, + {0x3ff2c00000000000,0x3f51e34327004b12,}, + {0x3ff2c00000000000,0x3f3b8c87666de717,}, + {0x3ff2b00000000000,0x3f6df31cb46e21fa,}, + {0x3ff2b00000000000,0x3f68764435474829,}, + {0x3ff2b00000000000,0x3f62fb06baa91b36,}, + {0x3ff2b00000000000,0x3f5b02c7209a63b6,}, + {0x3ff2b00000000000,0x3f5012b404ad012b,}, + {0x3ff2b00000000000,0x3f34974aea8865a4,}, + {0x3ff2a00000000000,0x3f6d1e10ee319fac,}, + {0x3ff2a00000000000,0x3f67aad002557aad,}, + {0x3ff2a00000000000,0x3f623925e7820a7f,}, + {0x3ff2a00000000000,0x3f599223d7c93739,}, + {0x3ff2a00000000000,0x3f4d6a4d78483a3f,}, + {0x3ff2a00000000000,0x3f2eda98d068c96c,}, + {0x3ff2900000000000,0x3f6c8253c8253c82,}, + {0x3ff2900000000000,0x3f6718915f37f7dc,}, + {0x3ff2900000000000,0x3f61b061a26f004a,}, + {0x3ff2900000000000,0x3f589387c4c16a70,}, + {0x3ff2900000000000,0x3f4b92ddc02526e5,}, + {0x3ff2900000000000,0x3f2813b9cca7ab4c,}, + {0x3ff2800000000000,0x3f6c1f4fba6b454b,}, + {0x3ff2800000000000,0x3f66bef31b179d7c,}, + {0x3ff2800000000000,0x3f61602511602511,}, + {0x3ff2800000000000,0x3f5805c9e073c589,}, + {0x3ff2800000000000,0x3f4a9cc82bf7e68b,}, + {0x3ff2800000000000,0x3f24d0bb56960b46,}, + {0x3ff2700000000000,0x3f6bf471439c9adf,}, + {0x3ff2700000000000,0x3f669d620a1b6f09,}, + {0x3ff2700000000000,0x3f6147dd5dcca078,}, + {0x3ff2700000000000,0x3f57e7c527f34ee4,}, + {0x3ff2700000000000,0x3f4a85c40939a85c,}, + {0x3ff2700000000000,0x3f25087fed8f57bc,}, + {0x3ff2600000000000,0x3f6c0126e0093700,}, + {0x3ff2600000000000,0x3f66b34cfcb0b5e4,}, + {0x3ff2600000000000,0x3f6166f9ac024d16,}, + {0x3ff2600000000000,0x3f5838588b23ca87,}, + {0x3ff2600000000000,0x3f4b4b908550bc7b,}, + {0x3ff2600000000000,0x3f28b20979e5de67,}, + {0x3ff2500000000000,0x3f6c44e10125e227,}, + {0x3ff2500000000000,0x3f670024b70024b7,}, + {0x3ff2500000000000,0x3f61bceb12a241ef,}, + {0x3ff2500000000000,0x3f58f666dbc18a3e,}, + {0x3ff2500000000000,0x3f4cebf48bbd90e5,}, + {0x3ff2500000000000,0x3f2fc478c60bbbe3,}, + {0x3ff2400000000000,0x3f6cbf1205260adf,}, + {0x3ff2400000000000,0x3f67835be88eefd9,}, + {0x3ff2400000000000,0x3f62492492492492,}, + {0x3ff2400000000000,0x3f5a20d6bcc076ca,}, + {0x3ff2400000000000,0x3f4f64bea4f570bb,}, + {0x3ff2400000000000,0x3f351b867d380c8d,}, + {0x3ff2300000000000,0x3f6d6f2e2ec0b673,}, + {0x3ff2300000000000,0x3f683c67240ad3b2,}, + {0x3ff2300000000000,0x3f630b1b0d623e14,}, + {0x3ff2300000000000,0x3f5bb692920048dc,}, + {0x3ff2300000000000,0x3f5159e26af37c05,}, + {0x3ff2300000000000,0x3f3c00918e0048c7,}, + {0x3ff2200000000000,0x3f6e54ab9d1f89cd,}, + {0x3ff2200000000000,0x3f692abcd7400916,}, + {0x3ff2200000000000,0x3f64024540245402,}, + {0x3ff2200000000000,0x3f5db6887053f65b,}, + {0x3ff2200000000000,0x3f536b72401224db,}, + {0x3ff2200000000000,0x3f42468d634fc2cc,}, + {0x3ff2100000000000,0x3f6f6f0243f6f024,}, + {0x3ff2100000000000,0x3f6a4dd543382e6b,}, + {0x3ff2100000000000,0x3f652e1bb8b74d39,}, + {0x3ff2100000000000,0x3f600fd506ed3308,}, + {0x3ff2100000000000,0x3f55e60121579805,}, + {0x3ff2100000000000,0x3f475e76e4772cc3,}, + {0x3ff2100000000000,0x3f17b57c78cd7a37,}, + {0x3ff2000000000000,0x3f6ba52a748132eb,}, + {0x3ff2000000000000,0x3f668e18cf81b10f,}, + {0x3ff2000000000000,0x3f61787659534455,}, + {0x3ff2000000000000,0x3f58c884edb1b516,}, + {0x3ff2000000000000,0x3f4d45f23532ce52,}, + {0x3ff2000000000000,0x3f32012012012012,}, + {0x3ff1f00000000000,0x3f6d30383b9b57dd,}, + {0x3ff1f00000000000,0x3f6821b89f9d15a3,}, + {0x3ff1f00000000000,0x3f6314a494da8179,}, + {0x3ff1f00000000000,0x3f5c11f7047dc11f,}, + {0x3ff1f00000000000,0x3f51fd799e16b971,}, + {0x3ff1f00000000000,0x3f3faf3f16b6419d,}, + {0x3ff1e00000000000,0x3f6eee7c258d61aa,}, + {0x3ff1e00000000000,0x3f69e878ff70985e,}, + {0x3ff1e00000000000,0x3f64e3ddd916d08d,}, + {0x3ff1e00000000000,0x3f5fc15436d65004,}, + {0x3ff1e00000000000,0x3f55bdba5f5a75b9,}, + {0x3ff1e00000000000,0x3f4779d9fdc3a219,}, + {0x3ff1e00000000000,0x3f1beeae93c31b83,}, + {0x3ff1d00000000000,0x3f6be1d979708189,}, + {0x3ff1d00000000000,0x3f66e5a1f8776b90,}, + {0x3ff1d00000000000,0x3f61eace5c957907,}, + {0x3ff1d00000000000,0x3f59e2bc2200d60e,}, + {0x3ff1d00000000000,0x3f4fe54205039f0f,}, + {0x3ff1d00000000000,0x3f381528c99206f6,}, + {0x3ff1c00000000000,0x3f6e0d5b450239e1,}, + {0x3ff1c00000000000,0x3f6919727130ceea,}, + {0x3ff1c00000000000,0x3f6426ea0a8ffb8d,}, + {0x3ff1c00000000000,0x3f5e6b82fc8703c0,}, + {0x3ff1c00000000000,0x3f548bf073816367,}, + {0x3ff1c00000000000,0x3f455e36ab38c009,}, + {0x3ff1c00000000000,0x3f0aa04fe0efa2cf,}, + {0x3ff1b00000000000,0x3f6b7ed2664a039b,}, + {0x3ff1b00000000000,0x3f6694808dda5202,}, + {0x3ff1b00000000000,0x3f61ab8b253e7141,}, + {0x3ff1b00000000000,0x3f5987e337a0cbb1,}, + {0x3ff1b00000000000,0x3f4f76cd84e8e73e,}, + {0x3ff1b00000000000,0x3f37c67f2bae2b21,}, + {0x3ff1a00000000000,0x3f6e154698cc77eb,}, + {0x3ff1a00000000000,0x3f693316ebd720dd,}, + {0x3ff1a00000000000,0x3f6452404f7db911,}, + {0x3ff1a00000000000,0x3f5ee58469ee5847,}, + {0x3ff1a00000000000,0x3f5529381b92441a,}, + {0x3ff1a00000000000,0x3f46df352f1f238c,}, + {0x3ff1a00000000000,0x3f1b8aac22b3d8e4,}, + {0x3ff1900000000000,0x3f6c0233c0233c02,}, + {0x3ff1900000000000,0x3f672967dbaf1d4d,}, + {0x3ff1900000000000,0x3f6251f126c56e44,}, + {0x3ff1900000000000,0x3f5af79e297fa80e,}, + {0x3ff1900000000000,0x3f514e02328a7012,}, + {0x3ff1900000000000,0x3f3e9c35424c9817,}, + {0x3ff1800000000000,0x3f6f015f360db81d,}, + {0x3ff1800000000000,0x3f6a308a371f2039,}, + {0x3ff1800000000000,0x3f6561072057b573,}, + {0x3ff1800000000000,0x3f6092d566dd9ec0,}, + {0x3ff1800000000000,0x3f578be90046178c,}, + {0x3ff1800000000000,0x3f4be98f87980349,}, + {0x3ff1800000000000,0x3f31811811811812,}, + {0x3ff1700000000000,0x3f6d673157568494,}, + {0x3ff1700000000000,0x3f689f8e57f97162,}, + {0x3ff1700000000000,0x3f63d9397b043b87,}, + {0x3ff1700000000000,0x3f5e28646f5a1060,}, + {0x3ff1700000000000,0x3f54a0f00ae93926,}, + {0x3ff1700000000000,0x3f4638297098ac4d,}, + {0x3ff1700000000000,0x3f199d167ae411fc,}, + {0x3ff1600000000000,0x3f6c0d1284e6f1d7,}, + {0x3ff1600000000000,0x3f674e8747fee946,}, + {0x3ff1600000000000,0x3f6291467611f493,}, + {0x3ff1600000000000,0x3f5baa9f10b8e57d,}, + {0x3ff1600000000000,0x3f523543f0c80459,}, + {0x3ff1600000000000,0x3f4184f4ffdd3b9f,}, + {0x3ff1500000000000,0x3f6fa920d92de10d,}, + {0x3ff1500000000000,0x3f6af24c3e67eb61,}, + {0x3ff1500000000000,0x3f663cbeea4e1a09,}, + {0x3ff1500000000000,0x3f61887857d16171,}, + {0x3ff1500000000000,0x3f59aaf004559aaf,}, + {0x3ff1500000000000,0x3f50477ac9b6a004,}, + {0x3ff1500000000000,0x3f3b9a3fdd5c8cb8,}, + {0x3ff1400000000000,0x3f6ec41742abbfa1,}, + {0x3ff1400000000000,0x3f6a162ab6335cb9,}, + {0x3ff1400000000000,0x3f656981d2e11059,}, + {0x3ff1400000000000,0x3f60be1c159a76d2,}, + {0x3ff1400000000000,0x3f5827f1f717e2da,}, + {0x3ff1400000000000,0x3f4dac6008a1dac6,}, + {0x3ff1400000000000,0x3f361bc5394b1683,}, + {0x3ff1300000000000,0x3f6e1d1a688e4838,}, + {0x3ff1300000000000,0x3f6977fcc49cc04e,}, + {0x3ff1300000000000,0x3f64d41f39e03c4c,}, + {0x3ff1300000000000,0x3f6031814729d64c,}, + {0x3ff1300000000000,0x3f572044d72044d7,}, + {0x3ff1300000000000,0x3f4bc00899bc008a,}, + {0x3ff1300000000000,0x3f3288ffbb3b5dc0,}, + {0x3ff1200000000000,0x3f6db37b5e5f4fe0,}, + {0x3ff1200000000000,0x3f691713db81577b,}, + {0x3ff1200000000000,0x3f647be8ef3cbf7f,}, + {0x3ff1200000000000,0x3f5fc3f4348a5207,}, + {0x3ff1200000000000,0x3f56928dbb24d6e0,}, + {0x3ff1200000000000,0x3f4ac73ae9819b50,}, + {0x3ff1200000000000,0x3f30dc899176b30e,}, + {0x3ff1100000000000,0x3f6d868dc6c1230b,}, + {0x3ff1100000000000,0x3f68f2c3fa1e3646,}, + {0x3ff1100000000000,0x3f6460334e904cf6,}, + {0x3ff1100000000000,0x3f5f9db68d4994e6,}, + {0x3ff1100000000000,0x3f567d76ca58177e,}, + {0x3ff1100000000000,0x3f4abf4cb4e4eb53,}, + {0x3ff1100000000000,0x3f31111111111111,}, + {0x3ff1000000000000,0x3f6d95a7c77f0022,}, + {0x3ff1000000000000,0x3f690a63a12a5b1b,}, + {0x3ff1000000000000,0x3f6480553340d500,}, + {0x3ff1000000000000,0x3f5feef80441fef0,}, + {0x3ff1000000000000,0x3f56dfaf24d66004,}, + {0x3ff1000000000000,0x3f4ba59da4055114,}, + {0x3ff1000000000000,0x3f332158583633d0,}, + {0x3ff0f00000000000,0x3f6de021fde021fe,}, + {0x3ff0f00000000000,0x3f695d4bc7331805,}, + {0x3ff0f00000000000,0x3f64dba7ece64472,}, + {0x3ff0f00000000000,0x3f605b35f52102c9,}, + {0x3ff0f00000000000,0x3f57b7eacc9686a0,}, + {0x3ff0f00000000000,0x3f4d77971c358120,}, + {0x3ff0f00000000000,0x3f370834f27f9a57,}, + {0x3ff0e00000000000,0x3f6e6557733baacd,}, + {0x3ff0e00000000000,0x3f69ead7cd391fbc,}, + {0x3ff0e00000000000,0x3f65718733f0ab49,}, + {0x3ff0e00000000000,0x3f60f9652f4a3cc4,}, + {0x3ff0e00000000000,0x3f5904e28eda5f53,}, + {0x3ff0e00000000000,0x3f50195609804390,}, + {0x3ff0e00000000000,0x3f3cc08f7f464c3c,}, + {0x3ff0d00000000000,0x3f6f24a591cbcc53,}, + {0x3ff0d00000000000,0x3f6ab265738c9526,}, + {0x3ff0d00000000000,0x3f6641511e8d2b32,}, + {0x3ff0d00000000000,0x3f61d1681c6e08b0,}, + {0x3ff0d00000000000,0x3f5ac553ee1be396,}, + {0x3ff0d00000000000,0x3f51ea2c71139757,}, + {0x3ff0d00000000000,0x3f4222b1acf1ce96,}, + {0x3ff0d00000000000,0x3eed6c19be9686c4,}, + {0x3ff0c00000000000,0x3f6bb354cee68802,}, + {0x3ff0c00000000000,0x3f674a6615c81a3e,}, + {0x3ff0c00000000000,0x3f62e29f79b47582,}, + {0x3ff0c00000000000,0x3f5cf8010c73e004,}, + {0x3ff0c00000000000,0x3f542d118e47cb98,}, + {0x3ff0c00000000000,0x3f46c8df21ea434e,}, + {0x3ff0c00000000000,0x3f24f0d1682e11cd,}, + {0x3ff0b00000000000,0x3f6ced083dbe5507,}, + {0x3ff0b00000000000,0x3f688c28caead1b7,}, + {0x3ff0b00000000000,0x3f642c6e4b027b9f,}, + {0x3ff0b00000000000,0x3f5f9bb096771e4d,}, + {0x3ff0b00000000000,0x3f56e0ccb21072e1,}, + {0x3ff0b00000000000,0x3f4c50600859c506,}, + {0x3ff0b00000000000,0x3f35c766a27e8011,}, + {0x3ff0a00000000000,0x3f6e5ee45dd96ae2,}, + {0x3ff0a00000000000,0x3f6a05fe2d13ac1a,}, + {0x3ff0a00000000000,0x3f65ae39d09a2c46,}, + {0x3ff0a00000000000,0x3f615796d7438be9,}, + {0x3ff0a00000000000,0x3f5a0429a0429a04,}, + {0x3ff0a00000000000,0x3f515b6694ff5995,}, + {0x3ff0a00000000000,0x3f4169c75795f620,}, + {0x3ff0a00000000000,0x3ed0a00428010a00,}, + {0x3ff0900000000000,0x3f6bb74d5f06c021,}, + {0x3ff0900000000000,0x3f6767697cf36a02,}, + {0x3ff0900000000000,0x3f6318a3ec49a95f,}, + {0x3ff0900000000000,0x3f5d95f87b6602da,}, + {0x3ff0900000000000,0x3f54fce404254fce,}, + {0x3ff0900000000000,0x3f48cc132a157ec5,}, + {0x3ff0900000000000,0x3f2e8b42861539b9,}, + {0x3ff0800000000000,0x3f6d9f7fad35f141,}, + {0x3ff0800000000000,0x3f695766eacbc402,}, + {0x3ff0800000000000,0x3f6510697324501f,}, + {0x3ff0800000000000,0x3f60ca86d879edeb,}, + {0x3ff0800000000000,0x3f590b7d5a7f4a3b,}, + {0x3ff0800000000000,0x3f50842108421084,}, + {0x3ff0800000000000,0x3f3ffbdf80108200,}, + {0x3ff0700000000000,0x3f6fbe0083fef802,}, + {0x3ff0700000000000,0x3f6b7d9dd36c1839,}, + {0x3ff0700000000000,0x3f673e5371d5c338,}, + {0x3ff0700000000000,0x3f630020f30020f3,}, + {0x3ff0700000000000,0x3f5d860bd5ce1620,}, + {0x3ff0700000000000,0x3f550e03db7bd23a,}, + {0x3ff0700000000000,0x3f4930523fbe3368,}, + {0x3ff0700000000000,0x3f3091eb30f07525,}, + {0x3ff0600000000000,0x3f6dd97c0522a9fb,}, + {0x3ff0600000000000,0x3f69a1d0020d9a1d,}, + {0x3ff0600000000000,0x3f656b38f225f6c4,}, + {0x3ff0600000000000,0x3f6135b66ae990fc,}, + {0x3ff0600000000000,0x3f5a02900419a029,}, + {0x3ff0600000000000,0x3f519bda9af51d54,}, + {0x3ff0600000000000,0x3f426e978d4fdf3b,}, + {0x3ff0600000000000,0x3f0a9c567c191351,}, + {0x3ff0500000000000,0x3f6c3a4f47dd3802,}, + {0x3ff0500000000000,0x3f680b3f43ddbf54,}, + {0x3ff0500000000000,0x3f63dd40e4eb0cc6,}, + {0x3ff0500000000000,0x3f5f60a78467ad43,}, + {0x3ff0500000000000,0x3f5708eee638a97a,}, + {0x3ff0500000000000,0x3f4d66ae3cf8796e,}, + {0x3ff0500000000000,0x3f397f7d73404146,}, + {0x3ff0400000000000,0x3f6f0743689e024b,}, + {0x3ff0400000000000,0x3f6adfa65618f693,}, + {0x3ff0400000000000,0x3f66b9180f46a6c3,}, + {0x3ff0400000000000,0x3f6293982cc98af1,}, + {0x3ff0400000000000,0x3f5cde4c8ef16004,}, + {0x3ff0400000000000,0x3f549783f0bf2c7d,}, + {0x3ff0400000000000,0x3f48a5ab62f84008,}, + {0x3ff0400000000000,0x3f30410410410410,}, + {0x3ff0300000000000,0x3f6de7e28de5daaf,}, + {0x3ff0300000000000,0x3f69c8b096334031,}, + {0x3ff0300000000000,0x3f65aa8a35002076,}, + {0x3ff0300000000000,0x3f618d6f048ff7e4,}, + {0x3ff0300000000000,0x3f5ae2bd3eb39e36,}, + {0x3ff0300000000000,0x3f52acb1401034ab,}, + {0x3ff0300000000000,0x3f44f17285e26377,}, + {0x3ff0300000000000,0x3f2236a3ebc349de,}, + {0x3ff0200000000000,0x3f6d0b811316e1c9,}, + {0x3ff0200000000000,0x3f68f4a0b9ff7e9c,}, + {0x3ff0200000000000,0x3f64dec8cf1fb336,}, + {0x3ff0200000000000,0x3f60c9f8ee53d18c,}, + {0x3ff0200000000000,0x3f596c6167556ade,}, + {0x3ff0200000000000,0x3f5146df76cb4965,}, + {0x3ff0200000000000,0x3f4246d687e0bd93,}, + {0x3ff0200000000000,0x3f10204081020408,}, + {0x3ff0100000000000,0x3f6c71547e6d0c77,}, + {0x3ff0100000000000,0x3f6862acae30d576,}, + {0x3ff0100000000000,0x3f64550a308ee839,}, + {0x3ff0100000000000,0x3f60486ca2f46ea6,}, + {0x3ff0100000000000,0x3f5879a746004058,}, + {0x3ff0100000000000,0x3f50647d9d044557,}, + {0x3ff0100000000000,0x3f40a2b70defada3,}, + {0x3ff0100000000000,0x3ef0101010101010,}, + {0x3ff0000000000000,0x3f6c189582d27829,}, + {0x3ff0000000000000,0x3f68120d8a279db6,}, + {0x3ff0000000000000,0x3f640c87d4e50f29,}, + {0x3ff0000000000000,0x3f60080402010080,}, + {0x3ff0000000000000,0x3f580903614479ae,}, + {0x3ff0000000000000,0x3f50040100401004,}, + {0x3ff0000000000000,0x3f40020040080100,}, + {0x3ff0000000000000,0x0,}, +}; + +extern "C" log_data log_f_256[1025] = { + {0x0,0x0,}, + {0x3f4ffc00a0000000,0x3db515621f7809a1,}, + {0x3f5ff802a0000000,0x3dc35621ccf14f1d,}, + {0x3f67f70470000000,0x3ddaf307b4d13ad1,}, + {0x3f6ff00aa0000000,0x3db5885e0250435b,}, + {0x3f73f38a60000000,0x3dae0c912b49e49c,}, + {0x3f77ee11e0000000,0x3de7b05d274f0b49,}, + {0x3f7be79c70000000,0x3d563b23e69b0101,}, + {0x3f7fe02a60000000,0x3de620cf11f86ed2,}, + {0x3f81ebde20000000,0x3dfa332fcbe005b9,}, + {0x3f83e72950000000,0x3dfa4b4fb1f006b3,}, + {0x3f85e1f700000000,0x3ddf65f2827d6177,}, + {0x3f87dc4750000000,0x3dff0214edba4a26,}, + {0x3f89d61aa0000000,0x3dfb8d7b196327b4,}, + {0x3f8bcf7120000000,0x3df8e87097825ef6,}, + {0x3f8dc84b10000000,0x3df22470295078e9,}, + {0x3f8fc0a8b0000000,0x3dbf807c79f3db4f,}, + {0x3f90dc4510000000,0x3e015f990f431ff4,}, + {0x3f91d7f7e0000000,0x3e073dd7cd8af806,}, + {0x3f92d36ce0000000,0x3e0f6aaf85d9a0b8,}, + {0x3f93cea440000000,0x3dea352ba779a52b,}, + {0x3f94c99e00000000,0x3df24077b31977d8,}, + {0x3f95c45a50000000,0x3ddb8d38893bd24f,}, + {0x3f96bed940000000,0x3e01a36fa1df4fae,}, + {0x3f97b91b00000000,0x3dff56c46aa49fd5,}, + {0x3f98b31fa0000000,0x3e0953601c3ab48e,}, + {0x3f99ace750000000,0x3df47314513409c2,}, + {0x3f9aa67210000000,0x3e0dd06b53ad716c,}, + {0x3f9b9fc020000000,0x3dfebe465fef5197,}, + {0x3f9c98d180000000,0x3e0a019027abe9d9,}, + {0x3f9d91a660000000,0x3e08a87987c59634,}, + {0x3f9e8a3ee0000000,0x3de866e5605c21ac,}, + {0x3f9f829b00000000,0x3e0cf0660099f1f8,}, + {0x3fa03d5d80000000,0x3e079cfbbc4b0769,}, + {0x3fa0b94f70000000,0x3e1832c2eced21fc,}, + {0x3fa1352370000000,0x3e10b2e3e53c48e0,}, + {0x3fa1b0d980000000,0x3e1247b2ff85945e,}, + {0x3fa22c71b0000000,0x3e19d5074a063e20,}, + {0x3fa2a7ec20000000,0x3df0a74398c42b75,}, + {0x3fa32348c0000000,0x3e0c005a5b6e42c8,}, + {0x3fa39e87b0000000,0x3e13fd7abf5202b6,}, + {0x3fa419a900000000,0x3e12b26d73719f52,}, + {0x3fa494acc0000000,0x3dfa6c88e3c52b7f,}, + {0x3fa50f92f0000000,0x3e083e65b3ec2a48,}, + {0x3fa58a5ba0000000,0x3e1f91c9a918d51f,}, + {0x3fa60506f0000000,0x3e1d31b516fdf9ac,}, + {0x3fa67f94f0000000,0x3dd297b307cf9f94,}, + {0x3fa6fa0590000000,0x3dfe3db415e41d63,}, + {0x3fa77458f0000000,0x3e08cb73f118d3cb,}, + {0x3fa7ee8f20000000,0x3e073505ef4f72d2,}, + {0x3fa868a830000000,0x3dd07ed9dc5ecb54,}, + {0x3fa8e2a420000000,0x3e00e86e7bac050a,}, + {0x3fa95c8300000000,0x3e1d91c7d6fad074,}, + {0x3fa9d644f0000000,0x3e1bff44f2414e69,}, + {0x3faa4fe9f0000000,0x3e1f47a469ed7eff,}, + {0x3faac97220000000,0x3de711f8d3ef0132,}, + {0x3fab42dd70000000,0x3de1971bec28d14c,}, + {0x3fabbc2bf0000000,0x3e1889e82e796ebf,}, + {0x3fac355dd0000000,0x3dd243e5999357f0,}, + {0x3facae72f0000000,0x3e172b8415037f69,}, + {0x3fad276b80000000,0x3e15b616a423c78a,}, + {0x3fada04780000000,0x3e17c724a58f63ee,}, + {0x3fae190700000000,0x3e184ec02b73373b,}, + {0x3fae91aa10000000,0x3e1229f0beaff11a,}, + {0x3faf0a30c0000000,0x3da162a6617cc971,}, + {0x3faf829b00000000,0x3e1cf0660099f1f8,}, + {0x3faffae910000000,0x3de9b9303374262c,}, + {0x3fb0398d60000000,0x3e26c44a9d640680,}, + {0x3fb0759830000000,0x3e166391c4c06d2a,}, + {0x3fb0b194e0000000,0x3e2c1a2ccdd49ed4,}, + {0x3fb0ed8390000000,0x3e26aa4dfc17256f,}, + {0x3fb1296440000000,0x3e100b8ab1122b95,}, + {0x3fb16536e0000000,0x3e2d46f5c1d0c4b8,}, + {0x3fb1a0fba0000000,0x3dfbf8a51fe618cf,}, + {0x3fb1dcb260000000,0x3e0ed8ca227af4f4,}, + {0x3fb2185b30000000,0x3e26eb439cec0e1a,}, + {0x3fb253f620000000,0x3e2e14282df1f6d3,}, + {0x3fb28f8340000000,0x3e143b6a35d6a846,}, + {0x3fb2cb0280000000,0x3e0faef0f716532c,}, + {0x3fb30673f0000000,0x3e016453278a773c,}, + {0x3fb341d790000000,0x3e186f47424a660e,}, + {0x3fb37d2d70000000,0x3e18a0c73eaac900,}, + {0x3fb3b87590000000,0x3e21636ddbea6b53,}, + {0x3fb3f3b000000000,0x3e105003c48e959c,}, + {0x3fb42edcb0000000,0x3e2d4c8de077753e,}, + {0x3fb469fbc0000000,0x3e2d76b6cc789e4b,}, + {0x3fb4a50d30000000,0x3e254360801ecf77,}, + {0x3fb4e01100000000,0x3e2146b5cb9fbe59,}, + {0x3fb51b0730000000,0x3e2e0c307ed24f1d,}, + {0x3fb555efe0000000,0x3e102d42d25e321a,}, + {0x3fb590caf0000000,0x3e2be038509eae45,}, + {0x3fb5cb9890000000,0x3e076a2f7c894ca0,}, + {0x3fb60658a0000000,0x3e226ea18763bdd4,}, + {0x3fb6410b40000000,0x3e1bf9eac070c342,}, + {0x3fb67bb070000000,0x3e037607dc92da7c,}, + {0x3fb6b64830000000,0x3dfafe40cf5ec882,}, + {0x3fb6f0d280000000,0x3e25cad69737c933,}, + {0x3fb72b4f80000000,0x3e10baa3ecccffce,}, + {0x3fb765bf20000000,0x3e0d35f09a1fe51e,}, + {0x3fb7a02160000000,0x3e2ec93c24994308,}, + {0x3fb7da7660000000,0x3e2af62599088902,}, + {0x3fb814be20000000,0x3e0fc601b2381da8,}, + {0x3fb84ef890000000,0x3e21d0505465b72d,}, + {0x3fb88925d0000000,0x3e027d7157d5d822,}, + {0x3fb8c345d0000000,0x3e18c66c83d6b2d1,}, + {0x3fb8fd58a0000000,0x3e25184226dfc869,}, + {0x3fb9375e50000000,0x3e15657b770dce03,}, + {0x3fb97156d0000000,0x3e291ec7c07cca05,}, + {0x3fb9ab4240000000,0x3e1880ceb36fb30f,}, + {0x3fb9e52090000000,0x3e1fe726bf596a5c,}, + {0x3fba1ef1d0000000,0x3e200c39a82edbf3,}, + {0x3fba58b600000000,0x3e28564647194747,}, + {0x3fba926d30000000,0x3e2495aac6ca17a4,}, + {0x3fbacc1760000000,0x3e208665587c5f48,}, + {0x3fbb05b490000000,0x3e27dc87fc8b063e,}, + {0x3fbb3f44d0000000,0x3e26443fa2a7b1bc,}, + {0x3fbb78c820000000,0x3e2761db4210878d,}, + {0x3fbbb23e90000000,0x3e0b474ba73e5531,}, + {0x3fbbeba810000000,0x3e2028cec90e9242,}, + {0x3fbc2504b0000000,0x3e2ef3ae2f89a1df,}, + {0x3fbc5e5480000000,0x3e2eb78e862bac30,}, + {0x3fbc979780000000,0x3e2af1d23fded106,}, + {0x3fbcd0cdb0000000,0x3e2f1827c29b6a1c,}, + {0x3fbd09f720000000,0x3e26989048c00035,}, + {0x3fbd4313d0000000,0x3e19b2cd75790dd9,}, + {0x3fbd7c23c0000000,0x3e1a72cd0236459b,}, + {0x3fbdb52700000000,0x3df87d9277856ae2,}, + {0x3fbdee1d80000000,0x3e29abdae4bf1ac2,}, + {0x3fbe270760000000,0x3e2c55e5cbd3d510,}, + {0x3fbe5fe4a0000000,0x3e264e540a2c1160,}, + {0x3fbe98b540000000,0x3e22ce28cee9138a,}, + {0x3fbed17940000000,0x3e2d06f0175e45b1,}, + {0x3fbf0a30c0000000,0x3db162a6617cc971,}, + {0x3fbf42dba0000000,0x3e0d11676a466905,}, + {0x3fbf7b79f0000000,0x3e2d86fbbd9e05da,}, + {0x3fbfb40bd0000000,0x3e1bfd3817d96f6a,}, + {0x3fbfec9130000000,0x3dfdbeabaaa2e51a,}, + {0x3fc0128500000000,0x3e34dbf95e79adff,}, + {0x3fc02ebb40000000,0x3e15f9ea5705a320,}, + {0x3fc04aeb40000000,0x3e227d9afa9065cd,}, + {0x3fc0671510000000,0x3e1652cb7150c648,}, + {0x3fc08338a0000000,0x3e3ff450533cac82,}, + {0x3fc09f5610000000,0x3e3dce33867d4754,}, + {0x3fc0bb6d60000000,0x3e123d55193cf334,}, + {0x3fc0d77e70000000,0x3e39a11cb2cd2ee3,}, + {0x3fc0f38970000000,0x3e034b12e530bb61,}, + {0x3fc10f8e40000000,0x3e1129cd898f798d,}, + {0x3fc12b8cf0000000,0x3e128c5229284f03,}, + {0x3fc1478580000000,0x3e219d0ab1a28814,}, + {0x3fc16377f0000000,0x3e36248323c357e8,}, + {0x3fc17f6450000000,0x3e31f94c21fd684a,}, + {0x3fc19b4aa0000000,0x3df9da277db69ded,}, + {0x3fc1b72ad0000000,0x3e24bd9e80a41812,}, + {0x3fc1d304f0000000,0x3e3186a592bb20bb,}, + {0x3fc1eed900000000,0x3e3c5b858558dc26,}, + {0x3fc20aa710000000,0x3e30205f2c943485,}, + {0x3fc2266f10000000,0x3e3214b596faa3e0,}, + {0x3fc2423110000000,0x3e1dd28717fe1c46,}, + {0x3fc25ded00000000,0x3e3578d5a3854f17,}, + {0x3fc279a300000000,0x3df569ef432b3235,}, + {0x3fc29552f0000000,0x3e303fea46980bb9,}, + {0x3fc2b0fcf0000000,0x3e1d8d177ca3e30a,}, + {0x3fc2cca0f0000000,0x3e27d7c9421cdca0,}, + {0x3fc2e83f00000000,0x3e080d079ea9ebd9,}, + {0x3fc303d710000000,0x3e31c8ffa5fd28c7,}, + {0x3fc31f6930000000,0x3e3d6332cc6c8d2e,}, + {0x3fc33af570000000,0x3e25dc393d9945fd,}, + {0x3fc3567bb0000000,0x3e3f845250d25399,}, + {0x3fc371fc20000000,0x3dce8f743bcd96c5,}, + {0x3fc38d7690000000,0x3e322c861129678e,}, + {0x3fc3a8eb20000000,0x3e3a6346ebeddf57,}, + {0x3fc3c459d0000000,0x3e3deededc86f6b7,}, + {0x3fc3dfc2b0000000,0x3dfd98c5395315c6,}, + {0x3fc3fb25a0000000,0x3e2654a32b7cd66b,}, + {0x3fc41682b0000000,0x3e3ee4f77fdc7bf0,}, + {0x3fc431da00000000,0x3e00508241bc1b70,}, + {0x3fc44d2b60000000,0x3e3996fa3ccfa7b3,}, + {0x3fc4687700000000,0x3e250bc4fd740e56,}, + {0x3fc483bcc0000000,0x3e39cdc7ba949c90,}, + {0x3fc49efcc0000000,0x3e28c4f9bc29982b,}, + {0x3fc4ba36f0000000,0x3e1cd2af2ad13038,}, + {0x3fc4d56b50000000,0x3e2e63b00b002b53,}, + {0x3fc4f099f0000000,0x3e2288c2c81a0a03,}, + {0x3fc50bc2c0000000,0x3e3a5386b695ca37,}, + {0x3fc526e5e0000000,0x3e1d0da1bd17200f,}, + {0x3fc5420330000000,0x3e34f50b46b476c3,}, + {0x3fc55d1ad0000000,0x3e208cb5bb29bb4d,}, + {0x3fc5782cb0000000,0x3e1848b16e72ba1b,}, + {0x3fc59338d0000000,0x3e3330410ba68b75,}, + {0x3fc5ae3f40000000,0x3e347548f512f809,}, + {0x3fc5c94000000000,0x3e2d65cae4d6e65c,}, + {0x3fc5e43b10000000,0x3e1adeaf152cc44a,}, + {0x3fc5ff3070000000,0x3df4f27a790e7c41,}, + {0x3fc61a2020000000,0x3e0a0eeecee8defa,}, + {0x3fc6350a20000000,0x3e31554eaf6055c1,}, + {0x3fc64fee80000000,0x3e304bf896fca299,}, + {0x3fc66acd40000000,0x3e13956a86f6ff1b,}, + {0x3fc685a650000000,0x3e33ddf706ab49f8,}, + {0x3fc6a079d0000000,0x3dfef55a3f8448d1,}, + {0x3fc6bb47a0000000,0x3e33d0067d9348fb,}, + {0x3fc6d60fe0000000,0x3e2c6748723551d9,}, + {0x3fc6f0d280000000,0x3e35cad69737c933,}, + {0x3fc70b8f90000000,0x3e2e86a9d4c9ed53,}, + {0x3fc7264700000000,0x3e3f47e88b20f18c,}, + {0x3fc740f8f0000000,0x3e2500de9326cdfd,}, + {0x3fc75ba540000000,0x3e3591dddca58bc5,}, + {0x3fc7764c10000000,0x3e1479093a481a3d,}, + {0x3fc790ed40000000,0x3e3dc4c666ef539e,}, + {0x3fc7ab8900000000,0x3e1086c848df1b59,}, + {0x3fc7c61f20000000,0x3e3cce6dc6d24ce4,}, + {0x3fc7e0afd0000000,0x3e28c309cf3e0ec8,}, + {0x3fc7fb3af0000000,0x3e376ea8240adb9f,}, + {0x3fc815c0a0000000,0x3e04357ead6836ff,}, + {0x3fc83040c0000000,0x3e32379e5b71c6e6,}, + {0x3fc84abb70000000,0x3e261944e4aa4164,}, + {0x3fc86530a0000000,0x3e318e198bb0cb4f,}, + {0x3fc87fa060000000,0x3e24832442408024,}, + {0x3fc89a0aa0000000,0x3e39a9ce05fded48,}, + {0x3fc8b46f80000000,0x3e111b12d9f2102e,}, + {0x3fc8cecee0000000,0x3e2d2b4b48beab7b,}, + {0x3fc8e928d0000000,0x3e3d10da8154b13d,}, + {0x3fc9037d60000000,0x3e34300986f52be1,}, + {0x3fc91dcc80000000,0x3e386817bc6abddf,}, + {0x3fc9381640000000,0x3e2c565673852b8c,}, + {0x3fc9525a90000000,0x3e39e8ad68ec8261,}, + {0x3fc96c9990000000,0x3daa9a88d59cbb45,}, + {0x3fc986d320000000,0x3e140c064ed59375,}, + {0x3fc9a10750000000,0x3e2a62164aa6242d,}, + {0x3fc9bb3620000000,0x3e3cfbf706abaf19,}, + {0x3fc9d55fa0000000,0x3e38c5a0b99603c5,}, + {0x3fc9ef83d0000000,0x3e13b4d19e90980c,}, + {0x3fca09a2a0000000,0x3e173cc44cc4657e,}, + {0x3fca23bc10000000,0x3e3fc56ac6326e23,}, + {0x3fca3dd040000000,0x3e37270cbed09b37,}, + {0x3fca57df20000000,0x3e30489b99c8ca1e,}, + {0x3fca71e8b0000000,0x3e2ef7eef5359110,}, + {0x3fca8becf0000000,0x3e39105e3185cf22,}, + {0x3fcaa5ebf0000000,0x3e31526d5f56c96b,}, + {0x3fcabfe5a0000000,0x3e3c8c24970ac6a1,}, + {0x3fcad9da10000000,0x3e3f04e77d4837fc,}, + {0x3fcaf3c940000000,0x3e3d017fe5b19cc0,}, + {0x3fcb0db330000000,0x3e3ac41fee1438eb,}, + {0x3fcb2797e0000000,0x3e3c8c6417756f93,}, + {0x3fcb417760000000,0x3e1a5d5574055998,}, + {0x3fcb5b5190000000,0x3e3d1f6b48dd13ff,}, + {0x3fcb7526a0000000,0x3e1172381b7e5cf1,}, + {0x3fcb8ef670000000,0x3de0830ea66642f1,}, + {0x3fcba8c100000000,0x3e35c8da32e29eef,}, + {0x3fcbc28670000000,0x3e20b63358a7e73a,}, + {0x3fcbdc46a0000000,0x3e3c689625b4023d,}, + {0x3fcbf601b0000000,0x3e361c89c354a3e2,}, + {0x3fcc0fb790000000,0x3e399fab90006617,}, + {0x3fcc296850000000,0x3e263063028c211c,}, + {0x3fcc4313e0000000,0x3e2d53a4f37ce996,}, + {0x3fcc5cba50000000,0x3e20eb90929decb4,}, + {0x3fcc765b90000000,0x3e3c9ad1ab6b3697,}, + {0x3fcc8ff7c0000000,0x3e2e6a6886b09760,}, + {0x3fcca98ed0000000,0x3e117afa59cf9cd7,}, + {0x3fccc320c0000000,0x3dc7650240e6994e,}, + {0x3fccdcad90000000,0x3e1ae8f2f807e59b,}, + {0x3fccf63540000000,0x3e3c138bb891cd04,}, + {0x3fcd0fb7f0000000,0x3e112af2856a6fce,}, + {0x3fcd293580000000,0x3e0b6b3e6c7f6bab,}, + {0x3fcd42adf0000000,0x3e3d86ba28ffc0a0,}, + {0x3fcd5c2160000000,0x3e369f7722b7221b,}, + {0x3fcd758fc0000000,0x3e32bdfa97bd5d30,}, + {0x3fcd8ef910000000,0x3e35e63abbe80f27,}, + {0x3fcda85d60000000,0x3e106728032982da,}, + {0x3fcdc1bca0000000,0x3df57d8fac1a628d,}, + {0x3fcddb16d0000000,0x3e319d384421a3bf,}, + {0x3fcdf46c00000000,0x3e38e45a5e82b0b8,}, + {0x3fce0dbc30000000,0x3e3b25559233f053,}, + {0x3fce270760000000,0x3e3c55e5cbd3d510,}, + {0x3fce404da0000000,0x3dda5b9e0447d976,}, + {0x3fce598ed0000000,0x3e26a1f8bb2d0c38,}, + {0x3fce72cb10000000,0x3def68eea4666faa,}, + {0x3fce8c0250000000,0x3e1552d2ff48fe2e,}, + {0x3fcea53490000000,0x3e3c47581b934c74,}, + {0x3fcebe61f0000000,0x3e2375ec2baccf02,}, + {0x3fced78a50000000,0x3e319505bc6d4de5,}, + {0x3fcef0adc0000000,0x3e37b8b26ca431bd,}, + {0x3fcf09cc50000000,0x3d9b768250636667,}, + {0x3fcf22e5e0000000,0x3e2cbc417561d7d0,}, + {0x3fcf3bfa90000000,0x3e1a6b3b3e5526f7,}, + {0x3fcf550a50000000,0x3e292decdc1c5f6e,}, + {0x3fcf6e1530000000,0x3e10a98d95a214ec,}, + {0x3fcf871b20000000,0x3e312aa08a0295ae,}, + {0x3fcfa01c30000000,0x3e376af978238148,}, + {0x3fcfb91860000000,0x3e3abc7c551aaa8d,}, + {0x3fcfd20fb0000000,0x3e3eedfb8ea9234e,}, + {0x3fcfeb0230000000,0x3e1f303e62dc65ac,}, + {0x3fd001f7e0000000,0x3e392118a95740ca,}, + {0x3fd00e6c40000000,0x3e36b540731a354c,}, + {0x3fd01ade30000000,0x3e42273deed9e664,}, + {0x3fd0274dc0000000,0x3e16c232f3d139f0,}, + {0x3fd033bad0000000,0x3e4f4e81c30bc148,}, + {0x3fd0402590000000,0x3e32d341036b89ef,}, + {0x3fd04c8de0000000,0x3e1841e01945aed3,}, + {0x3fd058f3c0000000,0x3e3c0faf1799432e,}, + {0x3fd0655740000000,0x3e3889c2263bf691,}, + {0x3fd071b850000000,0x3e4f9ab21a3a2e10,}, + {0x3fd07e1710000000,0x3e33c7210339b0c8,}, + {0x3fd08a7360000000,0x3e39f15ebc1d40c6,}, + {0x3fd096cd50000000,0x3e35645f998d2055,}, + {0x3fd0a324e0000000,0x3e239c871afb9fbd,}, + {0x3fd0af7a00000000,0x3e4d6d84f33e5251,}, + {0x3fd0bbccd0000000,0x3e461a497996662f,}, + {0x3fd0c81d40000000,0x3e40c150d2185ff1,}, + {0x3fd0d46b50000000,0x3e3e6add2c81f641,}, + {0x3fd0e0b700000000,0x3e434869501c53c3,}, + {0x3fd0ed0050000000,0x3e4ecafb48e2b5e9,}, + {0x3fd0f94750000000,0x3e438cd356cf407c,}, + {0x3fd1058bf0000000,0x3e435c95aa313f41,}, + {0x3fd111ce40000000,0x3daf7266e47b4a5a,}, + {0x3fd11e0e20000000,0x3e4b5b396e01dc0d,}, + {0x3fd12a4bc0000000,0x3e2c88d4b15f3d72,}, + {0x3fd1368700000000,0x3e249d4582f6cc53,}, + {0x3fd142bfe0000000,0x3e473408e730c2db,}, + {0x3fd14ef670000000,0x3e4f10d0b42cd102,}, + {0x3fd15b2ab0000000,0x3e4e85189c712d92,}, + {0x3fd1675ca0000000,0x3e47574c1c073990,}, + {0x3fd1738c40000000,0x3e3699a63916ffcd,}, + {0x3fd17fb980000000,0x3e4c2a12baba2c5b,}, + {0x3fd18be480000000,0x3e3764dc167f6f36,}, + {0x3fd1980d20000000,0x3e4ba846dece9e8e,}, + {0x3fd1a43380000000,0x3e3b99fd0af5f396,}, + {0x3fd1b05790000000,0x3e1f07b48ae648eb,}, + {0x3fd1bc7940000000,0x3e4fa3919879c5c2,}, + {0x3fd1c898c0000000,0x3e16999fafbc68e7,}, + {0x3fd1d4b5e0000000,0x3e3e5a89152de8cc,}, + {0x3fd1e0d0c0000000,0x3e29b8b5f1e55362,}, + {0x3fd1ece950000000,0x3e34a2b9ec613d93,}, + {0x3fd1f8ff90000000,0x3e4c9145e51b0103,}, + {0x3fd2051390000000,0x3e4ee760b70af0b0,}, + {0x3fd2112550000000,0x3e430c2c173c5d15,}, + {0x3fd21d34c0000000,0x3e4ab72daa97d946,}, + {0x3fd22941f0000000,0x3e479ef2cb44850a,}, + {0x3fd2354ce0000000,0x3e36f2228712f9fd,}, + {0x3fd2415580000000,0x3e47fa2807ff9914,}, + {0x3fd24d5be0000000,0x3e4ed5dff1143f82,}, + {0x3fd2596010000000,0x3e0beec73de11275,}, + {0x3fd26561f0000000,0x3e133862d2219beb,}, + {0x3fd2716190000000,0x3e13f853d3c7d856,}, + {0x3fd27d5ef0000000,0x3e1db5f36e45c39b,}, + {0x3fd2895a10000000,0x3e2ef4351af5a498,}, + {0x3fd29552f0000000,0x3e403fea46980bb9,}, + {0x3fd2a14990000000,0x3e4eec5792205706,}, + {0x3fd2ad3e00000000,0x3e456e66e5cb9223,}, + {0x3fd2b93030000000,0x3e45713a493b4a50,}, + {0x3fd2c52030000000,0x3df3e098429461a1,}, + {0x3fd2d10de0000000,0x3e48a10b0630fb84,}, + {0x3fd2dcf960000000,0x3e4f1fa42d28a38d,}, + {0x3fd2e8e2b0000000,0x3e45c23a61385992,}, + {0x3fd2f4c9c0000000,0x3e4e2f4b8f8249ba,}, + {0x3fd300aea0000000,0x3e4a0c6a17ab45bb,}, + {0x3fd30c9150000000,0x3e35fc7af5a9d7af,}, + {0x3fd31871c0000000,0x3e42a88309f5729a,}, + {0x3fd3245000000000,0x3e42ae0e938dcded,}, + {0x3fd3302c10000000,0x3e396196217dc2a4,}, + {0x3fd33c05f0000000,0x3e128dda8df38fe4,}, + {0x3fd347dd90000000,0x3e4530faa9ac8acf,}, + {0x3fd353b310000000,0x3e2bb6f667280c9f,}, + {0x3fd35f8650000000,0x3e4926527c10d8af,}, + {0x3fd36b5770000000,0x3e3af0445a5e16a7,}, + {0x3fd3772660000000,0x3e25fec2d792a759,}, + {0x3fd382f320000000,0x3e16c4ef9e2de2e6,}, + {0x3fd38ebdb0000000,0x3e2c76990582e67d,}, + {0x3fd39a8610000000,0x3e43e8a31dca326e,}, + {0x3fd3a64c50000000,0x3e35a517a71cbcd7,}, + {0x3fd3b21060000000,0x3e3ae6ec3e1267ef,}, + {0x3fd3bdd240000000,0x3e4d6296d425b479,}, + {0x3fd3c99200000000,0x3e4c36428385154d,}, + {0x3fd3d54fa0000000,0x3e3707dc3e1cd9a4,}, + {0x3fd3e10b10000000,0x3e39c05f3bcf1454,}, + {0x3fd3ecc460000000,0x3e0debe9fd79d83f,}, + {0x3fd3f87b80000000,0x3e3824ea2028aba7,}, + {0x3fd4043080000000,0x3e3a1a9f8ef4304a,}, + {0x3fd40fe360000000,0x3e2981bcb8bfcf3e,}, + {0x3fd41b9410000000,0x3e499c17dcb7f60e,}, + {0x3fd42742b0000000,0x3e309f6678d8fd48,}, + {0x3fd432ef20000000,0x3e4409d0276b3674,}, + {0x3fd43e9970000000,0x3e4e582387ee4819,}, + {0x3fd44a41b0000000,0x3e318f11ee28f37d,}, + {0x3fd455e7c0000000,0x3e44e4035b18c6cc,}, + {0x3fd4618bc0000000,0x3e20e2f613e85bda,}, + {0x3fd46d2d90000000,0x3e48500acd93afb4,}, + {0x3fd478cd50000000,0x3e42b367b226fc32,}, + {0x3fd4846af0000000,0x3e44eb7a70574722,}, + {0x3fd4900680000000,0x3df0027433001e5f,}, + {0x3fd49b9fe0000000,0x3e46f82ed60e2c56,}, + {0x3fd4a73730000000,0x3e49d9f32ee58a06,}, + {0x3fd4b2cc70000000,0x3e355567f0343874,}, + {0x3fd4be5f90000000,0x3e35dde2836d3265,}, + {0x3fd4c9f090000000,0x3e4c2a58788863c8,}, + {0x3fd4d57f80000000,0x3e4fdfc4fe499ff4,}, + {0x3fd4e10c60000000,0x3e479140c141f8b2,}, + {0x3fd4ec9730000000,0x3e2300134d7aaf05,}, + {0x3fd4f81fe0000000,0x3e31d8f40184de58,}, + {0x3fd503a680000000,0x3e2658e597370e90,}, + {0x3fd50f2b00000000,0x3e4c3c0d04a04624,}, + {0x3fd51aad80000000,0x3e3cb7e0b42724f6,}, + {0x3fd5262de0000000,0x3e4d7310f23047bb,}, + {0x3fd531ac40000000,0x3e35fb9df83b7d93,}, + {0x3fd53d2880000000,0x3e4877bddd8d0292,}, + {0x3fd548a2c0000000,0x3e2d6e93167e6308,}, + {0x3fd5541ae0000000,0x3e49237f3f4aa91c,}, + {0x3fd55f9100000000,0x3e3e90fb866e21c8,}, + {0x3fd56b0510000000,0x3e36860c923dde25,}, + {0x3fd5767710000000,0x3e3d1569b1526adb,}, + {0x3fd581e700000000,0x3e4a965c19c3c9da,}, + {0x3fd58d54f0000000,0x3e40dc05e47cc29e,}, + {0x3fd598c0d0000000,0x3e42d0f3d05b4793,}, + {0x3fd5a42ab0000000,0x3e0e99fc338a1a41,}, + {0x3fd5af9270000000,0x3e4f99bc7f9a0140,}, + {0x3fd5baf840000000,0x3e3aa86c6517078c,}, + {0x3fd5c65c00000000,0x3e39166601f9fe7f,}, + {0x3fd5d1bdb0000000,0x3e4eb01394a11b1c,}, + {0x3fd5dd1d70000000,0x3e24cdcea13cefd4,}, + {0x3fd5e87b20000000,0x3e0852a93e8c7bba,}, + {0x3fd5f3d6c0000000,0x3e45144bd7c2470d,}, + {0x3fd5ff3070000000,0x3e04f27a790e7c41,}, + {0x3fd60a8810000000,0x3e2e8d2dd37390f3,}, + {0x3fd615ddb0000000,0x3e32fb04f1f2a42f,}, + {0x3fd6213150000000,0x3e3093ac7d03b559,}, + {0x3fd62c82f0000000,0x3e25ce3ca97b7af9,}, + {0x3fd637d290000000,0x3e1329a82284328b,}, + {0x3fd6432030000000,0x3df111efe027a01d,}, + {0x3fd64e6bd0000000,0x3e046a6bfa01a758,}, + {0x3fd659b570000000,0x3e281f0f940ed858,}, + {0x3fd664fd10000000,0x3e4033718e55e464,}, + {0x3fd67042c0000000,0x3e0307c6148dbdcf,}, + {0x3fd67b8660000000,0x3e4a64f38fd63ea1,}, + {0x3fd686c810000000,0x3e4d36295d88857c,}, + {0x3fd69207d0000000,0x3e361167489e90c4,}, + {0x3fd69d4590000000,0x3e2501b1637b7f30,}, + {0x3fd6a88150000000,0x3e3a80e41d37b3a7,}, + {0x3fd6b3bb20000000,0x3e21aca1ec4af526,}, + {0x3fd6bef2f0000000,0x3e384471f1f928fb,}, + {0x3fd6ca28d0000000,0x3e271a4c2b42e312,}, + {0x3fd6d55cb0000000,0x3e42b86cdce4574d,}, + {0x3fd6e08ea0000000,0x3e445743c7182726,}, + {0x3fd6ebbea0000000,0x3e3803b99c298fba,}, + {0x3fd6f6eca0000000,0x3e4b164524163f7c,}, + {0x3fd70218c0000000,0x3e178e954a387113,}, + {0x3fd70d42e0000000,0x3e23c491aead337f,}, + {0x3fd7186b10000000,0x3e13811934e2677d,}, + {0x3fd7239140000000,0x3e4cca01c1d52bdd,}, + {0x3fd72eb590000000,0x3e45593dd010d08a,}, + {0x3fd739d7f0000000,0x3e3aef401a738931,}, + {0x3fd744f860000000,0x3e29f8f370b173f5,}, + {0x3fd75016e0000000,0x3e0c574c40ba4331,}, + {0x3fd75b3370000000,0x3df49e9da52ef8fd,}, + {0x3fd7664e10000000,0x3e21cede76092a2a,}, + {0x3fd77166c0000000,0x3e3d10096999f82a,}, + {0x3fd77c7d90000000,0x3ddbb9140f9af1ff,}, + {0x3fd7879260000000,0x3e4ad6e47d26bd9e,}, + {0x3fd792a550000000,0x3e4fba8f44f82bb5,}, + {0x3fd79db660000000,0x3e4035f5967374f3,}, + {0x3fd7a8c580000000,0x3e3b37d5107d6a25,}, + {0x3fd7b3d2b0000000,0x3e493e91aa57a7e4,}, + {0x3fd7bede00000000,0x3e446f5f7f3c3e1a,}, + {0x3fd7c9e770000000,0x3defc67d2aae8ee8,}, + {0x3fd7d4eee0000000,0x3e4ebdd8dbf9c1c3,}, + {0x3fd7dff480000000,0x3e407b066208cdf1,}, + {0x3fd7eaf830000000,0x3e47055f86c9674c,}, + {0x3fd7f5fa00000000,0x3e43aaf494619655,}, + {0x3fd800f9f0000000,0x3e2ee4a6579fcdbc,}, + {0x3fd80bf7f0000000,0x3e447cb6cdb9bf79,}, + {0x3fd816f410000000,0x3e4b41a92b6b6e1b,}, + {0x3fd821ee50000000,0x3e4d5362c1540a51,}, + {0x3fd82ce6b0000000,0x3e4bfc9b39b3dd33,}, + {0x3fd837dd30000000,0x3e4887604b76be86,}, + {0x3fd842d1d0000000,0x3e443d162e927629,}, + {0x3fd84dc490000000,0x3e406678100194e6,}, + {0x3fd858b570000000,0x3e3c97310ab6559b,}, + {0x3fd863a470000000,0x3e3e67c4000f8150,}, + {0x3fd86e9190000000,0x3e4466174013f9b1,}, + {0x3fd8797cd0000000,0x3e4f2853c6a14242,}, + {0x3fd8846640000000,0x3e40c00c47f4ef99,}, + {0x3fd88f4dd0000000,0x3e34e41e3a4c690b,}, + {0x3fd89a3380000000,0x3e3b05096ad69c62,}, + {0x3fd8a51750000000,0x3e4b34f007064bdf,}, + {0x3fd8aff950000000,0x3e44cc2effd1d3f3,}, + {0x3fd8bad970000000,0x3e4b8a7af56e4824,}, + {0x3fd8c5b7c0000000,0x3e40b169150faa58,}, + {0x3fd8d09430000000,0x3e4581ead2eca309,}, + {0x3fd8db6ed0000000,0x3e36789cb29e13b4,}, + {0x3fd8e64790000000,0x3e43203ef7465063,}, + {0x3fd8f11e80000000,0x3e3cd98b1df85da7,}, + {0x3fd8fbf390000000,0x3e4e604903abf1ad,}, + {0x3fd906c6e0000000,0x3e20e23a9cf31d2c,}, + {0x3fd9119850000000,0x3e032baa77f6b92d,}, + {0x3fd91c67e0000000,0x3e468b507b0f8fa9,}, + {0x3fd92735b0000000,0x3e25f8cd37656c8b,}, + {0x3fd93201a0000000,0x3e3e8d4cda86c770,}, + {0x3fd93ccbc0000000,0x3e451f4db3fd780c,}, + {0x3fd9479410000000,0x3e48422df57499ba,}, + {0x3fd9525a90000000,0x3e49e8ad68ec8261,}, + {0x3fd95d1f40000000,0x3e4b4b94143f0f01,}, + {0x3fd967e220000000,0x3e4da30c3641ec93,}, + {0x3fd972a340000000,0x3e11351586970275,}, + {0x3fd97d6280000000,0x3e341a8ee5160b77,}, + {0x3fd9881ff0000000,0x3e468d4de0195c27,}, + {0x3fd992dba0000000,0x3e31b8da7a89f990,}, + {0x3fd99d9580000000,0x3e117e08acba92ef,}, + {0x3fd9a84d90000000,0x3e1dde4d257555ed,}, + {0x3fd9b303d0000000,0x3e3d68d87c72f49d,}, + {0x3fd9bdb850000000,0x3e2133ced66aa457,}, + {0x3fd9c86b00000000,0x3e26e04314dd0229,}, + {0x3fd9d31be0000000,0x3e4427da756dd101,}, + {0x3fd9ddcb00000000,0x3e40cdce8337e51f,}, + {0x3fd9e87850000000,0x3e4cdad1c675d957,}, + {0x3fd9f323e0000000,0x3e497f3097e56d1b,}, + {0x3fd9fdcdb0000000,0x3e2faa7cdb0d8bd9,}, + {0x3fda0875b0000000,0x3e3298745c3108f4,}, + {0x3fda131be0000000,0x3e4ed286b9b25e6a,}, + {0x3fda1dc060000000,0x3e3356e655901287,}, + {0x3fda286310000000,0x3e3608ae9896a3ab,}, + {0x3fda330400000000,0x3e2027d31b9a54f2,}, + {0x3fda3da320000000,0x3e45e87784a7a334,}, + {0x3fda484090000000,0x3e0cb761457f94d7,}, + {0x3fda52dc30000000,0x3e31bbe419055290,}, + {0x3fda5d7610000000,0x3e3894b0dc5078a4,}, + {0x3fda680e30000000,0x3e3a75040e41c95d,}, + {0x3fda72a490000000,0x3e39af67a85a9dac,}, + {0x3fda7d3930000000,0x3e38953ec56cc58e,}, + {0x3fda87cc10000000,0x3e3976c664788bc2,}, + {0x3fda925d30000000,0x3e3ea3162ae9daa1,}, + {0x3fda9cec90000000,0x3e453410931a90a0,}, + {0x3fdaa77a30000000,0x3e4f895b466a4bc0,}, + {0x3fdab20620000000,0x3e3eee827ea67ed8,}, + {0x3fdabc9050000000,0x3e288c1d8959f9db,}, + {0x3fdac718c0000000,0x3e22c587206058f6,}, + {0x3fdad19f70000000,0x3e388ce839430025,}, + {0x3fdadc2460000000,0x3e4e05d1fe55c928,}, + {0x3fdae6a7a0000000,0x3e4b127f5c97be1f,}, + {0x3fdaf12930000000,0x3e223bc358899c22,}, + {0x3fdafba8f0000000,0x3e4b9d0c17142058,}, + {0x3fdb062710000000,0x3e05e2836ac9cdf8,}, + {0x3fdb10a360000000,0x3e46f30e14be1c9b,}, + {0x3fdb1b1e00000000,0x3e4d7bf8b6d223cb,}, + {0x3fdb2596f0000000,0x3e461895a501fd65,}, + {0x3fdb300e30000000,0x3e0e805468353afa,}, + {0x3fdb3a83b0000000,0x3e1046d9ef494ba4,}, + {0x3fdb44f770000000,0x3e47991ec5197ddb,}, + {0x3fdb4f6990000000,0x3e1db25847bf25fc,}, + {0x3fdb59d9f0000000,0x3e2df53e131573a7,}, + {0x3fdb6448a0000000,0x3e202a4174d6b539,}, + {0x3fdb6eb590000000,0x3e4a79e6bb3a921a,}, + {0x3fdb7920e0000000,0x3e37cd424d0a0405,}, + {0x3fdb838a70000000,0x3e496b83dfbcd407,}, + {0x3fdb8df260000000,0x3e208b24e9bc35a4,}, + {0x3fdb985890000000,0x3e3a4c43ed663ec5,}, + {0x3fdba2bd10000000,0x3e458eb59a875bd1,}, + {0x3fdbad1fe0000000,0x3e4e7522cae4e7a8,}, + {0x3fdbb78110000000,0x3e31e2ff4916e37b,}, + {0x3fdbc1e080000000,0x3e461b5a1484f438,}, + {0x3fdbcc3e50000000,0x3e2c26e0c18719f9,}, + {0x3fdbd69a60000000,0x3e4cd3188e2d454f,}, + {0x3fdbe0f4d0000000,0x3e488d729c1b5656,}, + {0x3fdbeb4d90000000,0x3e4b4e36f7ef0c3a,}, + {0x3fdbf5a4b0000000,0x3e28a93f186abf5e,}, + {0x3fdbfffa10000000,0x3e4a362108997313,}, + {0x3fdc0a4dd0000000,0x3e488588f583115a,}, + {0x3fdc149ff0000000,0x3e115f026acd0d1c,}, + {0x3fdc1ef050000000,0x3e483bfab111dd60,}, + {0x3fdc293f10000000,0x3e4bc826f7d61fa7,}, + {0x3fdc338c30000000,0x3e3bc45f0908bedd,}, + {0x3fdc3dd7a0000000,0x3e3f36b535cecf05,}, + {0x3fdc482170000000,0x3e102355a55c73b5,}, + {0x3fdc526990000000,0x3e28b67b583cc2b0,}, + {0x3fdc5cb000000000,0x3e4d26b2e24f2e1f,}, + {0x3fdc66f4e0000000,0x3e2ffb7fbf3eb5c7,}, + {0x3fdc713810000000,0x3e2f13727005956e,}, + {0x3fdc7b7990000000,0x3e4d86dd5f03ad63,}, + {0x3fdc85b980000000,0x3e34a529be072cee,}, + {0x3fdc8ff7c0000000,0x3e3e6a6886b09760,}, + {0x3fdc9a3460000000,0x3e3a76d70eb9f6a6,}, + {0x3fdca46f60000000,0x3e25c5a734221efb,}, + {0x3fdcaea8b0000000,0x3e48e2ddaf433fd0,}, + {0x3fdcb8e070000000,0x3e3135eb27f5bbc3,}, + {0x3fdcc31680000000,0x3e45a45ffdf50c5a,}, + {0x3fdccd4b00000000,0x3e0094bde60ae67f,}, + {0x3fdcd77dd0000000,0x3e37a6d1cc4c569c,}, + {0x3fdce1af00000000,0x3e470be7d6f6fa58,}, + {0x3fdcebdea0000000,0x3e1ddbd6a0e56a57,}, + {0x3fdcf60c90000000,0x3e42ea55b307b6e6,}, + {0x3fdd0038f0000000,0x3e2680b92e78aac6,}, + {0x3fdd0a63a0000000,0x3e4ce43cc84ab338,}, + {0x3fdd148cc0000000,0x3e49bd3bf5cbfb55,}, + {0x3fdd1eb440000000,0x3e4d316992c4c729,}, + {0x3fdd28da30000000,0x3e308d0d3e19f1d9,}, + {0x3fdd32fe70000000,0x3e4c01d7aac3bd92,}, + {0x3fdd3d2120000000,0x3e49682525231cfb,}, + {0x3fdd474240000000,0x3e07dbbab15292e5,}, + {0x3fdd5161b0000000,0x3e45466c558b07c0,}, + {0x3fdd5b7f90000000,0x3e45c58d07961060,}, + {0x3fdd659be0000000,0x3e1fefc5e219da29,}, + {0x3fdd6fb690000000,0x3dfe41fa87233ab1,}, + {0x3fdd79cfa0000000,0x3e3b4770c6312796,}, + {0x3fdd83e720000000,0x3e3628bcf941456f,}, + {0x3fdd8dfd00000000,0x3e4a44f48195459e,}, + {0x3fdd981150000000,0x3e4c35f36c69e60c,}, + {0x3fdda22410000000,0x3e41e75b1daf67e6,}, + {0x3fddac3530000000,0x3e4c58b2a8461cd3,}, + {0x3fddb644c0000000,0x3e4c89089d53d402,}, + {0x3fddc052c0000000,0x3e4376f357fe3eb6,}, + {0x3fddca5f30000000,0x3e11048a474f0e7d,}, + {0x3fddd46a00000000,0x3e33071282fb989b,}, + {0x3fddde7340000000,0x3e353a157dd89503,}, + {0x3fdde87af0000000,0x3e29a738d40335d1,}, + {0x3fddf28100000000,0x3e4de61558b33db4,}, + {0x3fddfc8590000000,0x3e420dab6a80f09d,}, + {0x3fde068890000000,0x3e1edf2c045bb6ee,}, + {0x3fde1089f0000000,0x3e444ba2d07d7ac0,}, + {0x3fde1a89d0000000,0x3e215d33e4d79235,}, + {0x3fde248810000000,0x3e44f8d84c397b1f,}, + {0x3fde2e84d0000000,0x3e2ca7105bacd9da,}, + {0x3fde387ff0000000,0x3e4be31aeb8b7a00,}, + {0x3fde427990000000,0x3e441d72e9fe6bd6,}, + {0x3fde4c71a0000000,0x3e40d0ee08599e49,}, + {0x3fde566820000000,0x3e42f53a5b39407e,}, + {0x3fde605d10000000,0x3e4b81925ddd0af6,}, + {0x3fde6a5080000000,0x3e36d97a741a38d4,}, + {0x3fde744260000000,0x3e1d68787e37da37,}, + {0x3fde7e32b0000000,0x3e24e1a4f2cbbf49,}, + {0x3fde882170000000,0x3e41043aa361ead0,}, + {0x3fde920eb0000000,0x3e300affe4a85876,}, + {0x3fde9bfa60000000,0x3e366187d591bafc,}, + {0x3fdea5e480000000,0x3e4b7a1fa756d24e,}, + {0x3fdeafcd20000000,0x3e49d53ae24ea31d,}, + {0x3fdeb9b440000000,0x3e2cd530ef994fa0,}, + {0x3fdec399d0000000,0x3e22346600bae773,}, + {0x3fdecd7dd0000000,0x3e42cef7ecd2d226,}, + {0x3fded76050000000,0x3e42eccc76a13c00,}, + {0x3fdee14150000000,0x3e2760303b801fbf,}, + {0x3fdeeb20c0000000,0x3e390377d0d61b8f,}, + {0x3fdef4feb0000000,0x3e2f69c6f273ebe1,}, + {0x3fdefedb10000000,0x3e48d25410034a6b,}, + {0x3fdf08b600000000,0x3de6469db755bac5,}, + {0x3fdf128f50000000,0x3e4f5e0dd966b907,}, + {0x3fdf1c6730000000,0x3e46d008b7ed20f9,}, + {0x3fdf263d90000000,0x3e2e75ddbac77437,}, + {0x3fdf301260000000,0x3e42b45879973ccf,}, + {0x3fdf39e5b0000000,0x3e49023cb79a00e2,}, + {0x3fdf43b780000000,0x3e4b7447ae17077f,}, + {0x3fdf4d87d0000000,0x3e4af72fcbdd6519,}, + {0x3fdf5756a0000000,0x3e48773eac0d18ac,}, + {0x3fdf6123f0000000,0x3e44e05158c28ad8,}, + {0x3fdf6aefc0000000,0x3e411dd88d8f06ea,}, + {0x3fdf74ba10000000,0x3e3c35b1f37cb920,}, + {0x3fdf7e82e0000000,0x3e3983d704d3b1da,}, + {0x3fdf884a30000000,0x3e3bfa7b08b18ae5,}, + {0x3fdf921000000000,0x3e42b69115ae9ac3,}, + {0x3fdf9bd450000000,0x3e4bd73d476715aa,}, + {0x3fdfa59730000000,0x3e34905ccd40b814,}, + {0x3fdfaf5880000000,0x3e4ef1e63db35f68,}, + {0x3fdfb91860000000,0x3e4abc7c551aaa8d,}, + {0x3fdfc2d6c0000000,0x3e4e8f9e3427c793,}, + {0x3fdfcc93b0000000,0x3e36a51f430ed6da,}, + {0x3fdfd64f20000000,0x3e0ec2ae39493d4f,}, + {0x3fdfe00910000000,0x3e1a170803d6232d,}, + {0x3fdfe9c180000000,0x3e403cb9fe278f5b,}, + {0x3fdff37880000000,0x3e337eaa44172cc6,}, + {0x3fdffd2e00000000,0x3e40afe930ab2fa0,}, + {0x3fe0037100000000,0x3e52f9a2567f6d73,}, + {0x3fe0084a50000000,0x3e34db9c2f4765ea,}, + {0x3fe00d22d0000000,0x3e5f81c216ee032e,}, + {0x3fe011fab0000000,0x3e225ff8a1810dd4,}, + {0x3fe016d1c0000000,0x3e4c0e6bfa0062b0,}, + {0x3fe01ba820000000,0x3e29265a3857e986,}, + {0x3fe0207dc0000000,0x3e20af801b1c9b6d,}, + {0x3fe02552a0000000,0x3e469743fb1a71a5,}, + {0x3fe02a26c0000000,0x3e5f36abda6df12c,}, + {0x3fe02efa30000000,0x3e5e47a53729b1be,}, + {0x3fe033ccf0000000,0x3e41dde58fcca5aa,}, + {0x3fe0389ee0000000,0x3e5f9cc676785571,}, + {0x3fe03d7030000000,0x3e2608fc07c4905f,}, + {0x3fe04240b0000000,0x3e52cbca9842e53b,}, + {0x3fe0471080000000,0x3e502c61fe5def03,}, + {0x3fe04bdf90000000,0x3e5b524da4cbf982,}, + {0x3fe050adf0000000,0x3e54acc34ac51b80,}, + {0x3fe0557b90000000,0x3e5caac69b5aab72,}, + {0x3fe05a4880000000,0x3e53bb294b841755,}, + {0x3fe05f14b0000000,0x3e5a4c8b381535b9,}, + {0x3fe063e030000000,0x3e50cd5a839e2435,}, + {0x3fe068aaf0000000,0x3e57abd3b434c77f,}, + {0x3fe06d7500000000,0x3e4eac03a250025a,}, + {0x3fe0723e50000000,0x3e5839be809caf2c,}, + {0x3fe07706f0000000,0x3e52c4b2251488d6,}, + {0x3fe07bced0000000,0x3e5f6453fadeed77,}, + {0x3fe0809600000000,0x3e5e85ea3573b814,}, + {0x3fe0855c80000000,0x3e50968a1cb82c13,}, + {0x3fe08a2240000000,0x3e5603182a2e0e62,}, + {0x3fe08ee750000000,0x3e4e70904c19fd45,}, + {0x3fe093aba0000000,0x3e5ca29d444623d1,}, + {0x3fe0986f40000000,0x3e5eae6a41723fb5,}, + {0x3fe09d3230000000,0x3e55c7d17faa3c74,}, + {0x3fe0a1f470000000,0x3e22d6291a523b58,}, + {0x3fe0a6b5f0000000,0x3e334c1cbe7e31f7,}, + {0x3fe0ab76b0000000,0x3e5d9c29a380a4db,}, + {0x3fe0b036d0000000,0x3e4a431d2ba19872,}, + {0x3fe0b4f630000000,0x3e53ce6851edef66,}, + {0x3fe0b9b4e0000000,0x3e520db97409a704,}, + {0x3fe0be72e0000000,0x3e4094aa0ada625f,}, + {0x3fe0c33020000000,0x3e56eede98a87caf,}, + {0x3fe0c7ecb0000000,0x3e5e65ca65ac5853,}, + {0x3fe0cca890000000,0x3e5f195d65cfd8ff,}, + {0x3fe0d163c0000000,0x3e5973ad6fc108cb,}, + {0x3fe0d61e40000000,0x3e4bbd42a6c1e34f,}, + {0x3fe0dad800000000,0x3e5cc3f0f58b15c0,}, + {0x3fe0df9120000000,0x3e3a3495af219f5d,}, + {0x3fe0e44980000000,0x3e4747322fdbab97,}, + {0x3fe0e90130000000,0x3e48e0ef874cee91,}, + {0x3fe0edb830000000,0x3e42b97d77d2e557,}, + {0x3fe0f26e80000000,0x3e2689e762dd5036,}, + {0x3fe0f72410000000,0x3e593692fa9d4222,}, + {0x3fe0fbd900000000,0x3e49ea66c3062a6b,}, + {0x3fe1008d30000000,0x3e5e75628c3c2322,}, + {0x3fe10540c0000000,0x3e4c3e6de2c6217f,}, + {0x3fe109f390000000,0x3e5c5a992dfbc7d9,}, + {0x3fe10ea5c0000000,0x3e431e8840ba92aa,}, + {0x3fe1135730000000,0x3e5624c50307c2f2,}, + {0x3fe1180800000000,0x3e2413dc3b37cfe2,}, + {0x3fe11cb810000000,0x3e4e1f33e102387b,}, + {0x3fe1216770000000,0x3e5c33252d920862,}, + {0x3fe1261630000000,0x3e44a7e9e9263dfd,}, + {0x3fe12ac430000000,0x3e59d8b3dcafad3d,}, + {0x3fe12f7190000000,0x3e464fbef14c048c,}, + {0x3fe1341e30000000,0x3e5ea7c87115404f,}, + {0x3fe138ca30000000,0x3e54be929eb7fa28,}, + {0x3fe13d7580000000,0x3e4ba46a49175c4d,}, + {0x3fe1422020000000,0x3e4490f513ca5e3b,}, + {0x3fe146ca10000000,0x3e450e01a8e4183e,}, + {0x3fe14b7350000000,0x3e4de673444e0f20,}, + {0x3fe1501be0000000,0x3e57f26a431bae2c,}, + {0x3fe154c3d0000000,0x3e37a6af4d4c799d,}, + {0x3fe1596b00000000,0x3e593deb547210a0,}, + {0x3fe15e1190000000,0x3e5253e9c762306f,}, + {0x3fe162b770000000,0x3e51903c45e2d76c,}, + {0x3fe1675ca0000000,0x3e57574c1c073990,}, + {0x3fe16c0130000000,0x3e30355b86884d96,}, + {0x3fe170a500000000,0x3e58166e939eea21,}, + {0x3fe1754830000000,0x3e53d679ad48ed97,}, + {0x3fe179eab0000000,0x3e57b133417f8c1d,}, + {0x3fe17e8c90000000,0x3e3028ac4f63209c,}, + {0x3fe1832db0000000,0x3e5944c5b1b15f85,}, + {0x3fe187ce30000000,0x3e57c43c8b2ad402,}, + {0x3fe18c6e00000000,0x3e5feb9e0c176514,}, + {0x3fe1910d30000000,0x3e521dcdb4d40a53,}, + {0x3fe195abb0000000,0x3e4d7b086620fc77,}, + {0x3fe19a4980000000,0x3e562d4f7a8568cd,}, + {0x3fe19ee6b0000000,0x3e419f25bb3172f7,}, + {0x3fe1a38330000000,0x3e3c1a1c97c0ff67,}, + {0x3fe1a81f00000000,0x3e51343aacf2924d,}, + {0x3fe1acba30000000,0x3e3eea45d0d94886,}, + {0x3fe1b154b0000000,0x3e45f68a7bbfb853,}, + {0x3fe1b5ee80000000,0x3e5b57e5a4ed751b,}, + {0x3fe1ba87b0000000,0x3e5931d8357200bf,}, + {0x3fe1bf2040000000,0x3e33a96212f94c19,}, + {0x3fe1c3b810000000,0x3e5ee278497929f2,}, + {0x3fe1c84f50000000,0x3e3dec7dce977d34,}, + {0x3fe1cce5d0000000,0x3e5f150c4499e10a,}, + {0x3fe1d17bc0000000,0x3e38434d9b83fc4c,}, + {0x3fe1d610f0000000,0x3e5ccee006109d59,}, + {0x3fe1daa590000000,0x3e2d7b9f344ec608,}, + {0x3fe1df3970000000,0x3e5b12a77d2aada3,}, + {0x3fe1e3ccc0000000,0x3e2ac3503771731a,}, + {0x3fe1e85f50000000,0x3e5ce081a07bd8b3,}, + {0x3fe1ecf150000000,0x3e401516bb4c2fd5,}, + {0x3fe1f182a0000000,0x3e34d7ed83600b92,}, + {0x3fe1f61340000000,0x3e54c21cf27263be,}, + {0x3fe1faa340000000,0x3e570e12981817b9,}, + {0x3fe1ff32a0000000,0x3e48f1ac57d3ab13,}, + {0x3fe203c150000000,0x3e556138f3b1683a,}, + {0x3fe2084f60000000,0x3e5225e3b7fc6cc4,}, + {0x3fe20cdcd0000000,0x3e292ab6d93503d1,}, + {0x3fe2116990000000,0x3e417bd4e0a79c74,}, + {0x3fe215f5b0000000,0x3e2a6e7292cb435f,}, + {0x3fe21a8120000000,0x3e53330a3a97ddb1,}, + {0x3fe21f0bf0000000,0x3e58cb7dd7c3b61e,}, + {0x3fe2239620000000,0x3e5474e0e49e86ce,}, + {0x3fe2281fb0000000,0x3e3a330cfa7f2644,}, + {0x3fe22ca890000000,0x3e4ee119f91b4ccf,}, + {0x3fe23130d0000000,0x3e4efafd0a0b78da,}, + {0x3fe235b870000000,0x3e3c42c293d7df37,}, + {0x3fe23a3f60000000,0x3e568714a605824b,}, + {0x3fe23ec5b0000000,0x3e5e3d7464eddbd2,}, + {0x3fe2434b60000000,0x3e5e907267c4288e,}, + {0x3fe247d070000000,0x3e57dc89f432c1dc,}, + {0x3fe24c54e0000000,0x3e44fc1e4b462ede,}, + {0x3fe250d8a0000000,0x3e56d12f0357edf7,}, + {0x3fe2555bc0000000,0x3e5d31ef96780876,}, + {0x3fe259de40000000,0x3e5dfc300009497c,}, + {0x3fe25e6020000000,0x3e598ba88edc596b,}, + {0x3fe262e160000000,0x3e503bead568dec6,}, + {0x3fe2676200000000,0x3e23430dfcd2ad51,}, + {0x3fe26be1f0000000,0x3e506c51a88d9359,}, + {0x3fe2706140000000,0x3e5aa2d8703f02c5,}, + {0x3fe274e000000000,0x3e166ed9129a7046,}, + {0x3fe2795e10000000,0x3e344d88d75bc1fa,}, + {0x3fe27ddb80000000,0x3e380b85397dc643,}, + {0x3fe2825850000000,0x3e323fbe9771fdcb,}, + {0x3fe286d480000000,0x3e114ebf7cacbfda,}, + {0x3fe28b5000000000,0x3e5bec0f055e04fd,}, + {0x3fe28fcaf0000000,0x3e556f6baac5859d,}, + {0x3fe2944540000000,0x3e4bf1dde8c44cfe,}, + {0x3fe298bef0000000,0x3e378980cfb4e3bc,}, + {0x3fe29d37f0000000,0x3e5d85611590b9ae,}, + {0x3fe2a1b060000000,0x3e553b6db4f0c7b1,}, + {0x3fe2a62830000000,0x3e4abbb9644cd665,}, + {0x3fe2aa9f60000000,0x3e39177d1aaee570,}, + {0x3fe2af15f0000000,0x3df320568e583229,}, + {0x3fe2b38bd0000000,0x3e5bcaa99795ab1c,}, + {0x3fe2b80120000000,0x3e5919198154ffca,}, + {0x3fe2bc75d0000000,0x3e58906d868bf438,}, + {0x3fe2c0e9e0000000,0x3e5a891d1772f538,}, + {0x3fe2c55d50000000,0x3e5f5b7ab9fb95fa,}, + {0x3fe2c9d030000000,0x3e3d7ed0795e4134,}, + {0x3fe2ce4260000000,0x3e52edd233718241,}, + {0x3fe2d2b400000000,0x3e22edc9dabba74e,}, + {0x3fe2d724f0000000,0x3e560728df973831,}, + {0x3fe2db9550000000,0x3e4c83788b193ef0,}, + {0x3fe2e00510000000,0x3e46c9d44543558e,}, + {0x3fe2e47430000000,0x3e4b9009a1015086,}, + {0x3fe2e8e2b0000000,0x3e55c23a61385992,}, + {0x3fe2ed50a0000000,0x3e2d54a59a914633,}, + {0x3fe2f1bde0000000,0x3e57d7f985da7866,}, + {0x3fe2f62a90000000,0x3e52a12a8c5b1a1a,}, + {0x3fe2fa96a0000000,0x3e545cc582c7f772,}, + {0x3fe2ff0210000000,0x3e5d6144415df845,}, + {0x3fe3036cf0000000,0x3e4c09f9a0e863f2,}, + {0x3fe307d730000000,0x3e3a7885f0fdac85,}, + {0x3fe30c40d0000000,0x3e3e0b03a21ffae8,}, + {0x3fe310a9d0000000,0x3e5108c624522a46,}, + {0x3fe3151240000000,0x3e2c2fc5ebc6904d,}, + {0x3fe3197a00000000,0x3e5f4ffcd43ac692,}, + {0x3fe31de140000000,0x3e32f14cbaea5aab,}, + {0x3fe32247d0000000,0x3e5420594c70f8df,}, + {0x3fe326add0000000,0x3e4ba292f323af21,}, + {0x3fe32b1330000000,0x3e52243ae2640aad,}, + {0x3fe32f7800000000,0x3e16e21a68bc9f99,}, + {0x3fe333dc20000000,0x3e5c03ceec47e2dd,}, + {0x3fe3383fc0000000,0x3e21cf879d0de4df,}, + {0x3fe33ca2b0000000,0x3e546513299035d3,}, + {0x3fe3410510000000,0x3e52d99e3b0d6605,}, + {0x3fe34566d0000000,0x3e5debd8281f4e00,}, + {0x3fe349c800000000,0x3e55efe456d381d9,}, + {0x3fe34e2890000000,0x3e5b39c3a62dd726,}, + {0x3fe3528890000000,0x3e4c3aa90214444e,}, + {0x3fe356e7f0000000,0x3e4ddca5e1e218e9,}, + {0x3fe35b46b0000000,0x3e5e0058b0e00fc5,}, + {0x3fe35fa4e0000000,0x3e5ba6dd40049f52,}, + {0x3fe3640280000000,0x3e406a6be8d514bf,}, + {0x3fe3685f80000000,0x3e2ff4b06ced129e,}, + {0x3fe36cbbe0000000,0x3e4eac1d8e7d5d94,}, + {0x3fe37117b0000000,0x3e451d1ed7177409,}, + {0x3fe37572e0000000,0x3e55fae565dbc00e,}, + {0x3fe379cd80000000,0x3e51edbc550dcade,}, + {0x3fe37e2780000000,0x3e5eb99e1deb85bb,}, + {0x3fe38280f0000000,0x3e5cb0f2fd7f5216,}, + {0x3fe386d9d0000000,0x3e484c0336bbd030,}, + {0x3fe38b3210000000,0x3e4ad5de37c719df,}, + {0x3fe38f89c0000000,0x3e0a37e64c9d229c,}, + {0x3fe393e0d0000000,0x3e3ab150cd4e2213,}, + {0x3fe3983740000000,0x3e5f4c6f26560f01,}, + {0x3fe39c8d30000000,0x3e46075fb0a854ac,}, + {0x3fe3a0e280000000,0x3e444729daec992e,}, + {0x3fe3a53730000000,0x3e5cfd7bf3193844,}, + {0x3fe3a98b60000000,0x3e2f150b8dab41ae,}, + {0x3fe3addee0000000,0x3e5f2420feba5d29,}, + {0x3fe3b231e0000000,0x3e4e25ea9cbbb581,}, + {0x3fe3b68440000000,0x3e53fff8455f1dbe,}, + {0x3fe3bad610000000,0x3e4c77c6157c2a58,}, + {0x3fe3bf2740000000,0x3e5e174e1966a83c,}, + {0x3fe3c377f0000000,0x3e2f158a8e809392,}, + {0x3fe3c7c7f0000000,0x3e5fee640b905fc9,}, + {0x3fe3cc1770000000,0x3e528a9d26e4126c,}, + {0x3fe3d06650000000,0x3e5c07731e29fb8d,}, + {0x3fe3d4b4a0000000,0x3e5cb4dc175350e3,}, + {0x3fe3d90260000000,0x3e54e2adf548084c,}, + {0x3fe3dd4f90000000,0x3e338279a4fe0c4d,}, + {0x3fe3e19c20000000,0x3e49fc86081b245a,}, + {0x3fe3e5e820000000,0x3e4b16228ec7b9d9,}, + {0x3fe3ea3390000000,0x3e3b597adc1ecdd3,}, + {0x3fe3ee7e60000000,0x3e592f60e9fc5644,}, + {0x3fe3f2c8b0000000,0x3e3394b66e86f06c,}, + {0x3fe3f71260000000,0x3e448d75798fbf0c,}, + {0x3fe3fb5b80000000,0x3e4345bd096d3a75,}, + {0x3fe3ffa410000000,0x3e2a427c115163eb,}, + {0x3fe403ec00000000,0x3e5785a4ac443ab1,}, + {0x3fe4083370000000,0x3e3aa555cdc6ccc5,}, + {0x3fe40c7a40000000,0x3e5101b9d2453c8b,}, + {0x3fe410c080000000,0x3e56dd0a5e467424,}, + {0x3fe4150630000000,0x3e58896058b5f14a,}, + {0x3fe4194b50000000,0x3e5654b5bf4618ba,}, + {0x3fe41d8fe0000000,0x3e508ce55cc8c97a,}, + {0x3fe421d3e0000000,0x3e3dfeab6747b019,}, + {0x3fe4261740000000,0x3e5b7aa2cd4eecaa,}, + {0x3fe42a5a20000000,0x3e4996959a2653b4,}, + {0x3fe42e9c60000000,0x3e5bbf017e595f72,}, + {0x3fe432de20000000,0x3e41460d4c742f1b,}, + {0x3fe4371f40000000,0x3e53c47b3a1729ce,}, + {0x3fe43b5fd0000000,0x3e5d70616ffc51bc,}, + {0x3fe43f9fe0000000,0x3e37ce733bd393dd,}, + {0x3fe443df50000000,0x3e4b35e47ead63d6,}, + {0x3fe4481e30000000,0x3e54b3081b020f93,}, + {0x3fe44c5c80000000,0x3e5b88663d9726fe,}, + {0x3fe4509a50000000,0x3e233bb0a503f8a1,}, + {0x3fe454d780000000,0x3e4339055f65a65e,}, + {0x3fe4591420000000,0x3e5173b8d0823d03,}, + {0x3fe45d5030000000,0x3e5a3926faecba57,}, + {0x3fe4618bc0000000,0x3e30e2f613e85bda,}, + {0x3fe465c6b0000000,0x3e4f7c9d4da2869e,}, + {0x3fe46a0110000000,0x3e5d158e8aa32018,}, + {0x3fe46e3af0000000,0x3e491426b9158eb6,}, + {0x3fe4727430000000,0x3e5e67555a635b3c,}, + {0x3fe476acf0000000,0x3e52f8aee39362bb,}, + {0x3fe47ae520000000,0x3e4512b9119b798a,}, + {0x3fe47f1cc0000000,0x3e3591f46f20c6fe,}, + {0x3fe48353d0000000,0x3e2ea88df73d5e8c,}, + {0x3fe4878a50000000,0x3e3897f7d388782b,}, + {0x3fe48bc040000000,0x3e49440f60ac452e,}, + {0x3fe48ff5a0000000,0x3e5793d763585815,}, + {0x3fe4942a80000000,0x3e3d17e03bda18a9,}, + {0x3fe4985ec0000000,0x3e5c02d752b09166,}, + {0x3fe49c9280000000,0x3e5614c57be74670,}, + {0x3fe4a0c5b0000000,0x3e55c5f595410491,}, + {0x3fe4a4f850000000,0x3e5b607d76044f7f,}, + {0x3fe4a92a70000000,0x3e3cb95745a141b7,}, + {0x3fe4ad5bf0000000,0x3e59795a45db4e43,}, + {0x3fe4b18cf0000000,0x3e528b496c3f24d2,}, + {0x3fe4b5bd60000000,0x3e52adc4e71bc2fd,}, + {0x3fe4b9ed40000000,0x3e5a2a5171c7b794,}, + {0x3fe4be1ca0000000,0x3e4294addf0da971,}, + {0x3fe4c24b70000000,0x3df5c81ea7bc61df,}, + {0x3fe4c679a0000000,0x3e5f99dc7362d1da,}, + {0x3fe4caa760000000,0x3e3d6e723cccef04,}, + {0x3fe4ced480000000,0x3e57e555e776427b,}, + {0x3fe4d30120000000,0x3e517fe10884ce85,}, + {0x3fe4d72d30000000,0x3e5473fa008e6a6a,}, + {0x3fe4db58c0000000,0x3e10a406e735bf8e,}, + {0x3fe4df83b0000000,0x3e578b3790951160,}, + {0x3fe4e3ae20000000,0x3e583f46539ce9d3,}, + {0x3fe4e7d810000000,0x3e2b75bb09cb0985,}, + {0x3fe4ec0160000000,0x3e5961b92ed1a632,}, + {0x3fe4f02a30000000,0x3e5a605e0c2fa29d,}, + {0x3fe4f45280000000,0x3e3aca70c881f3a1,}, + {0x3fe4f87a30000000,0x3e5ea04dd10b9aba,}, + {0x3fe4fca170000000,0x3e238988fc015daf,}, + {0x3fe500c810000000,0x3e526ce868b943e0,}, + {0x3fe504ee30000000,0x3e4db5f436311a10,}, + {0x3fe50913c0000000,0x3e5802d0d6979675,}, + {0x3fe50d38d0000000,0x3e4c5776f65f9459,}, + {0x3fe5115d50000000,0x3e519ced37390f15,}, + {0x3fe5158150000000,0x3e24ebecadf8f962,}, + {0x3fe519a4c0000000,0x3e174688ccd99094,}, + {0x3fe51dc7a0000000,0x3e4cd11d1765a7c8,}, + {0x3fe521ea00000000,0x3e4381691272fa7d,}, + {0x3fe5260bd0000000,0x3e53c38411d90759,}, + {0x3fe52a2d20000000,0x3e496f16abb9df23,}, + {0x3fe52e4de0000000,0x3e54e33d3782e3be,}, + {0x3fe5326e20000000,0x3e4919e2b21f9b2b,}, + {0x3fe5368dd0000000,0x3e53fae42adbcb31,}, + {0x3fe53aad00000000,0x3e46e66df2aa3750,}, + {0x3fe53ecba0000000,0x3e533beffafa06bf,}, + {0x3fe542e9c0000000,0x3e4735f4bc938d5b,}, + {0x3fe5470750000000,0x3e54d62657ac7ada,}, + {0x3fe54b2460000000,0x3e4e66525ea4550a,}, + {0x3fe54f40e0000000,0x3e5af79d4f08de39,}, + {0x3fe5535ce0000000,0x3e5869025009d6ee,}, + {0x3fe5577860000000,0x3e3f32f422f7a694,}, + {0x3fe55b9350000000,0x3e42d02f34f20cbd,}, + {0x3fe55fadb0000000,0x3e5d80417f2cf12b,}, + {0x3fe563c7a0000000,0x3e31693e5c4cd077,}, + {0x3fe567e0f0000000,0x3e5e3b3c364e50e7,}, + {0x3fe56bf9d0000000,0x3e46cfce65047188,}, + {0x3fe5701220000000,0x3e484a2be0c82304,}, + {0x3fe57429f0000000,0x3e06ee6e2829c729,}, + {0x3fe5784130000000,0x3e42c720c0fc44da,}, + {0x3fe57c57f0000000,0x3e39b78c842d58b9,}, + {0x3fe5806e20000000,0x3e581ac7dad381dd,}, + {0x3fe58483d0000000,0x3e5eae80881fb81e,}, + {0x3fe5889900000000,0x3e5a6d3502f3a494,}, + {0x3fe58cadb0000000,0x3e4735e624c24bc9,}, + {0x3fe590c1d0000000,0x3e527bae77d36991,}, + {0x3fe594d570000000,0x3e4ea681f8a32030,}, + {0x3fe598e890000000,0x3e232b53edc6ff21,}, + {0x3fe59cfb20000000,0x3e47eba1f7dd1adf,}, + {0x3fe5a10d30000000,0x3e4890014c123e1d,}, + {0x3fe5a51ec0000000,0x3e2cfb5f3b8b961e,}, + {0x3fe5a92fc0000000,0x3e523f6b74fb6c88,}, + {0x3fe5ad4040000000,0x3e586b3e59f65355,}, + {0x3fe5b15040000000,0x3e56660a0534e352,}, + {0x3fe5b55fc0000000,0x3e48e5b4ac1a36df,}, + {0x3fe5b96eb0000000,0x3e5ad4a1a94fccbb,}, + {0x3fe5bd7d30000000,0x3e1ce38e637f1b4e,}, + {0x3fe5c18b20000000,0x3e1a25f8b51d3e1a,}, + {0x3fe5c59880000000,0x3e5a93bbbb5a05d4,}, + {0x3fe5c9a570000000,0x3e49c9b494286fcb,}, + {0x3fe5cdb1d0000000,0x3e58d82ec919edc8,}, + {0x3fe5d1bdb0000000,0x3e5eb01394a11b1c,}, + {0x3fe5d5c910000000,0x3e5eaec9e03aad37,}, + {0x3fe5d9d3f0000000,0x3e591679c3890827,}, + {0x3fe5ddde50000000,0x3e4c52648ddcfa38,}, + {0x3fe5e1e820000000,0x3e5e28e97033c04a,}, + {0x3fe5e5f180000000,0x3e42aef89e4cc88f,}, + {0x3fe5e9fa50000000,0x3e4fed5e145ec1f3,}, + {0x3fe5ee02a0000000,0x3e52482ceae1ac13,}, + {0x3fe5f20a70000000,0x3e508d886a80e91d,}, + {0x3fe5f611c0000000,0x3e4610767d006e1e,}, + {0x3fe5fa1890000000,0x3e1f9a664f921558,}, + {0x3fe5fe1ed0000000,0x3e55a312311aba4f,}, + {0x3fe60224a0000000,0x3e3916b95e43945f,}, + {0x3fe60629e0000000,0x3e542291fae3d488,}, + {0x3fe60a2ea0000000,0x3e5f7abbb7cfc555,}, + {0x3fe60e32f0000000,0x3e411e236329f225,}, + {0x3fe61236b0000000,0x3e4f40c33c7ff019,}, + {0x3fe61639f0000000,0x3e54ef60d2ea1fa4,}, + {0x3fe61a3cb0000000,0x3e58bcac4ff28318,}, + {0x3fe61e3ef0000000,0x3e5b48c8cd2f246c,}, + {0x3fe62240b0000000,0x3e5cd422c6168b3a,}, + {0x3fe62641f0000000,0x3e5d9f0e85e1bf21,}, + {0x3fe62a42b0000000,0x3e5de9c833a6ab8a,}, + {0x3fe62e42f0000000,0x3e5df473de6af279,}, +}; + +extern "C" exp_data exp_lookup[1025] = { + {0x3ff0000000000000,0x0}, + {0x3ff002c600000000,0x3e578ba33b141b48}, + {0x3ff0058c80000000,0x3e5b687027a87fc6}, + {0x3ff0085380000000,0x3e47d77c18ed49fd}, + {0x3ff00b1af0000000,0x3e64b5797dac2535}, + {0x3ff00de2e0000000,0x3e6a1dc1e9ebf954}, + {0x3ff010ab50000000,0x3e66597a22e0e833}, + {0x3ff0137440000000,0x3e5326d6d3b52545}, + {0x3ff0163da0000000,0x3e63f6666adb094d}, + {0x3ff0190780000000,0x3e65ad433ddfee20}, + {0x3ff01bd1e0000000,0x3e5dc5c2d0579d8a}, + {0x3ff01e9cb0000000,0x3e6fc227dd8fb82b}, + {0x3ff0216810000000,0x3e50ec0a036a0678}, + {0x3ff02433e0000000,0x3e5252dd52ceb55f}, + {0x3ff0270030000000,0x3e303b10def7d10b}, + {0x3ff029ccf0000000,0x3e633ae4140b265e}, + {0x3ff02c9a30000000,0x3e6cef00c1dcdef9}, + {0x3ff02f67f0000000,0x3e6f4ecbcb91c93c}, + {0x3ff0323630000000,0x3e6a85604eff546b}, + {0x3ff03504f0000000,0x3e5d7bc1c5bc2ee9}, + {0x3ff037d420000000,0x3e6c237798156812}, + {0x3ff03aa3e0000000,0x3e370aafd8395b10}, + {0x3ff03d7410000000,0x3e3915a8a6df003a}, + {0x3ff04044b0000000,0x3e6d12d56ccee1d7}, + {0x3ff04315e0000000,0x3e60dcff097ae71f}, + {0x3ff045e780000000,0x3e6eac817226b791}, + {0x3ff048b9b0000000,0x3e4ab2cec0487355}, + {0x3ff04b8c50000000,0x3e5211e89f8619b7}, + {0x3ff04e5f70000000,0x3e47b2a5894c3794}, + {0x3ff0513300000000,0x3e6d83407ebcd45f}, + {0x3ff0540720000000,0x3e5ff05d8654351e}, + {0x3ff056dbb0000000,0x3e6d76f0d641b21d}, + {0x3ff059b0d0000000,0x3e48ac2ba1d73e2a}, + {0x3ff05c8660000000,0x3e5480116aa51f2f}, + {0x3ff05f5c70000000,0x3e53c2fb09996d50}, + {0x3ff0623300000000,0x3e44ec10b242a8b7}, + {0x3ff0650a00000000,0x3e6c783f1151a425}, + {0x3ff067e190000000,0x3e5f89b050324159}, + {0x3ff06ab990000000,0x3e6f4c80f79685bf}, + {0x3ff06d9220000000,0x3e5675e532de0a3f}, + {0x3ff0706b20000000,0x3e63bbedbb8db880}, + {0x3ff07344a0000000,0x3e68fb3aa173f7e8}, + {0x3ff0761ea0000000,0x3e6b24a92589ea67}, + {0x3ff078f920000000,0x3e6a6410ba6f5125}, + {0x3ff07bd420000000,0x3e66e5506c4c8cd1}, + {0x3ff07eafa0000000,0x3e60d44ee223dd7a}, + {0x3ff0818ba0000000,0x3e50b9f4be45b9bf}, + {0x3ff0846810000000,0x3e6dab48c3f43342}, + {0x3ff0874510000000,0x3e60eb37901186be}, + {0x3ff08a2290000000,0x3e32465f18ad29db}, + {0x3ff08d0080000000,0x3e61f0127e0ee8f9}, + {0x3ff08fdf00000000,0x3dda3f89a3af8986}, + {0x3ff092bdf0000000,0x3e59981f7e97f9c8}, + {0x3ff0959d60000000,0x3e6859061ad6fdb9}, + {0x3ff0987d60000000,0x3e3701715c5f4984}, + {0x3ff09b5dd0000000,0x3e591b75db2d8400}, + {0x3ff09e3ec0000000,0x3e658de7068a43c1}, + {0x3ff0a12030000000,0x3e6e0cf4c6b3e2ee}, + {0x3ff0a40230000000,0x3e48dcb8a9c01f5a}, + {0x3ff0a6e4a0000000,0x3e5c71c9b6fd090b}, + {0x3ff0a9c790000000,0x3e663e72325745b2}, + {0x3ff0acab00000000,0x3e6e7437377f3ebc}, + {0x3ff0af8f00000000,0x3e4c1a7293764302}, + {0x3ff0b27370000000,0x3e602212e710ecd7}, + {0x3ff0b55860000000,0x3e69f3121ec53172}, + {0x3ff0b83de0000000,0x3e42986888250c15}, + {0x3ff0bb23d0000000,0x3e6067b27da51fde}, + {0x3ff0be0a40000000,0x3e6d646a76702f53}, + {0x3ff0c0f140000000,0x3e5791b2154f9890}, + {0x3ff0c3d8b0000000,0x3e6bc19cf3460b11}, + {0x3ff0c6c0b0000000,0x3e5af6b94ab1757f}, + {0x3ff0c9a930000000,0x3e222c65358a1e6f}, + {0x3ff0cc9220000000,0x3e66e48fee80f6e1}, + {0x3ff0cf7ba0000000,0x3e5ddaee504e2734}, + {0x3ff0d265a0000000,0x3e52d482e624c9ea}, + {0x3ff0d55020000000,0x3e4a1ef01352572a}, + {0x3ff0d83b20000000,0x3e49caef5c87d643}, + {0x3ff0db26a0000000,0x3e52b03b52543578}, + {0x3ff0de12a0000000,0x3e5ec98c01e181a9}, + {0x3ff0e0ff20000000,0x3e68c5a12ca6e25d}, + {0x3ff0e3ec30000000,0x3e469e8d10103a17}, + {0x3ff0e6d9b0000000,0x3e6637c8299ffabc}, + {0x3ff0e9c7c0000000,0x3e5546271898a049}, + {0x3ff0ecb650000000,0x3e38b4874375a83b}, + {0x3ff0efa550000000,0x3e6fbf53895b1232}, + {0x3ff0f294f0000000,0x3e194ed155c28cc4}, + {0x3ff0f58500000000,0x3e499473669fa755}, + {0x3ff0f87590000000,0x3e60bc7136873bb9}, + {0x3ff0fb66a0000000,0x3e6ffda635e46412}, + {0x3ff0fe5840000000,0x3e6455f6420cdf93}, + {0x3ff1014a60000000,0x3e5be54738bdf791}, + {0x3ff1043d00000000,0x3e5a01f0bd4b8312}, + {0x3ff1073020000000,0x3e61ae467c751bac}, + {0x3ff10a23c0000000,0x3e6c27e7c4863a25}, + {0x3ff10d17f0000000,0x3e59367bc42862ec}, + {0x3ff1100ca0000000,0x3e39ad92f1c6b500}, + {0x3ff11301d0000000,0x3df25b50a4ebbf1b}, + {0x3ff115f780000000,0x3e3cae1fa1b07d74}, + {0x3ff118edb0000000,0x3e5b6cb703c63407}, + {0x3ff11be460000000,0x3e6eb406588b1e90}, + {0x3ff11edba0000000,0x3e66bc556b1add58}, + {0x3ff121d360000000,0x3e65fce1928ff5aa}, + {0x3ff124cba0000000,0x3e6ca34b8f576a36}, + {0x3ff127c470000000,0x3e55ba781558c3c6}, + {0x3ff12abdc0000000,0x3e1b0c72fee4aeb5}, + {0x3ff12db780000000,0x3e6ec27ab62c5a0b}, + {0x3ff130b1e0000000,0x3e43250744b1e1dc}, + {0x3ff133acb0000000,0x3e631a8143238190}, + {0x3ff136a810000000,0x3e53c812abd1dee1}, + {0x3ff139a3f0000000,0x3e52a76488bfc77b}, + {0x3ff13ca050000000,0x3e61975c3bd792f7}, + {0x3ff13f9d40000000,0x3e36e77aeb5f66f2}, + {0x3ff1429aa0000000,0x3e6d525bbf668203}, + {0x3ff14598a0000000,0x3e225996e9fa677c}, + {0x3ff1489710000000,0x3e5d0950dfbfa37c}, + {0x3ff14b9610000000,0x3e4676430504efdf}, + {0x3ff14e9590000000,0x3e4a79896e46e17c}, + {0x3ff1519590000000,0x3e61b53533b4cd1a}, + {0x3ff1549620000000,0x3e4c40a4f01821b0}, + {0x3ff1579730000000,0x3e4b759996ee4d58}, + {0x3ff15a98c0000000,0x3e614b1ca24901ab}, + {0x3ff15d9ae0000000,0x3e4a1e0f93097e9e}, + {0x3ff1609d80000000,0x3e4b03708cfdf453}, + {0x3ff163a0a0000000,0x3e62256d583f7602}, + {0x3ff166a450000000,0x3e51c70f0818f23c}, + {0x3ff169a880000000,0x3e5653055c3f9782}, + {0x3ff16cad30000000,0x3e6925bee6860ba8}, + {0x3ff16fb270000000,0x3e6306a44743ae75}, + {0x3ff172b830000000,0x3e68faa2f5b9bef9}, + {0x3ff175be80000000,0x3e5660664815b0ae}, + {0x3ff178c550000000,0x3e53abaa2500be0f}, + {0x3ff17bcca0000000,0x3e651a1110eff7c7}, + {0x3ff17ed480000000,0x3e5a56ef00427900}, + {0x3ff181dce0000000,0x3e6238a0d333af2f}, + {0x3ff184e5d0000000,0x3e41c0b64413ab6a}, + {0x3ff187ef40000000,0x3e400319565c4a82}, + {0x3ff18af930000000,0x3e61191bd3777ee1}, + {0x3ff18e03b0000000,0x3e57cfcdaa4b513b}, + {0x3ff1910eb0000000,0x3e649be83e7a5306}, + {0x3ff1941a40000000,0x3e56c7d21c1de6ab}, + {0x3ff1972650000000,0x3e606eba5ea556ec}, + {0x3ff19a32f0000000,0x3e3f59ab447c3e7f}, + {0x3ff19d4010000000,0x3e4820ee0c5fbe16}, + {0x3ff1a04db0000000,0x3e66f4b625e9b85d}, + {0x3ff1a35be0000000,0x3e66df96ea796d32}, + {0x3ff1a66aa0000000,0x3e47df5e35b75ed4}, + {0x3ff1a979e0000000,0x3e41b1e7c02474f4}, + {0x3ff1ac89a0000000,0x3e626c8819921a35}, + {0x3ff1af99f0000000,0x3e60271438bdfc2d}, + {0x3ff1b2aac0000000,0x3e6dcb38a51a1a99}, + {0x3ff1b5bc20000000,0x3e6b8817e0760e4b}, + {0x3ff1b8ce10000000,0x3e5319b9309c0f58}, + {0x3ff1bbe080000000,0x3e5011734e6ac79d}, + {0x3ff1bef370000000,0x3e672aea1641804f}, + {0x3ff1c206f0000000,0x3e6722b11e74ce25}, + {0x3ff1c51b00000000,0x3e503eb4545446b1}, + {0x3ff1c82f90000000,0x3e54a071ad009778}, + {0x3ff1cb44a0000000,0x3e6de4a8f4c5d8a8}, + {0x3ff1ce5a50000000,0x3e3860745f297e2f}, + {0x3ff1d17070000000,0x3e69f5d5d9d0d8fa}, + {0x3ff1d48730000000,0x3e368b9aa7805b80}, + {0x3ff1d79e60000000,0x3e6dce63ad8b79de}, + {0x3ff1dab630000000,0x3e5638579e74bbfb}, + {0x3ff1ddce80000000,0x3e55d4b1c49f86a5}, + {0x3ff1e0e750000000,0x3e6d68804d481140}, + {0x3ff1e400c0000000,0x3e3631fdb1b6a3de}, + {0x3ff1e71aa0000000,0x3e6b333d0434c7ec}, + {0x3ff1ea3520000000,0x3e4b7c99833873ca}, + {0x3ff1ed5020000000,0x3e47e6c8e5c40d00}, + {0x3ff1f06ba0000000,0x3e68b29f40dc7026}, + {0x3ff1f387b0000000,0x3e6f39b4708f2585}, + {0x3ff1f6a450000000,0x3e69bec10a36f854}, + {0x3ff1f9c180000000,0x3e50e3393240adb6}, + {0x3ff1fcdf30000000,0x3e57044de74c1d2d}, + {0x3ff1fffd70000000,0x3e390241e50a8f3e}, + {0x3ff2031c30000000,0x3e5ef7e1c9b3fb10}, + {0x3ff2063b80000000,0x3e60c519ac771dd6}, + {0x3ff2095b60000000,0x3e4caf0e91bed019}, + {0x3ff20c7bc0000000,0x3e62dff82ffbbb3c}, + {0x3ff20f9cb0000000,0x3e6411c906056d9d}, + {0x3ff212be30000000,0x3e55e2a0653592d3}, + {0x3ff215e030000000,0x3e67aeb0185f561b}, + {0x3ff21902c0000000,0x3e6a7a1371fe29a8}, + {0x3ff21c25e0000000,0x3e6383ad539c2ddf}, + {0x3ff21f4990000000,0x3e37ddc962552fd3}, + {0x3ff2226dc0000000,0x3e5224f58ef3e8d7}, + {0x3ff2259280000000,0x3e47e0f939b283a8}, + {0x3ff228b7c0000000,0x3e69dd5849aa9ed4}, + {0x3ff22bdda0000000,0x3e43c89689d34fb5}, + {0x3ff22f0400000000,0x3e4d9c2e90e37e0b}, + {0x3ff2322af0000000,0x3e26c77fe0521ff5}, + {0x3ff2355260000000,0x3e6332e0c3fd0501}, + {0x3ff2387a60000000,0x3e6ceac470cd83f6}, + {0x3ff23ba2f0000000,0x3e6ec4a9e721f548}, + {0x3ff23ecc10000000,0x3e68f12073191430}, + {0x3ff241f5c0000000,0x3e57417f9774965a}, + {0x3ff2451ff0000000,0x3e670428146b3f32}, + {0x3ff2484ab0000000,0x3e6b4c01de659b96}, + {0x3ff24b7600000000,0x3e68a8fe2a2d1ecb}, + {0x3ff24ea1e0000000,0x3e5e97acd20bcfe9}, + {0x3ff251ce40000000,0x3e6f654c7e6b0557}, + {0x3ff254fb40000000,0x3e524c55830a8778}, + {0x3ff25828c0000000,0x3e597e87fd447d94}, + {0x3ff25b56d0000000,0x3e54c2e6f15764c6}, + {0x3ff25e8570000000,0x3e31ece754f86893}, + {0x3ff261b490000000,0x3e6484ac89054394}, + {0x3ff264e450000000,0x3e26797036ae5806}, + {0x3ff2681490000000,0x3e522eb30bb0e65e}, + {0x3ff26b4560000000,0x3e5789f37495e99d}, + {0x3ff26e76c0000000,0x3e53430b9459a58e}, + {0x3ff271a8b0000000,0x3e36f0a2fe777b95}, + {0x3ff274db20000000,0x3e67abc4a7e20230}, + {0x3ff2780e30000000,0x3e50777ca5e067c0}, + {0x3ff27b41c0000000,0x3e64bf3196d6fcdb}, + {0x3ff27e75e0000000,0x3e6d675730414460}, + {0x3ff281aaa0000000,0x3e332b83210e0cc1}, + {0x3ff284dfe0000000,0x3e3f5638096cf15d}, + {0x3ff28815b0000000,0x3e31456b0abad3c9}, + {0x3ff28b4c00000000,0x3e6d507e6b49f37d}, + {0x3ff28e82f0000000,0x3e65939d93e44a73}, + {0x3ff291ba70000000,0x3e5646edbf699c6f}, + {0x3ff294f270000000,0x3e6e317ee475667e}, + {0x3ff2982b10000000,0x3e5dde65950f41c2}, + {0x3ff29b6430000000,0x3e6d8e184e711fd8}, + {0x3ff29e9df0000000,0x3e547f7b84b09745}, + {0x3ff2a1d830000000,0x3e6535ba0f81452c}, + {0x3ff2a51300000000,0x3e6ea1acb7cb1afd}, + {0x3ff2a84e70000000,0x3e4ad4f75cb50100}, + {0x3ff2ab8a60000000,0x3e5b443c4a6a8bce}, + {0x3ff2aec6e0000000,0x3e639a06f684d5fa}, + {0x3ff2b203f0000000,0x3e68ceba3e4ff11e}, + {0x3ff2b54190000000,0x3e6d72028fdb6e5f}, + {0x3ff2b87fd0000000,0x3e2b5b31ffbbd48d}, + {0x3ff2bbbe90000000,0x3e472e9f1a4fa958}, + {0x3ff2befde0000000,0x3e53cb8a0029cb8e}, + {0x3ff2c23dc0000000,0x3e5c6befddfa19d0}, + {0x3ff2c57e30000000,0x3e62ee365d57f5d3}, + {0x3ff2c8bf30000000,0x3e68407ebe3e7dba}, + {0x3ff2cc00c0000000,0x3e6e5ed82f5719c6}, + {0x3ff2cf42f0000000,0x3e45ed49e959aa30}, + {0x3ff2d285a0000000,0x3e5b900c2d002475}, + {0x3ff2d5c8e0000000,0x3e6777142a27cd70}, + {0x3ff2d90cc0000000,0x3e35d534619676be}, + {0x3ff2dc5120000000,0x3e5f89df8b32bb28}, + {0x3ff2df9610000000,0x3e6ec82b12e8b680}, + {0x3ff2e2dba0000000,0x3e5fed38cb8a60a7}, + {0x3ff2e621c0000000,0x3e3c1483336515dc}, + {0x3ff2e96860000000,0x3e699e5c75391066}, + {0x3ff2ecafa0000000,0x3e627c5eac23941f}, + {0x3ff2eff770000000,0x3e5c9dfbc08f21e4}, + {0x3ff2f33fd0000000,0x3e5a915346cc4af5}, + {0x3ff2f688c0000000,0x3e5f37b48ad3c49f}, + {0x3ff2f9d240000000,0x3e657b10d5eac3ab}, + {0x3ff2fd1c50000000,0x3e6f18d725b26e52}, + {0x3ff3006700000000,0x3e594f7f90815f95}, + {0x3ff303b230000000,0x3e6e5a66155041e4}, + {0x3ff306fe00000000,0x3e64636e2a5bd1ab}, + {0x3ff30a4a60000000,0x3e5deb09d8469390}, + {0x3ff30d9750000000,0x3e5c86c01062c0b4}, + {0x3ff310e4d0000000,0x3e627fbdf661685a}, + {0x3ff31432e0000000,0x3e6bdd65fa656690}, + {0x3ff3178190000000,0x3e551e504a98d44b}, + {0x3ff31ad0c0000000,0x3e6ec7dd570928e5}, + {0x3ff31e2090000000,0x3e68ba673ff8df2b}, + {0x3ff32170f0000000,0x3e6899b0626a739e}, + {0x3ff324c1e0000000,0x3e6e98ac1425deaf}, + {0x3ff3281370000000,0x3e55d4acffe7abed}, + {0x3ff32b6580000000,0x3e6dc1b4a725bb73}, + {0x3ff32eb830000000,0x3e6751d4631dd0be}, + {0x3ff3320b70000000,0x3e67cdcc66d7ae36}, + {0x3ff3355f40000000,0x3e6f68bc4070fe38}, + {0x3ff338b3b0000000,0x3e5cab98b564f8c7}, + {0x3ff33c08b0000000,0x3e4320b7fa64e431}, + {0x3ff33f5e40000000,0x3e3798daa7010649}, + {0x3ff342b460000000,0x3e5213aecf139089}, + {0x3ff3460b10000000,0x3e673fae236a7c4b}, + {0x3ff3496260000000,0x3e5b8fe8b3652c53}, + {0x3ff34cba40000000,0x3e59ac0f82f228d7}, + {0x3ff35012b0000000,0x3e649d4ef94677f7}, + {0x3ff3536bc0000000,0x3e4544e6227f9687}, + {0x3ff356c550000000,0x3e6f253fe1928c47}, + {0x3ff35a1f90000000,0x3e32671b11fa7ae7}, + {0x3ff35d7a50000000,0x3e5df75caccd6c5d}, + {0x3ff360d5b0000000,0x3e4594cfe3d47eae}, + {0x3ff36431a0000000,0x3e46f441d63cebb6}, + {0x3ff3678e20000000,0x3e6036e8ea1ec475}, + {0x3ff36aeb40000000,0x3e4419ada17e20a7}, + {0x3ff36e48f0000000,0x3e417d3bddb2a0d0}, + {0x3ff371a730000000,0x3e5ceaa72a9c5154}, + {0x3ff3750610000000,0x3e3be211c4360175}, + {0x3ff3786580000000,0x3e3d3f668d0f6c10}, + {0x3ff37bc580000000,0x3e5e585c9984a42b}, + {0x3ff37f2620000000,0x3e48f3aa4cc146ac}, + {0x3ff3828750000000,0x3e521c1d19d1ee21}, + {0x3ff385e910000000,0x3e67d390222d1dff}, + {0x3ff3894b70000000,0x3e62c16e3d10e22c}, + {0x3ff38cae60000000,0x3e6a0bb0cb0b5396}, + {0x3ff39011f0000000,0x3e5bccd17d0ce041}, + {0x3ff3937610000000,0x3e5d0b6020dec4fb}, + {0x3ff396dac0000000,0x3e6c1da9c1c7067e}, + {0x3ff39a4010000000,0x3e66e281dd32b2d0}, + {0x3ff39da5f0000000,0x3e6f086d788d4831}, + {0x3ff3a10c70000000,0x3e64c3aab678862e}, + {0x3ff3a47380000000,0x3e684880c7eea56a}, + {0x3ff3a7db30000000,0x3e53967fdba86f25}, + {0x3ff3ab4370000000,0x3e530082f51499d4}, + {0x3ff3aeac40000000,0x3e679be7d380df9b}, + {0x3ff3b215b0000000,0x3e64529e72c984bd}, + {0x3ff3b57fb0000000,0x3e6fd8d9e8aa6337}, + {0x3ff3b8ea50000000,0x3e6a6317dd31706d}, + {0x3ff3bc5590000000,0x3e40977c471fcb75}, + {0x3ff3bfc150000000,0x3e6d55bf62c64ab0}, + {0x3ff3c32dc0000000,0x3e489d47242000f9}, + {0x3ff3c69ab0000000,0x3e6ecf385b8018ad}, + {0x3ff3ca0850000000,0x3e4e08794336c259}, + {0x3ff3cd7680000000,0x3e0d2e00343736bd}, + {0x3ff3d0e540000000,0x3e53b785cc7fa342}, + {0x3ff3d454a0000000,0x3e3f602d01e27c72}, + {0x3ff3d7c490000000,0x3e5db49fe7d2ae92}, + {0x3ff3db3520000000,0x3e55b6f59c02469c}, + {0x3ff3dea640000000,0x3e682468446b6824}, + {0x3ff3e21800000000,0x3e66ea0397d3daff}, + {0x3ff3e58a60000000,0x3e4d8504d503fb5b}, + {0x3ff3e8fd50000000,0x3e537e3d6f567009}, + {0x3ff3ec70d0000000,0x3e6e38a2e9942672}, + {0x3ff3efe500000000,0x3e440b771a791993}, + {0x3ff3f359b0000000,0x3e6e52e87d24d7f0}, + {0x3ff3f6cf10000000,0x3e54bbcadfa81a3e}, + {0x3ff3fa4500000000,0x3e52b2006e82fdc0}, + {0x3ff3fdbb80000000,0x3e6b796da384e8be}, + {0x3ff40132b0000000,0x3e1e8d77ba256df3}, + {0x3ff404aa60000000,0x3e69ff41ca0d9656}, + {0x3ff40822c0000000,0x3e4b3d0121bddf8b}, + {0x3ff40b9bb0000000,0x3e4e6703dc4fd424}, + {0x3ff40f1530000000,0x3e6c9426d39a27ae}, + {0x3ff4128f60000000,0x3e47cf7872f610ea}, + {0x3ff4160a20000000,0x3e3f72e29f84325c}, + {0x3ff4198570000000,0x3e66b9203ef7a494}, + {0x3ff41d0160000000,0x3e6e89b1e9848bfb}, + {0x3ff4207df0000000,0x3e6b95a2a6d1a206}, + {0x3ff423fb20000000,0x3e5c251a267b9d24}, + {0x3ff42778e0000000,0x3e66361515e88cf6}, + {0x3ff42af740000000,0x3e6435e7e24e448d}, + {0x3ff42e7640000000,0x3e508f77f3c9d17b}, + {0x3ff431f5d0000000,0x3e62a1512db8e088}, + {0x3ff4357600000000,0x3e637870a00a35aa}, + {0x3ff438f6d0000000,0x3e5605d98bd416b5}, + {0x3ff43c7830000000,0x3e6976a168d85cbb}, + {0x3ff43ffa30000000,0x3e6f0973a86202fa}, + {0x3ff4437cd0000000,0x3e6bf151fbbf0341}, + {0x3ff4470010000000,0x3e6064343371246a}, + {0x3ff44a83e0000000,0x3e6c981b7ae2cca0}, + {0x3ff44e0860000000,0x3e18624b40c4dbd0}, + {0x3ff4518d60000000,0x3e6d1b2cb6f4906b}, + {0x3ff4551310000000,0x3e61d687d78e4e57}, + {0x3ff4589950000000,0x3e6f2b4a631a8b08}, + {0x3ff45c2040000000,0x3e453e918f9e6f9a}, + {0x3ff45fa7c0000000,0x3e41e73d23ae3cab}, + {0x3ff4632fd0000000,0x3e6ce00de76501e8}, + {0x3ff466b890000000,0x3e5d7158f8f87ca8}, + {0x3ff46a41e0000000,0x3e6a3a00aee4a25f}, + {0x3ff46dcbd0000000,0x3e6f9a69907e4ea2}, + {0x3ff4715660000000,0x3e6f104f9ff81dc1}, + {0x3ff474e190000000,0x3e68d224ca71e42c}, + {0x3ff4786d60000000,0x3e5a2cc8da3df0f1}, + {0x3ff47bf9c0000000,0x3e6c139356e90433}, + {0x3ff47f86d0000000,0x3e4800ff284c755b}, + {0x3ff4831470000000,0x3e562602fbba50d4}, + {0x3ff486a2b0000000,0x3e5704f3404f068f}, + {0x3ff48a3190000000,0x3e4e154b5c5be2af}, + {0x3ff48dc100000000,0x3e6f524142b8fc8e}, + {0x3ff4915120000000,0x3e6320027ea83152}, + {0x3ff494e1e0000000,0x3e392aed1d89aed4}, + {0x3ff4987330000000,0x3e5f324692ef792a}, + {0x3ff49c0520000000,0x3e68b22d881beb7d}, + {0x3ff49f97b0000000,0x3e6ea75ff9e00531}, + {0x3ff4a32af0000000,0x3e2afa7bcce5b17a}, + {0x3ff4a6bec0000000,0x3e300fdba2fc457c}, + {0x3ff4aa5320000000,0x3e6fd55b4b20f80e}, + {0x3ff4ade830000000,0x3e6b60d0f45baf9d}, + {0x3ff4b17de0000000,0x3e64db6fadbb691e}, + {0x3ff4b51430000000,0x3e58f8a881ebe41b}, + {0x3ff4b8ab20000000,0x3e33d5282b96ab17}, + {0x3ff4bc42a0000000,0x3e670d91e1f34ec2}, + {0x3ff4bfdad0000000,0x3e54d8a89c750e5f}, + {0x3ff4c37390000000,0x3e6cce2f54b61b46}, + {0x3ff4c70d00000000,0x3e5cd4df284dd61c}, + {0x3ff4caa700000000,0x3e6f786b414a336c}, + {0x3ff4ce41b0000000,0x3e602f822882f14b}, + {0x3ff4d1dd00000000,0x3e18e3b5f071cfb7}, + {0x3ff4d578e0000000,0x3e6176b0d6f7d869}, + {0x3ff4d91570000000,0x3e33adc1e17a0458}, + {0x3ff4dcb290000000,0x3e63fbba1ac766de}, + {0x3ff4e05060000000,0x3e490119395bb8c9}, + {0x3ff4e3eec0000000,0x3e697af654189a82}, + {0x3ff4e78dd0000000,0x3e5bc6da992d729d}, + {0x3ff4eb2d80000000,0x3e3d8abfeab6a0b4}, + {0x3ff4eecdc0000000,0x3e6b1c6cd285acef}, + {0x3ff4f26eb0000000,0x3e645c6be0a3854c}, + {0x3ff4f61040000000,0x3e5f523dcc615e0e}, + {0x3ff4f9b270000000,0x3e5a74b29ab4cf63}, + {0x3ff4fd5540000000,0x3e5a8ff05b4ffc78}, + {0x3ff500f8b0000000,0x3e6009e24da84302}, + {0x3ff5049cc0000000,0x3e65b808249f4248}, + {0x3ff5084170000000,0x3e6e8a63dc344937}, + {0x3ff50be6d0000000,0x3e5571f2a4406abb}, + {0x3ff50f8cc0000000,0x3e6a7bd619dc0ed4}, + {0x3ff5133360000000,0x3e5c1622fc9fd9f4}, + {0x3ff516daa0000000,0x3e467b320e0897a9}, + {0x3ff51a8280000000,0x3e26f31e846c8ad6}, + {0x3ff51e2b00000000,0x3e2b47627ef62368}, + {0x3ff521d420000000,0x3e4a9b5defec34e6}, + {0x3ff5257de0000000,0x3e607e9dddc6cce5}, + {0x3ff5292840000000,0x3e6f741b083e3293}, + {0x3ff52cd350000000,0x3e63bfaa798c4e6f}, + {0x3ff5307f00000000,0x3e5b3362e999d66d}, + {0x3ff5342b50000000,0x3e5a753e077c2a0f}, + {0x3ff537d840000000,0x3e62daebf871eb59}, + {0x3ff53b85d0000000,0x3e6eb31aef00be29}, + {0x3ff53f3410000000,0x3e60fbb84f3b7669}, + {0x3ff542e2f0000000,0x3e53dab49cbc9369}, + {0x3ff5469270000000,0x3e538141e18772d7}, + {0x3ff54a4290000000,0x3e60ae360b97dd2a}, + {0x3ff54df350000000,0x3e6eeecd468bf8bc}, + {0x3ff551a4c0000000,0x3e64bb241d8a5d8c}, + {0x3ff55556d0000000,0x3e624c01e26a97ab}, + {0x3ff5590980000000,0x3e67da37bea5e667}, + {0x3ff55cbce0000000,0x3e467a82d4300257}, + {0x3ff56070d0000000,0x3e6bd221a378248f}, + {0x3ff5642570000000,0x3e6aada9448673ef}, + {0x3ff567dac0000000,0x3e3351818a4cd91b}, + {0x3ff56b90a0000000,0x3e6340b8e300c4dc}, + {0x3ff56f4730000000,0x3e5ad49f699bb2c0}, + {0x3ff572fe60000000,0x3e61200ae56c09e3}, + {0x3ff576b630000000,0x3e6e9b0a98e6a7d7}, + {0x3ff57a6eb0000000,0x3e661478da504852}, + {0x3ff57e27d0000000,0x3e67c5899d7a339c}, + {0x3ff581e1a0000000,0x3e3f3bd6056106d3}, + {0x3ff5859c00000000,0x3e6ab3940e5c3e04}, + {0x3ff5895710000000,0x3e6c63273ee78411}, + {0x3ff58d12d0000000,0x3e525f1ff494af0b}, + {0x3ff590cf30000000,0x3e25233d9d9755bb}, + {0x3ff5948c30000000,0x3e441209a7ecb170}, + {0x3ff59849d0000000,0x3e647ff52be0e2f1}, + {0x3ff59c0820000000,0x3e5ffc1f2e81d312}, + {0x3ff59fc710000000,0x3e67b85f1c109984}, + {0x3ff5a386b0000000,0x3e57d0f6487d81a5}, + {0x3ff5a746f0000000,0x3e59900a2adcb475}, + {0x3ff5ab07d0000000,0x3e6a90a852b19260}, + {0x3ff5aec960000000,0x3e657c1a3e45199a}, + {0x3ff5b28b90000000,0x3e6dc41a3b4bc29b}, + {0x3ff5b64e70000000,0x3e63a271af8a6e06}, + {0x3ff5ba11f0000000,0x3e6750f4052442f6}, + {0x3ff5bdd620000000,0x3e5212fd58ae68fc}, + {0x3ff5c19af0000000,0x3e520bf23a71a88f}, + {0x3ff5c56060000000,0x3e678054d973723c}, + {0x3ff5c92680000000,0x3e64b28d6e038963}, + {0x3ff5cced50000000,0x3e1ad50e9eaf3e01}, + {0x3ff5d0b4b0000000,0x3e6c26b597239097}, + {0x3ff5d47cd0000000,0x3e4b733a37d16cc4}, + {0x3ff5d84590000000,0x3e2331725194ac2c}, + {0x3ff5dc0ef0000000,0x3e56c77a789b45d2}, + {0x3ff5dfd900000000,0x3e46a3e32456db08}, + {0x3ff5e3a3b0000000,0x3e603d0bd87e7360}, + {0x3ff5e76f10000000,0x3e56b48521ba6f93}, + {0x3ff5eb3b10000000,0x3e673af3338ffaa3}, + {0x3ff5ef07c0000000,0x3e64197e1ebdbd81}, + {0x3ff5f2d520000000,0x3e31826e78ba6fd8}, + {0x3ff5f6a320000000,0x3e2b9d6e19854887}, + {0x3ff5fa71c0000000,0x3e62f0981548b132}, + {0x3ff5fe4110000000,0x3e660f1a4cfe262a}, + {0x3ff6021110000000,0x3e569fe1223ca0b3}, + {0x3ff605e1b0000000,0x3e62edb81160edeb}, + {0x3ff609b300000000,0x3e5a46304d24e5c3}, + {0x3ff60d84f0000000,0x3e6a2ac25456ebce}, + {0x3ff6115790000000,0x3e6a3f724aed2eac}, + {0x3ff6152ae0000000,0x3e5b37dbd1e4b3e5}, + {0x3ff618fed0000000,0x3e647b053d25a1ee}, + {0x3ff61cd370000000,0x3e5e2f251058d8d0}, + {0x3ff620a8b0000000,0x3e6dac7a3e56baa9}, + {0x3ff6247eb0000000,0x3e0d2ac258f87d03}, + {0x3ff6285540000000,0x3e67ab1dca47926d}, + {0x3ff62c2c90000000,0x3e3c56acd779649f}, + {0x3ff6300480000000,0x3e413b7f401d952a}, + {0x3ff633dd10000000,0x3e6a3253fac23886}, + {0x3ff637b660000000,0x3e45c14faa74aaac}, + {0x3ff63b9050000000,0x3e49102ebc9f62ad}, + {0x3ff63f6ae0000000,0x3e6ce8b199cad6ed}, + {0x3ff6434630000000,0x3e53330c7f1dbe1c}, + {0x3ff6472220000000,0x3e5923a8f5c89918}, + {0x3ff64afec0000000,0x3e4833c5b5aba188}, + {0x3ff64edc00000000,0x3e66463c81ba03ab}, + {0x3ff652b9f0000000,0x3e6d791f6d28e152}, + {0x3ff6569890000000,0x3e6be10e31976ede}, + {0x3ff65a77e0000000,0x3e61b9871f374c72}, + {0x3ff65e57d0000000,0x3e6f3e12d65523fc}, + {0x3ff6623880000000,0x3e42a91124893ecf}, + {0x3ff66619d0000000,0x3e31cdc5ebf67f3e}, + {0x3ff669fbc0000000,0x3e682817cec39032}, + {0x3ff66dde70000000,0x3e4ac44dbe33f068}, + {0x3ff671c1c0000000,0x3e5c20cfd70bc66d}, + {0x3ff675a5c0000000,0x3e5d03b7d26559b6}, + {0x3ff6798a70000000,0x3e508280d779b6ba}, + {0x3ff67d6fc0000000,0x3e6b8a70d4bedf04}, + {0x3ff68155d0000000,0x3e5132a5cc20715d}, + {0x3ff6853c80000000,0x3e5f53ad8723d869}, + {0x3ff68923e0000000,0x3e60f7f6f4fb42a5}, + {0x3ff68d0bf0000000,0x3e597f70cf4db8b0}, + {0x3ff690f4b0000000,0x3e39e953830097b3}, + {0x3ff694de10000000,0x3e64ac66cd30ab74}, + {0x3ff698c830000000,0x3e24991a72ed817c}, + {0x3ff69cb2f0000000,0x3e52a1b328971532}, + {0x3ff6a09e60000000,0x3e59fcef32422cbf}, + {0x3ff6a48a80000000,0x3e591d5e558445ea}, + {0x3ff6a87750000000,0x3e507b9c6111dd77}, + {0x3ff6ac64d0000000,0x3e020b4179b87a6a}, + {0x3ff6b052f0000000,0x3e64ea2e7c3471ea}, + {0x3ff6b441d0000000,0x3e4980ff72055486}, + {0x3ff6b83150000000,0x3e64e6d8e965072a}, + {0x3ff6bc2190000000,0x3e174f7c19f3b303}, + {0x3ff6c01270000000,0x3e542f6afbb5daa6}, + {0x3ff6c40400000000,0x3e613b1cfa9c008b}, + {0x3ff6c7f640000000,0x3e66615411f4dd60}, + {0x3ff6cbe930000000,0x3e69c70701669d4c}, + {0x3ff6cfdcd0000000,0x3e6ba8ec8ae3d54e}, + {0x3ff6d3d120000000,0x3e6c43c5f6a34ef8}, + {0x3ff6d7c620000000,0x3e6bd45f14f31260}, + {0x3ff6dbbbd0000000,0x3e6a978e400bc107}, + {0x3ff6dfb230000000,0x3e68ca345de441c6}, + {0x3ff6e3a940000000,0x3e66a93ce205bdc4}, + {0x3ff6e7a100000000,0x3e64719dcf5fee9c}, + {0x3ff6eb9970000000,0x3e626057ba1dbd9e}, + {0x3ff6ef9290000000,0x3e60b275c97a345b}, + {0x3ff6f38c60000000,0x3e5f4a1b732b7cde}, + {0x3ff6f786e0000000,0x3e5eea7fba97795b}, + {0x3ff6fb8210000000,0x3e606037200869ac}, + {0x3ff6ff7df0000000,0x3e62a329079f0fc3}, + {0x3ff7037a80000000,0x3e667b55b6209097}, + {0x3ff70777c0000000,0x3e6c2607ebb23e26}, + {0x3ff70b75c0000000,0x3e3f04a843282bff}, + {0x3ff70f7460000000,0x3e5bd0ba1c19d645}, + {0x3ff71373b0000000,0x3e6a7acaa218d916}, + {0x3ff71773c0000000,0x3e53aaa61ed57da4}, + {0x3ff71b7470000000,0x3e6c3576483002f4}, + {0x3ff71f75e0000000,0x3e61d8bee7ba46e2}, + {0x3ff7237800000000,0x3e55f98468b0f8c0}, + {0x3ff7277ad0000000,0x3e4f7c8084c13489}, + {0x3ff72b7e50000000,0x3e517b06a02fa8ea}, + {0x3ff72f8280000000,0x3e5bab4226df55fd}, + {0x3ff7338760000000,0x3e6765396ffd44b2}, + {0x3ff7378d00000000,0x3e46a85c7b1683da}, + {0x3ff73b9340000000,0x3e68e20f8ee84d1f}, + {0x3ff73f9a40000000,0x3e614b02e77ab935}, + {0x3ff743a1f0000000,0x3e5e45b812c7be47}, + {0x3ff747aa50000000,0x3e62a79091383c65}, + {0x3ff74bb360000000,0x3e6c1720d9161e22}, + {0x3ff74fbd30000000,0x3e575f2ff5047fd6}, + {0x3ff753c7b0000000,0x3e2af0bd044bd0fc}, + {0x3ff757d2d0000000,0x3e6e539cf846549f}, + {0x3ff75bdec0000000,0x3e2db76d56e0024f}, + {0x3ff75feb50000000,0x3e59099f22fdba6b}, + {0x3ff763f890000000,0x3e6e8de81ef669c8}, + {0x3ff7680690000000,0x3e68350c3aeb1382}, + {0x3ff76c1540000000,0x3e69b8926eeb19ed}, + {0x3ff77024b0000000,0x3e3ab6e096de1dc6}, + {0x3ff77434c0000000,0x3e654e554ed8e709}, + {0x3ff7784590000000,0x3e5fbaea3a2989ca}, + {0x3ff77c5710000000,0x3e6342bd4bb837d6}, + {0x3ff7806940000000,0x3e6fbcba7ec335c0}, + {0x3ff7847c30000000,0x3e658a0431eda50d}, + {0x3ff7888fd0000000,0x3e64e93cba888524}, + {0x3ff78ca420000000,0x3e6e1911495f6a58}, + {0x3ff790b930000000,0x3e615839ec9a4d43}, + {0x3ff794cef0000000,0x3e5dcaf3233f5b53}, + {0x3ff798e560000000,0x3e66ff9e06f708f1}, + {0x3ff79cfc90000000,0x3e53cafffc57486f}, + {0x3ff7a11470000000,0x3e4f580c36bea881}, + {0x3ff7a52d00000000,0x3e611015b2bf9c58}, + {0x3ff7a94650000000,0x3e474ac54d1863af}, + {0x3ff7ad6050000000,0x3e497368feffcded}, + {0x3ff7b17b00000000,0x3e62ed9fb520a254}, + {0x3ff7b59670000000,0x3e578837bd6dff0e}, + {0x3ff7b9b290000000,0x3e611f73d8125e06}, + {0x3ff7bdcf70000000,0x3e39f6bd773f96ab}, + {0x3ff7c1ed00000000,0x3e330c1327c49334}, + {0x3ff7c60b40000000,0x3e5d8d73e3ed8441}, + {0x3ff7ca2a40000000,0x3e515b9e8ada3c5e}, + {0x3ff7ce49f0000000,0x3e60561e48a513a0}, + {0x3ff7d26a60000000,0x3e47fc378237bb7f}, + {0x3ff7d68b80000000,0x3e53d01fdf487d4e}, + {0x3ff7daad50000000,0x3e6c50a157d98b5e}, + {0x3ff7decfe0000000,0x3e6d7849fc7c6314}, + {0x3ff7e2f330000000,0x3e5b3d398841740b}, + {0x3ff7e71730000000,0x3e5a066f35113fae}, + {0x3ff7eb3be0000000,0x3e6be5c3728d497f}, + {0x3ff7ef6150000000,0x3e6a85f448086ff4}, + {0x3ff7f38780000000,0x3e524712437c0772}, + {0x3ff7f7ae60000000,0x3e4ff9304d18d508}, + {0x3ff7fbd5f0000000,0x3e6756123ef7d252}, + {0x3ff7fffe40000000,0x3e676abbd7d2f855}, + {0x3ff8042750000000,0x3e50f86846d8379a}, + {0x3ff8085110000000,0x3e5594e2f7aec9b5}, + {0x3ff80c7b80000000,0x3e6e9575519460f3}, + {0x3ff810a6c0000000,0x3e407530b5e82748}, + {0x3ff814d2a0000000,0x3e6ba20db2a321b8}, + {0x3ff818ff50000000,0x3e458f72816b93f9}, + {0x3ff81d2cb0000000,0x3e2a2e6d40a11129}, + {0x3ff8215ac0000000,0x3e609f654b2440ef}, + {0x3ff8258990000000,0x3e62999c25159f11}, + {0x3ff829b920000000,0x3e4f476a94c3b42e}, + {0x3ff82de960000000,0x3e60887b349de0b3}, + {0x3ff8321a60000000,0x3e59fbc6c88fae0d}, + {0x3ff8364c10000000,0x3e6d7283eeccdcd2}, + {0x3ff83a7e90000000,0x3e3136c5d368690a}, + {0x3ff83eb1b0000000,0x3e6b5b68dafa4598}, + {0x3ff842e5a0000000,0x3e52a18d2790615b}, + {0x3ff8471a40000000,0x3e588f1eb3394bdb}, + {0x3ff84b4fa0000000,0x3e4201af528180fd}, + {0x3ff84f85b0000000,0x3e623c0fe2500a49}, + {0x3ff853bc80000000,0x3e65bb3a976da0fd}, + {0x3ff857f410000000,0x3e5e7d6c83e458b7}, + {0x3ff85c2c50000000,0x3e6f07586affce83}, + {0x3ff8606560000000,0x3e4558076350a430}, + {0x3ff8649f20000000,0x3e335cf485d8c6ab}, + {0x3ff868d990000000,0x3e668925d901c83b}, + {0x3ff86d14d0000000,0x3e2ef9a3aea17d5b}, + {0x3ff87150c0000000,0x3e43802612797726}, + {0x3ff8758d60000000,0x3e6f9b8ccb257bb8}, + {0x3ff879cad0000000,0x3e6263486c574b5f}, + {0x3ff87e08f0000000,0x3e6d786c10d161fb}, + {0x3ff88247e0000000,0x3e21c32adec2a736}, + {0x3ff8868770000000,0x3e6d8fe287b05664}, + {0x3ff88ac7d0000000,0x3e6314cd32cca618}, + {0x3ff88f08f0000000,0x3e2ec4f968c07787}, + {0x3ff8934ac0000000,0x3e54afa3dd98181a}, + {0x3ff8978d50000000,0x3e59318f9be76c1f}, + {0x3ff89bd0a0000000,0x3e51e1603dd53954}, + {0x3ff8a014a0000000,0x3e6fa11527106770}, + {0x3ff8a45970000000,0x3e60eb8c8834a11b}, + {0x3ff8a89ef0000000,0x3e6d11b7428ee199}, + {0x3ff8ace540000000,0x3e415506dadd3e2b}, + {0x3ff8b12c40000000,0x3e4bdf8e9e7de4b7}, + {0x3ff8b57400000000,0x3e44ed80f22e1327}, + {0x3ff8b9bc70000000,0x3e6f6186030bb8b5}, + {0x3ff8be05b0000000,0x3e65ac2ef0f65af8}, + {0x3ff8c24fb0000000,0x3e50ba80ccc3d13f}, + {0x3ff8c69a60000000,0x3e67b6ab2f9fa4d4}, + {0x3ff8cae5e0000000,0x3e3fd35c39b3fded}, + {0x3ff8cf3210000000,0x3e5ad5122fbcaa87}, + {0x3ff8d37f00000000,0x3e644916fe7b83bf}, + {0x3ff8d7ccb0000000,0x3e68d833cc1adaa9}, + {0x3ff8dc1b20000000,0x3e6b5a0987ede14f}, + {0x3ff8e06a50000000,0x3e6c10cdb14775ad}, + {0x3ff8e4ba40000000,0x3e6b3ec14198c36a}, + {0x3ff8e90af0000000,0x3e692630ae6e9315}, + {0x3ff8ed5c60000000,0x3e660973eb6ef1a3}, + {0x3ff8f1ae90000000,0x3e622aee6c57304f}, + {0x3ff8f60180000000,0x3e5b9a1e4df479b3}, + {0x3ff8fa5530000000,0x3e5264a12a7ea491}, + {0x3ff8fea9a0000000,0x3e4274e2dc840895}, + {0x3ff902fed0000000,0x3e0416452b25950c}, + {0x3ff90754b0000000,0x3e6c8e4ec001cb92}, + {0x3ff90bab60000000,0x3e6999c25752e4a7}, + {0x3ff91002d0000000,0x3e67b56806e51659}, + {0x3ff9145b00000000,0x3e6723ff8b114c37}, + {0x3ff918b3f0000000,0x3e68285432454643}, + {0x3ff91d0da0000000,0x3e6b053cdf050f94}, + {0x3ff9216810000000,0x3e6ffd9c09eccdf0}, + {0x3ff925c350000000,0x3e4d517f0ecbaa06}, + {0x3ff92a1f40000000,0x3e614c81b72a93a7}, + {0x3ff92e7bf0000000,0x3e6e29072b4697f5}, + {0x3ff932d970000000,0x3e5c5a020a3934ea}, + {0x3ff93737b0000000,0x3e29b8bc9e8a0388}, + {0x3ff93b96a0000000,0x3e68b7cfa110f744}, + {0x3ff93ff660000000,0x3e63c500562a76ed}, + {0x3ff94456e0000000,0x3e63065d5afd19b3}, + {0x3ff948b820000000,0x3e66bf31c988f0a6}, + {0x3ff94d1a20000000,0x3e6f32d4660b7068}, + {0x3ff9517cf0000000,0x3e59494f420a2fbb}, + {0x3ff955e070000000,0x3e6f5819993f7097}, + {0x3ff95a44c0000000,0x3e6790a41dd36907}, + {0x3ff95ea9d0000000,0x3e6591ccb0300890}, + {0x3ff9630fa0000000,0x3e699f2486217d82}, + {0x3ff9677640000000,0x3e3fe2445ec42850}, + {0x3ff96bdd90000000,0x3e64ece165f22d35}, + {0x3ff97045b0000000,0x3e596946e6ffe201}, + {0x3ff974ae90000000,0x3e572e9da0205d3d}, + {0x3ff9791830000000,0x3e61d8af55b6f7e9}, + {0x3ff97d8290000000,0x3e6fbc9c9f173d24}, + {0x3ff981edc0000000,0x3e6586fa096c5211}, + {0x3ff98659b0000000,0x3e637bb6b693cd70}, + {0x3ff98ac660000000,0x3e69decd8f17c2f2}, + {0x3ff98f33e0000000,0x3e51e88a8872af6b}, + {0x3ff993a220000000,0x3e2003051fbb1575}, + {0x3ff9981120000000,0x3e3235680979fd56}, + {0x3ff99c80e0000000,0x3e5a17cad2fac24b}, + {0x3ff9a0f170000000,0x3e2940f737462137}, + {0x3ff9a562c0000000,0x3df1b66d49eb4e60}, + {0x3ff9a9d4d0000000,0x3e51fc965eb29f67}, + {0x3ff9ae47a0000000,0x3e6c6903d94d6af5}, + {0x3ff9b2bb40000000,0x3e6aa7fc19113d8e}, + {0x3ff9b72fb0000000,0x3e3ffd285360d19d}, + {0x3ff9bba4d0000000,0x3e68b47ba659b245}, + {0x3ff9c01ac0000000,0x3e690b08c5189217}, + {0x3ff9c49180000000,0x3e451f8480e3e236}, + {0x3ff9c908f0000000,0x3e6dafa554ac0a01}, + {0x3ff9cd8140000000,0x3e34380f269af45d}, + {0x3ff9d1fa40000000,0x3e6412af3a90ebc6}, + {0x3ff9d67410000000,0x3e629771a9574a0b}, + {0x3ff9daeea0000000,0x3e6e5a19703a5548}, + {0x3ff9df6a00000000,0x3e679f82bc002979}, + {0x3ff9e3e620000000,0x3e6eac95a9327acd}, + {0x3ff9e86310000000,0x3e63c64646304995}, + {0x3ff9ece0c0000000,0x3e673194953ff1ff}, + {0x3ff9f15f40000000,0x3e5267191d432f73}, + {0x3ff9f5de80000000,0x3e54228c4543db09}, + {0x3ff9fa5e80000000,0x3e6a0fe53bad58c5}, + {0x3ff9fedf50000000,0x3e697499c063712f}, + {0x3ffa0360f0000000,0x3e51093f2b55b910}, + {0x3ffa07e350000000,0x3e4e14fa83161aa3}, + {0x3ffa0c6670000000,0x3e66bbcac96535b5}, + {0x3ffa10ea60000000,0x3e666da3fbc07aac}, + {0x3ffa156f20000000,0x3e4b80d8aa9ff964}, + {0x3ffa19f4a0000000,0x3e50b1f2a3385567}, + {0x3ffa1e7ae0000000,0x3e6b1d7176e330c7}, + {0x3ffa2301f0000000,0x3e6f732ead9f6b29}, + {0x3ffa2789d0000000,0x3e659fcd17e61d0e}, + {0x3ffa2c1270000000,0x3e6de8f4e8d68e18}, + {0x3ffa309be0000000,0x3e68945a66b182e4}, + {0x3ffa352620000000,0x3e479ef7b3c44996}, + {0x3ffa39b120000000,0x3e48a3afb98360ad}, + {0x3ffa3e3ce0000000,0x3e699dbcf7368393}, + {0x3ffa42c980000000,0x3e1182b5e5587fa7}, + {0x3ffa4756d0000000,0x3e6b39e6db92921c}, + {0x3ffa4be500000000,0x3e53da5ac2f1acb5}, + {0x3ffa5073f0000000,0x3e59d7e48f70d8fc}, + {0x3ffa5503b0000000,0x3e41f12ae45a1225}, + {0x3ffa599430000000,0x3e60e458065d60f0}, + {0x3ffa5e2580000000,0x3e626a47a8777233}, + {0x3ffa62b7a0000000,0x3e52a8a685159fd3}, + {0x3ffa674a80000000,0x3e65e8c0a4150f56}, + {0x3ffa6bde30000000,0x3e686de1cb077789}, + {0x3ffa7072b0000000,0x3e612a14e5e39328}, + {0x3ffa750800000000,0x3e08f1157607fc1c}, + {0x3ffa799e10000000,0x3e49859ac3796fd9}, + {0x3ffa7e34f0000000,0x3e3b4bf61ebd85e7}, + {0x3ffa82cc90000000,0x3e67c29b94abbc34}, + {0x3ffa876510000000,0x3e3d9ac32335bd49}, + {0x3ffa8bfe50000000,0x3e4e0972c560f30a}, + {0x3ffa909860000000,0x3e3bb2e1c9934455}, + {0x3ffa953330000000,0x3e67d616fb295ca7}, + {0x3ffa99cee0000000,0x3e43a164e84c7b13}, + {0x3ffa9e6b50000000,0x3e55e7f6fd0fac91}, + {0x3ffaa30890000000,0x3e547fc53204d0b8}, + {0x3ffaa7a6a0000000,0x3e3897fd200b92f6}, + {0x3ffaac4570000000,0x3e65b4500628a2d1}, + {0x3ffab0e520000000,0x3e3356eba313863b}, + {0x3ffab58590000000,0x3e52fb7be80463ea}, + {0x3ffaba26d0000000,0x3e566827b9cd1ec4}, + {0x3ffabec8e0000000,0x3e4f54376e716370}, + {0x3ffac36bb0000000,0x3e6fa7e6f381b72d}, + {0x3ffac80f60000000,0x3e62f3e680e9bd30}, + {0x3ffaccb3e0000000,0x3e300301da02be90}, + {0x3ffad15920000000,0x3e5a29686e5d3a12}, + {0x3ffad5ff30000000,0x3e64784ee8bf79de}, + {0x3ffadaa610000000,0x3e6872a92584bf8c}, + {0x3ffadf4dc0000000,0x3e694b4826bc8fd5}, + {0x3ffae3f640000000,0x3e6749bd8b77288a}, + {0x3ffae89f90000000,0x3e62b5a75abd0e6a}, + {0x3ffaed49b0000000,0x3e57ad600b6b2eb3}, + {0x3ffaf1f4a0000000,0x3e37a4734e6ea06b}, + {0x3ffaf6a050000000,0x3e685705d2dfd931}, + {0x3ffafb4ce0000000,0x3e588bcbfab4d03f}, + {0x3ffafffa30000000,0x3e6f090b1868f73d}, + {0x3ffb04a860000000,0x3e60e85dc81c1a02}, + {0x3ffb095760000000,0x3e315e993c924619}, + {0x3ffb0e0720000000,0x3e631b6ccb210856}, + {0x3ffb12b7c0000000,0x3e3ff9c613f38c66}, + {0x3ffb176920000000,0x3e651f519aeb18b0}, + {0x3ffb1c1b60000000,0x3e4b0f79857153db}, + {0x3ffb20ce60000000,0x3e693512a4a6e812}, + {0x3ffb258240000000,0x3e59765cef540bcc}, + {0x3ffb2a36f0000000,0x3e29e7e737abc6fa}, + {0x3ffb2eec60000000,0x3e68275bb98fbbf9}, + {0x3ffb33a2b0000000,0x3e609e2bf5ed7fa2}, + {0x3ffb3859d0000000,0x3e5696c2c2a5ac9c}, + {0x3ffb3d11c0000000,0x3e50eef586cb9828}, + {0x3ffb41ca80000000,0x3e50d606e9c1e858}, + {0x3ffb468410000000,0x3e56dd26c3822708}, + {0x3ffb4b3e70000000,0x3e61cacf0b732bf5}, + {0x3ffb4ff9a0000000,0x3e6bc8678b02e839}, + {0x3ffb54b5b0000000,0x3e5360352692d162}, + {0x3ffb597280000000,0x3e6bcab2731c7102}, + {0x3ffb5e3030000000,0x3e626106177df6a4}, + {0x3ffb62eeb0000000,0x3e5b77f21b9820df}, + {0x3ffb67ae00000000,0x3e5c48f70be28e76}, + {0x3ffb6c6e20000000,0x3e63e38a5495479b}, + {0x3ffb712f10000000,0x3e6f422ef54df4cd}, + {0x3ffb75f0e0000000,0x3e60897f8cd0dcf0}, + {0x3ffb7ab380000000,0x3e50053dd64a1d0e}, + {0x3ffb7f76f0000000,0x3e47daf237553d84}, + {0x3ffb843b30000000,0x3e555e29444569f7}, + {0x3ffb890040000000,0x3e6674f007379e66}, + {0x3ffb8dc630000000,0x3e532348a0b61f79}, + {0x3ffb928cf0000000,0x3e413a4f1c91bd35}, + {0x3ffb975480000000,0x3e4bd4b5b6be91ce}, + {0x3ffb9c1ce0000000,0x3e61ceed00d1983d}, + {0x3ffba0e620000000,0x3e44956be9345fb8}, + {0x3ffba5b030000000,0x3e2420c930819679}, + {0x3ffbaa7b10000000,0x3e49ba8f15058656}, + {0x3ffbaf46c0000000,0x3e64f4cf4ec68ce2}, + {0x3ffbb41350000000,0x3e5a3c956654f396}, + {0x3ffbb8e0b0000000,0x3e5e69bc7bf82b4c}, + {0x3ffbbdaee0000000,0x3e6b825f04fd8ba5}, + {0x3ffbc27df0000000,0x3e6250aeea5bd62f}, + {0x3ffbc74dd0000000,0x3e63e9bc9ee6b295}, + {0x3ffbcc1e90000000,0x3e12f074891ee83d}, + {0x3ffbd0f010000000,0x3e68a40c4f414c6b}, + {0x3ffbd5c270000000,0x3e6c596bc9db4757}, + {0x3ffbda95b0000000,0x3e5803882b51d09b}, + {0x3ffbdf69c0000000,0x3e4f9d1037f1ecee}, + {0x3ffbe43ea0000000,0x3e6054276a22db24}, + {0x3ffbe91460000000,0x3e464adafe7861a8}, + {0x3ffbedeaf0000000,0x3e4fb51e1182080f}, + {0x3ffbf2c250000000,0x3e67ae3c110811ae}, + {0x3ffbf79a90000000,0x3e652003a31a3b2b}, + {0x3ffbfc73b0000000,0x3e11a34be803d426}, + {0x3ffc014d90000000,0x3e6a400953831e27}, + {0x3ffc062860000000,0x3e341b33cc4eb4ac}, + {0x3ffc0b03f0000000,0x3e69a1d4b8d57ba8}, + {0x3ffc0fe060000000,0x3e6fe603e8ff9783}, + {0x3ffc14bdb0000000,0x3e659ab0d3f82daf}, + {0x3ffc199bd0000000,0x3e6b0aa538444196}, + {0x3ffc1e7ad0000000,0x3e6080b7cb3cc0a0}, + {0x3ffc235aa0000000,0x3e6647cc3b4dcff1}, + {0x3ffc283b50000000,0x3e5955a6646cfbc7}, + {0x3ffc2d1cd0000000,0x3e63f4ca5748d74f}, + {0x3ffc31ff30000000,0x3e58e178a354c157}, + {0x3ffc36e260000000,0x3e6669c0ca94f31f}, + {0x3ffc3bc670000000,0x3e622afc6f97fd8f}, + {0x3ffc40ab50000000,0x3e6fffa0f4da29bf}, + {0x3ffc459120000000,0x3df9768badb2c9a1}, + {0x3ffc4a77b0000000,0x3e63102c9f375085}, + {0x3ffc4f5f20000000,0x3e68e2b861e80d5a}, + {0x3ffc544770000000,0x3e61f5f644897839}, + {0x3ffc593090000000,0x3e6e95593e1cc11a}, + {0x3ffc5e1a90000000,0x3e6f0c6159cc6aba}, + {0x3ffc630570000000,0x3e63a69bb930ae13}, + {0x3ffc67f120000000,0x3e6cafa296944270}, + {0x3ffc6cddb0000000,0x3e6a731d47398a32}, + {0x3ffc71cb20000000,0x3e5a79807b40489a}, + {0x3ffc76b960000000,0x3e65584d0bcae29c}, + {0x3ffc7ba880000000,0x3e63119265862511}, + {0x3ffc809880000000,0x3e4ad1b08aba6763}, + {0x3ffc858950000000,0x3e608cc341786286}, + {0x3ffc8a7b00000000,0x3e60e68de8b69e50}, + {0x3ffc8f6d90000000,0x3e501b9ed446b2f1}, + {0x3ffc9460f0000000,0x3e664e9844a7e1ec}, + {0x3ffc995530000000,0x3e6bf50626a5812b}, + {0x3ffc9e4a50000000,0x3e694d43f03e9b90}, + {0x3ffca34050000000,0x3e5d47136b406a09}, + {0x3ffca83720000000,0x3e6c441cc14bdb33}, + {0x3ffcad2ee0000000,0x3e33da7cb30faa43}, + {0x3ffcb22770000000,0x3e29581f2ec795fe}, + {0x3ffcb720d0000000,0x3e69df20d22a0798}, + {0x3ffcbc1b20000000,0x3e57494cddb2d5e6}, + {0x3ffcc11640000000,0x3e67329a45858012}, + {0x3ffcc61240000000,0x3e6cd59116d181d1}, + {0x3ffccb0f20000000,0x3e6cda2ce9c5bbe1}, + {0x3ffcd00ce0000000,0x3e678d1d0e1ca374}, + {0x3ffcd50b80000000,0x3e5a763c3d20abfc}, + {0x3ffcda0af0000000,0x3e6e30fa03287e2a}, + {0x3ffcdf0b50000000,0x3e55770fe7113e25}, + {0x3ffce40c80000000,0x3e6327ac793ec5c8}, + {0x3ffce90e90000000,0x3e67c2597212a140}, + {0x3ffcee1180000000,0x3e68d88e125500bb}, + {0x3ffcf31550000000,0x3e66b756e72fb8b2}, + {0x3ffcf81a00000000,0x3e61abcdd8f5ee5b}, + {0x3ffcfd1f90000000,0x3e5406345ae993bd}, + {0x3ffd022600000000,0x3dd4e114891e8f2d}, + {0x3ffd072d40000000,0x3e640f12f71a1e46}, + {0x3ffd0c3570000000,0x3e49794380636337}, + {0x3ffd113e70000000,0x3e6745871824f0af}, + {0x3ffd164860000000,0x3e4c487f6cd870b2}, + {0x3ffd1b5320000000,0x3e661192d0aab1b1}, + {0x3ffd205ed0000000,0x3e424594366caa9a}, + {0x3ffd256b50000000,0x3e62df29172e0d8b}, + {0x3ffd2a78c0000000,0x3e2487ee4ec3f51f}, + {0x3ffd2f8700000000,0x3e601b13e315bc24}, + {0x3ffd349620000000,0x3e6fa4a2f4f6b790}, + {0x3ffd39a630000000,0x3e6032f4773d243a}, + {0x3ffd3eb720000000,0x3e309ef212751927}, + {0x3ffd43c8e0000000,0x3e659543ac9eda9e}, + {0x3ffd48db90000000,0x3e560a2b1a0c69c4}, + {0x3ffd4def20000000,0x3e358a91e8c83466}, + {0x3ffd530380000000,0x3e6ce8059b7f1ce2}, + {0x3ffd5818d0000000,0x3e69f7490e4bb40b}, + {0x3ffd5d2f00000000,0x3e6a2d438555d54c}, + {0x3ffd624610000000,0x3e6dd8297c911d51}, + {0x3ffd675e10000000,0x3e4518f3f99baa82}, + {0x3ffd6c76e0000000,0x3e60c5cda60ff43d}, + {0x3ffd7190a0000000,0x3e14a7143dc91304}, + {0x3ffd76ab30000000,0x3e6532e8b5e7b4d8}, + {0x3ffd7bc6b0000000,0x3e5d7aac7b812921}, + {0x3ffd80e310000000,0x3e5b260e5eee13e7}, + {0x3ffd860050000000,0x3e62028f1d9e9e99}, + {0x3ffd8b1e70000000,0x3e6c5a8f39bc4ce4}, + {0x3ffd903d80000000,0x3e59d36cad45e444}, + {0x3ffd955d70000000,0x3e3ff60756814b6f}, + {0x3ffd9a7e40000000,0x3e2e87912c98f6cd}, + {0x3ffd9f9ff0000000,0x3e4bd6da4de9bbdc}, + {0x3ffda4c280000000,0x3e63755edc91d6be}, + {0x3ffda9e600000000,0x3e4ed9942b84600d}, + {0x3ffdaf0a60000000,0x3e401f27aaeab9c4}, + {0x3ffdb42fa0000000,0x3e517137f4a3224c}, + {0x3ffdb955c0000000,0x3e6617f76c18ed08}, + {0x3ffdbe7cd0000000,0x3e58ea0c524890e7}, + {0x3ffdc3a4c0000000,0x3e583dffa710209a}, + {0x3ffdc8cd90000000,0x3e656529c8ba8e9a}, + {0x3ffdcdf750000000,0x3e512dae47ea9547}, + {0x3ffdd321f0000000,0x3e480da3025b4aef}, + {0x3ffdd84d70000000,0x3e5bf49a7909df72}, + {0x3ffddd79e0000000,0x3e19601f51e84699}, + {0x3ffde2a720000000,0x3e6ec50e24d249a7}, + {0x3ffde7d560000000,0x3e5070195e35aad7}, + {0x3ffded0470000000,0x3e6d73a25949dfc1}, + {0x3ffdf23470000000,0x3e6ec782b1b8d2de}, + {0x3ffdf76560000000,0x3e5906de2f3c704f}, + {0x3ffdfc9730000000,0x3e4bdcdaf5cb4656}, + {0x3ffe01c9e0000000,0x3e5ce56d56ae3acf}, + {0x3ffe06fd80000000,0x3e3a2ece0bca216e}, + {0x3ffe0c3200000000,0x3e470262e9edc4fb}, + {0x3ffe116760000000,0x3e6632fa2dda95ad}, + {0x3ffe169db0000000,0x3e64ed12925595cb}, + {0x3ffe1bd4f0000000,0x3e31f82202a70ab7}, + {0x3ffe210d00000000,0x3e6e78ff74527658}, + {0x3ffe264610000000,0x3e53d684a2849d88}, + {0x3ffe2b8000000000,0x3e4398638bece417}, + {0x3ffe30bad0000000,0x3e5f73ba414036d2}, + {0x3ffe35f690000000,0x3e556dedde134517}, + {0x3ffe3b3330000000,0x3e662ddc23305ade}, + {0x3ffe4070c0000000,0x3e626f108497354f}, + {0x3ffe45af30000000,0x3e6fcb25cfb67724}, + {0x3ffe4aee90000000,0x3e6e92bbb8671525}, + {0x3ffe502ee0000000,0x3e5e2cffd89cf44c}, + {0x3ffe557010000000,0x3e61a72e154ab8f5}, + {0x3ffe5ab230000000,0x3e4a563f6f7ca75c}, + {0x3ffe5ff530000000,0x3e5c64f9d342e723}, + {0x3ffe653920000000,0x3e519db5d74e003c}, + {0x3ffe6a7df0000000,0x3e66bb9d94f2dd19}, + {0x3ffe6fc3b0000000,0x3e6849c6a0e407f8}, + {0x3ffe750a60000000,0x3e5b94cbab484c52}, + {0x3ffe7a51f0000000,0x3e678e990696a916}, + {0x3ffe7f9a70000000,0x3e65e78c16c85e3d}, + {0x3ffe84e3e0000000,0x3e524cf1f6bed6a6}, + {0x3ffe8a2e30000000,0x3e619ca7be0bb695}, + {0x3ffe8f7970000000,0x3e5f36dcfeef76b8}, + {0x3ffe94c5a0000000,0x3e3ba18bcdce57ae}, + {0x3ffe9a12b0000000,0x3e5af0c6058b73d4}, + {0x3ffe9f60b0000000,0x3e5bf3071dbdf35d}, + {0x3ffea4afa0000000,0x3e452486cc2c7b9d}, + {0x3ffea9ff70000000,0x3e63b8da2784d43f}, + {0x3ffeaf5030000000,0x3e699a57ca2f39ed}, + {0x3ffeb4a1e0000000,0x3e673f53a109b201}, + {0x3ffeb9f480000000,0x3e59f329b94832f2}, + {0x3ffebf4800000000,0x3e6b1af0da936e48}, + {0x3ffec49c80000000,0x3e2f54b27e6e24e0}, + {0x3ffec9f1e0000000,0x3e2da95839d5b5cf}, + {0x3ffecf4820000000,0x3e6b1ccfe11b6062}, + {0x3ffed49f60000000,0x3e5c1c10d542e779}, + {0x3ffed9f780000000,0x3e6b005b83c2dad8}, + {0x3ffedf50a0000000,0x3e322f9e5ee6991b}, + {0x3ffee4aaa0000000,0x3e40c4288238d1b5}, + {0x3ffeea0590000000,0x3e213e5a02f80c27}, + {0x3ffeef6160000000,0x3e6940dbac4b61db}, + {0x3ffef4be30000000,0x3e5a149fd82f2852}, + {0x3ffefa1be0000000,0x3e6cc2b44eee3fa4}, + {0x3ffeff7a90000000,0x3e5179121d8f7cad}, + {0x3fff04da20000000,0x3e614a5cb2b4d0cd}, + {0x3fff0a3aa0000000,0x3e66becc11594075}, + {0x3fff0f9c10000000,0x3e696c825366effd}, + {0x3fff14fe70000000,0x3e69a638f61959c8}, + {0x3fff1a61c0000000,0x3e67beb7cdb17c92}, + {0x3fff1fc600000000,0x3e6408d507f23646}, + {0x3fff252b30000000,0x3e5daeea5d3a1a5c}, + {0x3fff2a9150000000,0x3e50fb1653decef4}, + {0x3fff2ff860000000,0x3e24e18432031477}, + {0x3fff356050000000,0x3e699c2c26ddf128}, + {0x3fff3ac940000000,0x3e61bae4e7cd4b4c}, + {0x3fff403320000000,0x3e53fade020fe6a5}, + {0x3fff459df0000000,0x3e35b82ac4e06739}, + {0x3fff4b09a0000000,0x3e6c3af1420bfb2b}, + {0x3fff507650000000,0x3e66dc8a80ce9f09}, + {0x3fff55e3f0000000,0x3e62ef374ad0048c}, + {0x3fff5b5280000000,0x3e60c66c4af27f39}, + {0x3fff60c200000000,0x3e60b5aca3903595}, + {0x3fff663270000000,0x3e631089f0fd1bda}, + {0x3fff6ba3d0000000,0x3e682aa44c095dfb}, + {0x3fff711630000000,0x3e05ea93210e3f4b}, + {0x3fff768970000000,0x3e57d6b2177e878d}, + {0x3fff7bfda0000000,0x3e6b397c27122769}, + {0x3fff8172d0000000,0x3e5d2bdb84bd8e17}, + {0x3fff86e8f0000000,0x3e49525a2a575dcb}, + {0x3fff8c6000000000,0x3e364b6dc1df327b}, + {0x3fff91d800000000,0x3e4121e447bb455d}, + {0x3fff9750f0000000,0x3e564b99ddd75a89}, + {0x3fff9ccad0000000,0x3e67b58c39951cc8}, + {0x3fffa245b0000000,0x3e5497d0e3f42f1a}, + {0x3fffa7c180000000,0x3e39e90d82e90a7e}, + {0x3fffad3e40000000,0x3e36ec353ddf898f}, + {0x3fffb2bbf0000000,0x3e5302e950af1290}, + {0x3fffb83a90000000,0x3e677d57a23cbe87}, + {0x3fffbdba30000000,0x3e5a4b544f9a6234}, + {0x3fffc33ac0000000,0x3e559deae0916a68}, + {0x3fffc8bc40000000,0x3e60cdd15a572c7c}, + {0x3fffce3eb0000000,0x3e6f76e46e92d018}, + {0x3fffd3c220000000,0x3e671ee3e212eb75}, + {0x3fffd94680000000,0x3e681a9398f707d7}, + {0x3fffdecbe0000000,0x3e35f631479446b3}, + {0x3fffe45220000000,0x3e67605cdbd8b9bf}, + {0x3fffe9d960000000,0x3e665447b2294c07}, + {0x3fffef6190000000,0x3e6fef85659d46d9}, + {0x3ffff4eac0000000,0x3e6487236bb467cf}, + {0x3ffffa74e0000000,0x3e64703df842f4ee}, + {0x4000000000000000,0x0}, +}; diff --git a/src/native/clrmath/src/opt/powf.cpp b/src/native/clrmath/src/opt/powf.cpp new file mode 100644 index 00000000000000..6165336573137f --- /dev/null +++ b/src/native/clrmath/src/opt/powf.cpp @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + /* + * Contains implementation of powf() + * Prototype : + * float powf(float x, float y) + * + * Algorithm + * x^y = e^(y*ln(x)) + * + * Look in exp, log for the respective algorithms + * + + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_typehelper.h" + +#define N 8 +#define TABLE_SIZE (1ULL << N) +#define MAX_POLYDEGREE 8 + +extern "C" uint64_t log_256[]; + +#if N == 8 +#define POLY_DEGREE 4 +extern "C" const uint64_t log_table_256[]; +extern "C" const uint64_t log_f_inv_256[]; +#define TAB_F_INV log_f_inv_256 +#define TAB_LOG log_table_256 +#define MANT_MASK_N (0x000FF00000000000ULL) +#define MANT_MASK_N1 (0x0000080000000000ULL) +#elif N == 9 +#define POLY_DEGREE 5 +extern "C" double log_table_512[]; +extern "C" double log_f_inv_512[]; + +#elif N == 10 +#define POLY_DEGREE 4 +extern "C" double log_table_1024[]; +extern "C" double log_f_inv_1024[]; +#define TAB_F_INV log_f_inv_1024 +#define TAB_LOG log_table_1024 +#define MANT_MASK_N (0x000FFC0000000000ULL) +#define MANT_MASK_N1 (0x0000020000000000ULL) +#endif + +#define MANT_BITS_MASK (TABLE_SIZE - 1) +#define MANT1_BITS_MASK (1ULL << (N + 1)) + +#define EXPF_N 6 +#define EXPF_POLY_DEGREE 4 +#if EXPF_N == 5 +#define EXPF_POLY_DEGREE 3 +#elif EXPF_N == 4 +#define EXPF_POLY_DEGREE 3 +#endif + +#define EXPF_TABLE_SIZE (1 << EXPF_N) +#define EXPF_MAX_POLY_DEGREE 4 + +struct log_data_t { + double ALIGN(16) poly[MAX_POLYDEGREE]; + double_t ln2_lead, ln2_tail; +}; + +#if N == 8 +#endif + +static const log_data_t log_data = { + /* + * Polynomial constants, 1/x! (reciprocal x) + * To make better use of cache line, + * we dont store 0! and 1! + */ + /* .poly = */ { /* skip for 0/1 and 1/1 */ + 0x1.0000000000000p-1, /* 1/2 */ + 0x1.5555555555555p-2, /* 1/3 */ + 0x1.0000000000000p-2, /* 1/4 */ + 0x1.999999999999ap-3, /* 1/5 */ + 0x1.5555555555555p-3, /* 1/6 */ + 0x1.2492492492492p-3, /* 1/7 */ + 0x1.0000000000000p-3, /* 1/8 */ + 0x1.c71c71c71c71cp-4, /* 1/9 */ + }, + + // .ln2 = 0x1.62e42fefa39efp-1; /* ln(2) */ + + /* .ln2_lead = */ 0x1.62e42e0000000p-1, + /* .ln2_tail = */ 0x1.efa39ef35793cp-25, +}; + +#define C2 log_data.poly[0] +#define C3 log_data.poly[1] +#define C4 log_data.poly[2] +#define C5 log_data.poly[3] +#define C6 log_data.poly[4] +#define C7 log_data.poly[5] +#define C8 log_data.poly[6] +#define LN2_LEAD log_data.ln2_lead +#define LN2_TAIL log_data.ln2_tail +#define SIGN_BIAS 0x8000000000000000 + +#include "expf_data.h" + +static const expf_data expf_v2_data = { + /* .tblsz_byln2 = */ 0x1.71547652b82fep+6, + /* .Huge = */ 0x1.8000000000000p+52, + /* .ln2by_tblsz = */ 0x1.62e42fefa39efp-7, + /* .poly = */ { + 1.0, /* 1/1! = 1 */ + 0x1.0000000000000p-1, /* 1/2! = 1/2 */ + 0x1.5555555555555p-3, /* 1/3! = 1/6 */ + 0x1.cacccaa4ba57cp-5, /* 1/4! = 1/24 */ + }, +#if EXPF_N == 6 + /* .table_v3 = */ &__two_to_jby64[0], +#elif EXPF_N == 5 + /* .table_v3 = */ &__two_to_jby32[0], +#endif +}; + +#define D1 expf_v2_data.poly[0] +#define D2 expf_v2_data.poly[1] +#define D3 expf_v2_data.poly[2] +#define D4 expf_v2_data.poly[3] + +#define EXPF_LN2_BY_TBLSZ expf_v2_data.ln2by_tblsz +#define EXPF_TBLSZ_BY_LN2 expf_v2_data.tblsz_byln2 +#define EXPF_HUGE expf_v2_data.Huge +#define EXPF_TABLE expf_v2_data.table + +#define EXPF_FARG_MIN -0x1.9fe368p6f /* log(0x1p-150) ~= -103.97 */ +#define EXPF_FARG_MAX 0x1.62e42ep6f /* log(0x1p128) ~= 88.72 */ +#define Ln2 0x1.62e42fefa39efp-1 +#define EXP_Y_INF 3 +#define EXP_Y_ZERO 2 + +struct log_table { + double lead, tail; +}; + +double _log_special(double x, double y, uint32_t code); +float _expf_special(float x, float y, uint32_t code); + +/* Returns 0 if not int, 1 if odd int, 2 if even int. The argument is + the bit representation of a non-zero finite floating-point value. */ +static inline int +checkint(uint32_t iy) +{ + int e = iy >> 23 & 0xff; + if (e < 0x7f) + return 0; + if (e > 0x7f + 23) + return 2; + if (iy & ((1 << (0x7f + 23 - e)) - 1)) + return 0; + if (iy & (1 << (0x7f + 23 - e))) + return 1; + return 2; +} + +static inline int +isSignalingNaN(float x) +{ + uint32_t ix = asuint32(x); + return 2 * (ix ^ 0x00400000) > 2u * 0x7fc00000;; +} + +static inline uint64_t top12(double x) +{ + /* 12 are the exponent bits */ + return asuint64(x) >> (64 - 12); +} + +static inline int +zeroinfnan(uint32_t ix) +{ + return 2 * ix - 1 >= 2u * 0x7f800000 - 1; +} + + +static inline double_t +calculate_log(double_t x) +{ + double_t q, r; + double_t dexpo, j_times_half; + + uint64_t ux = asuint64(x); + + int32_t expo = (ux >> 52) - 1023; + + flt64_t mant; + mant.i = ux & 0x000fffffffffffffULL; + + dexpo = (double)expo; + uint64_t mant_n = ux & MANT_MASK_N; + + /* + * Step needed for better accuracy + uint64_t mant_n1 = ux & MANT_MASK_N1; + uint64_t j = (mant_n) + (mant_n1 << 1); + */ + + uint64_t j = (mant_n); + + mant.i |= 0x3fe0000000000000ULL; /* F */ + j_times_half = asdouble(0x3fe0000000000000ULL | j); /* Y */ + + j >>= (52 - N); + + /* f = F - Y */ + double_t f = j_times_half - mant.d; + + r = f * asdouble(TAB_F_INV[j]); + + double_t r2 = r * r; /* r^2 */ + + double_t temp = C2 + r * C3; + + q = r + r2 * temp; + + /* m*log(2) + log(G) - poly */ + + temp = (dexpo * Ln2) + asdouble(log_256[j]); + + temp -= q; + + return temp; + +} + +static inline float calculate_exp(double_t x, uint64_t sign_bias) +{ + double_t q, dn, r, z; + uint64_t n, j; + + if (unlikely(top12(x) > top12(88.0))) { + + if ((float)x > EXPF_FARG_MAX) { + return _expf_special((float)x, asfloat((sign_bias >> 32) | PINFBITPATT_SP32), EXP_Y_INF); + } + + if (((float)x) < EXPF_FARG_MIN) { + return _expf_special((float)x, asfloat(sign_bias >> 32), EXP_Y_ZERO); + } + + } + + z = x * EXPF_TBLSZ_BY_LN2; + + /* + * n = (int) scale(x) + * dn = (double) n + */ +#undef FAST_INTEGER_CONVERSION +#define FAST_INTEGER_CONVERSION 1 +#if FAST_INTEGER_CONVERSION + dn = z + EXPF_HUGE; + + n = asuint64(dn); + + dn -= EXPF_HUGE; +#else + n = z; + dn = cast_i32_to_float(n); + +#endif + + r = x - dn * EXPF_LN2_BY_TBLSZ; + + j = n % EXPF_TABLE_SIZE; + + double_t qtmp = D2 + (D3 * r); + + double_t r2 = r * r; + + double_t tbl = asdouble(sign_bias | (asuint64(__two_to_jby64[j]) + (n << (52 - EXPF_N)))); + + q = r + (r2 * qtmp); + + double_t result = tbl + tbl * q; + + return (float_t)(result); + +} + +float ALM_PROTO_OPT(powf)(float x, float y) +{ + double_t logx, ylogx, result, q, r; + double_t dx; + uint32_t ux, uy; + + ux = asuint32(x); + uy = asuint32(y); + uint64_t sign_bias = 0; + + if (unlikely(ux - 0x3F880000 >= 0x7f800000 - 0x3F880000 || zeroinfnan(uy))) + { + + /* All x less than 1.0625, infinity, NaN and y = zero, infinity or NAN caught here + * x < 0x1p-126 or inf or nan. + * Either (x < 0x1p-126 or inf or nan) or (y is 0 or inf or nan). + * + */ + if (unlikely(zeroinfnan(uy))) + { + if (2 * uy == 0) + return isSignalingNaN(x) ? x + y : 1.0f; + + if (ux == 0x3f800000) + return isSignalingNaN(y) ? x + y : 1.0f; + + if (2 * ux > 2u * 0x7f800000 || 2 * uy > 2u * 0x7f800000) + return x + y; + + if (2 * ux == 2 * 0x3f800000) + return 1.0f; + + if ((2 * ux < 2 * 0x3f800000) == !(uy & 0x80000000)) + return 0.0f; /* |x|<1 && y==inf or |x|>1 && y==-inf. */ + + return y * y; + } + + if (unlikely(zeroinfnan(ux))) + { + float_t x2 = x * x; + + if (ux & 0x80000000 && checkint(uy) == 1) /* x is -0 and y is odd */ + { + x2 = -x2; + sign_bias = SIGN_BIAS; + } + + if (2 * ux == 0 && uy & 0x80000000) + { + x = INFINITY; + ux = asuint32(x); + return asfloat((sign_bias >> 32) | ux); + } + + return uy & 0x80000000 ? (1 / x2) : x2; /* if y is negative, return 1/x else return x */ + } + + /* x and y are non-zero finite */ + if (ux & 0x80000000) /* x is negative */ + { + /* Finite x < 0 */ + int yint = checkint(uy); + if (yint == 0) + return (float)FN_PROTOTYPE(sqrt)(x); + if (yint == 1) + sign_bias = SIGN_BIAS; + + ux &= 0x7fffffff; /* x is negative, y is integer */ + x = asfloat(ux); + } + + /* if 0.9375 < x < 1.0625 */ + if ((0x3F880000 - ux) < (0x3F880000 - 0x3F700000)) + { + dx = (double_t)x; + + double_t u, u2, u3, u7; + double_t A1, A2, B1, B2, R1, R2; + static const double ca[5] = { + 0x1.55555555554e6p-4, /* 1/2^2 * 3 */ + 0x1.9999999bac6d4p-7, /* 1/2^4 * 5 */ + 0x1.2492307f1519fp-9, /* 1/2^6 * 7 */ + 0x1.c8034c85dfff0p-12 /* 1/2^8 * 9 */ + }; + + /* + * Less than threshold, no table lookup + * + */ + + flt64_t one_minus_mant; + one_minus_mant.d = dx - 1.0; + + r = one_minus_mant.d; + + double_t u_by_2 = r / (2.0 + r); + + q = u_by_2 * r; /* correction */ + + u = u_by_2 + u_by_2; + +#define CA1 ca[0] +#define CA2 ca[1] +#define CA3 ca[2] +#define CA4 ca[3] + + u2 = u * u; + + A1 = CA2 * u2 + CA1; + A2 = CA4 * u2 + CA3; + + u3 = u2 * u; + B1 = u3 * A1; + + u7 = u * (u3 * u3); + B2 = u7 * A2; + + R1 = B1 + B2; + R2 = R1 - q; + + logx = r + R2; + + ylogx = y * logx; + + result = calculate_exp(ylogx, sign_bias); + + return (float)result; + + } + } + + dx = (double_t)x; + + logx = calculate_log(dx); + + ylogx = y * logx; + + result = calculate_exp(ylogx, sign_bias); + + return (float)result; +} diff --git a/src/native/clrmath/src/opt/sin.cpp b/src/native/clrmath/src/opt/sin.cpp new file mode 100644 index 00000000000000..0c8f5e65399f36 --- /dev/null +++ b/src/native/clrmath/src/opt/sin.cpp @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + /* + * ISO-IEC-10967-2: Elementary Numerical Functions + * Signature: + * double sin(double x) + * + * Spec: + * sin(0) = 0 + * sin(-0) = -0 + * sin(inf) = NaN + * sin(-inf) = NaN + * + * + ****************************************** + * Implementation Notes + * --------------------- + * + * checks for special cases + * if ( ux = infinity) raise overflow exception and return x + * if x is NaN then raise invalid FP operation exception and return x. + * + * 1. Argument reduction + * if |x| > 5e5 then + * __amd_remainder_piby2(x, &r, &rr, ®ion) + * else + * Argument reduction + * Let z = |x| * 2/pi + * z = dn + r, where dn = round(z) + * rhead = dn * pi/2_head + * rtail = dn * pi/2_tail + * r = z - dn = |x| - rhead - rtail + * expdiff = exp(dn) - exp(r) + * if(expdiff) > 15) + * rtail = |x| - dn*pi/2_tail2 + * r = |x| - dn*pi/2_head - dn*pi/2_tail1 - dn*pi/2_tail2 - (((rhead + rtail) - rhead )-rtail) + * rr = (|x| - rhead) - r + rtail + * + * 2. Polynomial approximation + * if(dn is odd) + * rr = rr * r; + * x4 = x2 * x2; + * s = 0.5 * x2; + * t = s - 1.0; + * poly = x4 * (C1 + x2 * (C2 + x2 * (C3 + x2 * (C4 + x2 * (C5 + x2 * x6))))) + * r = (((1.0 + t) - s) - rr) + poly - t + * else + * x3 = x2 * r + * poly = S2 + (r2 * (S3 + (r2 * (S4 + (r2 * (S5 + S6 * r2)))))) + * r = r - ((x2 * (0.5*rr - x3 * poly)) - rr) - S1 * x3 + * if(((sign & region) | ((~sign) & (~region))) & 1) + * return r + * else + * return -r; + + * if |x| < pi/4 && |x| > 2.0^(-13) + * sin(x) = x + (x * (r2 * (S1 + r2 * (S2 + r2 * (S3 + r2 * (S4 + r2 * (S5 + r2 * S6))))))) + * if |x| < 2.0^(-13) && |x| > 2.0^(-27) + * sin(x) = x - (x * x * x * (1/6)); + * + * + ****************************************** + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_types.h" +#include "libm/libm_typehelper.h" +#include "libm/libm_poly.h" + +struct sin_data_t { + const double twobypi, piby2_1, piby2_1tail, invpi, pi, pi1, pi2; + const double piby2_2, piby2_2tail, ALM_SHIFT; + const double one_by_six; + double poly_sin[7]; + double poly_cos[6]; +}; + +static const sin_data_t sin_data = { + /* .twobypi = */ 0x1.45f306dc9c883p-1, + /* .piby2_1 = */ 0x1.921fb54400000p0, + /* .piby2_1tail = */ 0x1.0b4611a626331p-34, + /* .invpi = */ 0x1.45f306dc9c883p-2, + /* .pi = */ 0x1.921fb54442d18p1, + /* .pi1 = */ 0x1.921fb50000000p1, + /* .pi2 = */ 0x1.110b4611a6263p-25, + /* .piby2_2 = */ 0x1.0b4611a600000p-34, + /* .piby2_2tail = */ 0x1.3198a2e037073p-69, + /* .ALM_SHIFT = */ 0x1.8p+52, + /* .one_by_six = */ 0.1666666666666666666, + + /* + * Polynomial coefficients + */ + + /* .poly_sin = */ { + -0x1.5555555555555p-3, + 0x1.1111111110bb3p-7, + -0x1.a01a019e83e5cp-13, + 0x1.71de3796cde01p-19, + -0x1.ae600b42fdfa7p-26, + 0x1.5e0b2f9a43bb8p-33 + }, + + /* .poly_cos = */ { + 0x1.5555555555555p-5, /* 0.0416667 */ + -0x1.6c16c16c16967p-10, /* -0.00138889 */ + 0x1.A01A019F4EC91p-16, /* 2.48016e-005 */ + -0x1.27E4FA17F667Bp-22, /* -2.75573e-007 */ + 0x1.1EEB690382EECp-29, /* 2.08761e-009 */ + -0x1.907DB47258AA7p-37 /* -1.13826e-011 */ + }, +}; + +void __amd_remainder_piby2(double x, double* r, double* rr, int* region); + +#define pi sin_data.pi +#define pi1 sin_data.pi1 +#define pi2 sin_data.pi2 +#define invpi sin_data.invpi +#define TwobyPI sin_data.twobypi +#define PIby2_1 sin_data.piby2_1 +#define PIby2_1tail sin_data.piby2_1tail +#define PIby2_2 sin_data.piby2_2 +#define PIby2_2tail sin_data.piby2_2tail +#define PIby4 0x3fe921fb54442d18 +#define FiveE6 0x415312d000000000 +#define ONE_BY_SIX sin_data.one_by_six +#define ALM_SHIFT sin_data.ALM_SHIFT + +#define S1 sin_data.poly_sin[0] +#define S2 sin_data.poly_sin[1] +#define S3 sin_data.poly_sin[2] +#define S4 sin_data.poly_sin[3] +#define S5 sin_data.poly_sin[4] +#define S6 sin_data.poly_sin[5] + +#define C1 sin_data.poly_cos[0] +#define C2 sin_data.poly_cos[1] +#define C3 sin_data.poly_cos[2] +#define C4 sin_data.poly_cos[3] +#define C5 sin_data.poly_cos[4] +#define C6 sin_data.poly_cos[5] + +#define SIGN_MASK 0x7FFFFFFFFFFFFFFF /* Infinity */ +#define INF 0x7ff0000000000000 +#define SIGN_MASK32 0x7FFFFFFF +#define SIN_SMALL 0x3f20000000000000 /* 2.0^(-13) */ +#define SIN_SMALLER 0X3e40000000000000 /* 2.0^(-27) */ + +float _sinf_special(float x); +double _sin_special_underflow(double x); + +double +ALM_PROTO_OPT(sin)(double x) +{ + + double r, rr, poly, x2, s; + double rhead, rtail, x3, x4; + uint64_t uy; + uint64_t sign = 0; + int32_t region; + + /* sin(inf) = sin(-inf) = sin(NaN) = NaN */ + + uint64_t ux = asuint64(x); + + sign = ux >> 63; + + ux = ux & SIGN_MASK; + + if (unlikely((ux & SIGN_MASK) >= INF)) { + /* infinity or NaN */ + return _sinf_special((float)x); + } + + if (ux > PIby4) { + + x = asdouble(ux); + /* ux > pi/4 */ + if (ux < FiveE6) { + /* reduce the argument to be in a range from -pi/4 to +pi/4 + by subtracting multiples of pi/2 */ + + r = TwobyPI * x; /* x * two_by_pi*/ + + int32_t xexp = ux >> 52; + + double npi2d = r + ALM_SHIFT; + + int64_t npi2 = asuint64(npi2d); + + npi2d -= ALM_SHIFT; + + rhead = x - npi2d * PIby2_1; + + rtail = npi2d * PIby2_1tail; + + r = rhead - rtail; + + uy = asuint64(r); + + int64_t expdiff = xexp - ((uy << 1) >> 53); + + region = (int32_t)npi2; + + if (expdiff > 15) { + + double t = rhead; + + rtail = npi2d * PIby2_2; + + rhead = t - rtail; + + rtail = npi2d * PIby2_2tail - ((t - rhead) - rtail); + + r = rhead - rtail; + } + + rr = (rhead - r) - rtail; + } + else { + // Reduce x into range [-pi/4,pi/4] + __amd_remainder_piby2(x, &r, &rr, ®ion); + } + + x2 = r * r; + + if (region & 1) { + + /*cos region */ + rr = rr * r; + + x4 = x2 * x2; + + s = 0.5 * x2; + + double t = s - 1.0; + + /* poly = x4 * (C1 + x2 * (C2 + x2 * (C3 + x2 * (C4 + x2 * (C5 + x2 * x6))))) */ + poly = x4 * POLY_EVAL_6(x2, C1, C2, C3, C4, C5, C6); + + r = (((1.0 + t) - s) - rr) + poly; + + r -= t; + } + else { + /* region 0 or 2 do a sin calculation */ + x3 = x2 * r; + + /* poly = S2 + (r2 * (S3 + (r2 * (S4 + (r2 * (S5 + S6 * r2)))))) */ + poly = POLY_EVAL_5(x2, S2, S3, S4, S5, S6); + + s = 0.5 * rr; + + poly = ((x2 * (s - x3 * poly)) - rr) - S1 * x3; + + r -= poly; /* r - ((r2 * (0.5 * rr - x3 * poly) - rr) - S1*r3 */ + } + + region >>= 1; + + if (((sign & region) | ((~sign) & (~region))) & 1) { + + return r; + + } + + return -r; + } + else if (ux >= SIN_SMALL) { + /* x > 2.0^(-13) */ + x2 = x * x; + + /* x + (x * (r2 * (S1 + r2 * (S2 + r2 * (S3 + r2 * (S4 + r2 * (S5 + r2 * S6))))))) */ + return x + (x * (x2 * POLY_EVAL_6(x2, S1, S2, S3, S4, S5, S6))); + + } + else if (ux > SIN_SMALLER) { + /* if x > 2.0^(-27) */ + return x - (x * x * x * ONE_BY_SIX); + + } + + return x; +} diff --git a/src/native/clrmath/src/opt/sinf.cpp b/src/native/clrmath/src/opt/sinf.cpp new file mode 100644 index 00000000000000..7021509d027d24 --- /dev/null +++ b/src/native/clrmath/src/opt/sinf.cpp @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + /* + * ISO-IEC-10967-2: Elementary Numerical Functions + * Signature: + * float sin(float x) + * + * Spec: + * sinf(0) = 0 + * sinf(-0) = -0 + * sinf(inf) = NaN + * sinf(-inf) = NaN + * + * + ****************************************** + * Implementation Notes + * --------------------- + * + * checks for special cases + * if ( ux = infinity) raise overflow exception and return x + * if x is NaN then raise invalid FP operation exception and return x. + * + * 1. Argument reduction + * if |x| > 5e5 then + * __amd_remainder_piby2(x, &r, &rr, ®ion) + * else + * Argument reduction + * Let z = |x| * 2/pi + * z = dn + r, where dn = round(z) + * rhead = dn * pi/2_head + * rtail = dn * pi/2_tail + * r = z - dn = |x| - rhead - rtail + * expdiff = exp(dn) - exp(r) + * if(expdiff) > 15) + * rtail = |x| - dn*pi/2_tail2 + * r = |x| - dn*pi/2_head - dn*pi/2_tail1 - dn*pi/2_tail2 - (((rhead + rtail) - rhead )-rtail) + * rr = (|x| - rhead) - r + rtail + * + * 2. Polynomial approximation + * if(dn is odd) + * rr = rr * r; + * x4 = x2 * x2; + * s = 0.5 * x2; + * t = s - 1.0; + * poly = x4 * (C1 + x2 * (C2 + x2 * (C3 + x2 * (C4)))) + * r = (((1.0 + t) - s) - rr) + poly - t + * else + * x3 = x2 * r + * poly = S2 + (r2 * (S3 + (r2 * (S4)))) + * r = r - ((x2 * (0.5*rr - x3 * poly)) - rr) - S1 * x3 + * if(((sign & region) | ((~sign) & (~region))) & 1) + * return r + * else + * return -r; + + * if |x| < pi/4 && |x| > 2.0^(-13) + * sin(x) = x + (x * (r2 * (S1 + r2 * (S2 + r2 * (S3 + r2 * (S4))))) + * if |x| < 2.0^(-13) && |x| > 2.0^(-27) + * sin(x) = x - (x * x * x * (1/6)); + * + * + ****************************************** + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_types.h" +#include "libm/libm_typehelper.h" +#include "libm/libm_poly.h" + +struct sin_data_t { + const double twobypi, piby2_1, piby2_1tail, invpi, pi, pi1, pi2; + const double piby2_2, piby2_2tail, ALM_SHIFT; + const float one_by_six; + double poly_sin[7]; + double poly_cos[6]; +}; + +static const sin_data_t sin_data = { + /* .twobypi = */ 0x1.45f306dc9c883p-1, + /* .piby2_1 = */ 0x1.921fb54400000p0, + /* .piby2_1tail = */ 0x1.0b4611a626331p-34, + /* .invpi = */ 0x1.45f306dc9c883p-2, + /* .pi = */ 0x1.921fb54442d18p1, + /* .pi1 = */ 0x1.921fb50000000p1, + /* .pi2 = */ 0x1.110b4611a6263p-25, + /* .piby2_2 = */ 0x1.0b4611a600000p-34, + /* .piby2_2tail = */ 0x1.3198a2e037073p-69, + /* .ALM_SHIFT = */ 0x1.8p+52, + /* .one_by_six = */ 0.166666666666666f, + + /* + * Polynomial coefficients + */ + + /* .poly_sin = */ { + -0x1.5555555555555p-3, + 0x1.1111111110bb3p-7, + -0x1.a01a019e83e5cp-13, + 0x1.71de3796cde01p-19, + }, + /* .poly_cos = */ { + 0x1.5555555555555p-5, /* 0.0416667 */ + -0x1.6c16c16c16967p-10, /* -0.00138889 */ + 0x1.A01A019F4EC91p-16, /* 2.48016e-005 */ + -0x1.27E4FA17F667Bp-22, /* -2.75573e-007 */ + }, +}; + +void __amd_remainder_piby2d2f(uint64_t x, double* r, int* region); + +#define pi sin_data.pi +#define pi1 sin_data.pi1 +#define pi2 sin_data.pi2 +#define invpi sin_data.invpi +#define TwobyPI sin_data.twobypi +#define PIby2_1 sin_data.piby2_1 +#define PIby2_1tail sin_data.piby2_1tail +#define PIby2_2 sin_data.piby2_2 +#define PIby2_2tail sin_data.piby2_2tail +#define PIby4 0x3F490FDB +#define FiveE6 0x4A989680 +#define ONE_BY_SIX sin_data.one_by_six +#define ALM_SHIFT sin_data.ALM_SHIFT + +#define S1 sin_data.poly_sin[0] +#define S2 sin_data.poly_sin[1] +#define S3 sin_data.poly_sin[2] +#define S4 sin_data.poly_sin[3] + +#define C1 sin_data.poly_cos[0] +#define C2 sin_data.poly_cos[1] +#define C3 sin_data.poly_cos[2] +#define C4 sin_data.poly_cos[3] + +#define SIGN_MASK32 0x7FFFFFFF +#define SIGN_MASK 0x7FFFFFFFFFFFFFFF +#define INF32 0x7F800000 /* Infinity */ +#define SIN_SMALL 0x3C000000 /* 2.0^(-7) */ +#define SIN_SMALLER 0x39000000 /* 2.0^(-13) */ + +float _sinf_special(float x); + +float +ALM_PROTO_OPT(sinf)(float x) +{ + + double xd, r, s, poly, x2; + double rhead, rtail, x3, x4; + uint64_t uy; + uint32_t sign = 0; + int32_t region; + + /* sinf(inf) = sinf(-inf) = sinf(NaN) = NaN */ + + uint32_t uxf = asuint32(x); + + sign = uxf >> 31; + + uxf = uxf & SIGN_MASK32; + + if (unlikely(uxf >= INF32)) { + // infinity or NaN // + return _sinf_special(x); + + } + + if (uxf > PIby4) { + + float ax = asfloat(uxf); + + xd = (double)ax; + + /* ux > pi/4 */ + if (uxf < FiveE6) { + /* reduce the argument to be in a range from -pi/4 to +pi/4 + by subtracting multiples of pi/2 */ + + r = TwobyPI * xd; /* x * two_by_pi*/ + + int32_t xexp = uxf >> 23; + + double npi2d = r + ALM_SHIFT; + + int64_t npi2 = asuint64(npi2d); + + npi2d -= ALM_SHIFT; + + rhead = xd - npi2d * PIby2_1; + + rtail = npi2d * PIby2_1tail; + + r = rhead - rtail; + + uy = asuint64(r); + + int64_t expdiff = xexp - ((uy << 1) >> 53); + + region = (int32_t)npi2; + + if (expdiff > 15) { + + double t = rhead; + + rtail = npi2d * PIby2_2; + + rhead = t - rtail; + + rtail = npi2d * PIby2_2tail - ((t - rhead) - rtail); + + r = rhead - rtail; + } + + } + else { + /* Reduce x into range [-pi/4,pi/4] */ + __amd_remainder_piby2d2f(asuint64(xd), &r, ®ion); + + } + + x2 = r * r; + + if (region & 1) { + + /*cos region */ + + x4 = x2 * x2; + + s = 0.5 * x2; + + double t = 1.0 - s; + + poly = x4 * POLY_EVAL_3(x2, C1, C2, C3, C4); + + r = t + poly; + + } + else { + /* region 0 or 2 do a sin calculation */ + x3 = x2 * r; + + r += x3 * POLY_EVAL_3(x2, S1, S2, S3, S4); + + } + + region >>= 1; + + if (((sign & region) | ((~sign) & (~region))) & 1) { + + return (float)r; + + } + + return (float)(-r); + + } + else if (uxf >= SIN_SMALLER) { + + if (uxf >= SIN_SMALL) { + /* x > 2.0^(-13) */ + xd = (double)x; + + x2 = xd * xd; + + return (float)(xd + (xd * (x2 * POLY_EVAL_3(x2, S1, S2, S3, S4)))); + + } + + return x - x * x * x * ONE_BY_SIX; + + } + + return x; +} diff --git a/src/native/clrmath/src/opt/tan.cpp b/src/native/clrmath/src/opt/tan.cpp new file mode 100644 index 00000000000000..f382a180d72e57 --- /dev/null +++ b/src/native/clrmath/src/opt/tan.cpp @@ -0,0 +1,410 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * ISO-IEC-10967-2: Elementary Numerical Functions + * Signature: + * double tan(double x) + * + * Spec: + * tan(0) = 0 + * tan(-0) = 0 + * tan(inf) = NaN + * tan(NaN) = NaN + * + * + ****************************************** + * Implementation Notes + * --------------------- + * + * checks for special cases + * if ( ux = infinity) raise overflow exception and return x + * if x is NaN then raise invalid FP operation exception and return x. + * + * 1. Argument reduction + * if 2.0^(-13) < |x| < pi/4 then + * tan(pi/4-x) = (1-tan(x))/(1+tan(x)) for x close to pi/4 + * tan(x-pi/4) = (tan(x)-1)/(tan(x)+1) close to -pi/4 + * tan(x) is approximated by Core Remez [2,3] approximation to tan(x+xx) on the + * interval [0,0.68]. + * if 2.0^(-27) < |x| < 2.0^(-13) then tan(x) = x + (x * x * x * 1/3) + * if |x| < 2.0^(-27) then underflow + * + * if x < 5e5 then + * Reduce x into range [-pi/4,pi/4] and then compute tan(pi/4-x) + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_types.h" +#include "libm/libm_typehelper.h" +#include "libm/libm_poly.h" + +struct tan_data_t { + const uint64_t pi_by_4, small_x, min, zero; + const uint64_t five_e5, seven_pi_by_4; + const double one_by_three, twobypi, piby2_1, piby2_1tail, invpi; + const double piby2_2, piby2_2tail, ALM_SHIFT; + const double piby2_3, piby2_3tail, one_by_six; + const double piby4_lead, piby4_tail; + const uint64_t five_pi_by_4, three_pi_by_4, nine_pi_by_4; + double poly_tan[7]; +}; + +static const tan_data_t tan_data = { + /* .pi_by_4 = */ 0x3fe921fb54442d18, + /* .small_x = */ 0x3f20000000000000, + /* .min = */ 0x3e40000000000000, + /* .zero = */ 0x0, + /* .five_e5 = */ 0x411E848000000000, + /* .seven_pi_by_4 = */ 0x4015fdbbe9bba775, + /* .one_by_three = */ 0.333333333333333333, + /* .twobypi = */ 6.36619772367581382433e-01, /* 0x3fe45f306dc9c883 */ + /* .piby2_1 = */ 1.57079632673412561417e+00, /* 0x3ff921fb54400000 */ + /* .piby2_1tail = */ 6.07710050650619224932e-11, /* 0x3dd0b4611a626331 */ + /* .invpi = */ 0x1.45f306dc9c883p-2, + /* .piby2_2 = */ 6.07710050630396597660e-11, /* 0x3dd0b4611a600000 */ + /* .piby2_2tail = */ 0x1.3198a2e037073p-69, + /* .ALM_SHIFT = */ 0x1.8p+52, + /* .piby2_3 = */ 2.02226624871116645580e-21, /* 0x3ba3198a2e000000 */ + /* .piby2_3tail = */ 8.47842766036889956997e-32, /* 0x397b839a252049c1 */ + /* .one_by_six = */ 0.1666666666666666666, + /* .piby4_lead = */ 7.85398163397448278999e-01, /* 0x3fe921fb54442d18 */ + /* .piby4_tail = */ 3.06161699786838240164e-17, /* 0x3c81a62633145c06 */ + /* .five_pi_by_4 = */ 0x400f6a7a2955385e, + /* .three_pi_by_4 = */ 0x4002d97c7f3321d2, + /* .nine_pi_by_4 = */ 0x401c463abeccb2bb, + + /* + * Polynomial coefficients + */ + + /* .poly_tan = */ { + 0.372379159759792203640806338901e0, + -0.229345080057565662883358588111e-1, + 0.224044448537022097264602535574e-3, + 0.111713747927937668539901657944e1, + -0.515658515729031149329237816945e0, + 0.260656620398645407524064091208e-1, + -0.232371494088563558304549252913e-3 + }, +}; + +#define PI_BY_4 tan_data.pi_by_4 +#define SMALL_X tan_data.small_x +#define SMALLER_X tan_data.min +#define ZERO_ tan_data.zero +#define ONE_BY_THREE tan_data.one_by_three +#define FIVE_e5 tan_data.five_e5 +#define TWO_BY_PI tan_data.twobypi +#define PI_BY_2_1 tan_data.piby2_1 +#define PI_BY_2_1TAIL tan_data.piby2_1tail +#define PI_BY_2_2 tan_data.piby2_2 +#define PI_BY_2_2TAIL tan_data.piby2_2tail +#define PI_BY_2_3 tan_data.piby2_3 +#define PI_BY_2_3TAIL tan_data.piby2_3tail +#define FIVE_PI_BY_4 tan_data.five_pi_by_4 +#define THREE_PI_BY_4 tan_data.three_pi_by_4 +#define NINE_PI_BY_4 tan_data.nine_pi_by_4 +#define SEVEN_PI_BY_4 tan_data.seven_pi_by_4 +#define ALM_SHIFT tan_data.ALM_SHIFT +#define PI_BY_4_HEAD tan_data.piby4_lead +#define PI_BY_4_TAIL tan_data.piby4_tail + +#define T1 tan_data.poly_tan[0] +#define T2 tan_data.poly_tan[1] +#define T3 tan_data.poly_tan[2] +#define T4 tan_data.poly_tan[3] +#define T5 tan_data.poly_tan[4] +#define T6 tan_data.poly_tan[5] +#define T7 tan_data.poly_tan[6] + +#define MASK_LOWER32 0xffffffff00000000 +extern void __amd_remainder_piby2(double x, double* r, double* rr, int32_t* region); + + +/* tan(x + xx) approximation valid on the interval [-pi/4,pi/4]. + If recip is true return -1/tan(x + xx) instead. */ +static inline double tan_piby4(double x, double xx, int32_t recip) +{ + double r, r1, r2, t1, t2, xl; + int32_t transform = 0; + + /* In order to maintain relative precision transform using the identity: + tan(pi/4-x) = (1-tan(x))/(1+tan(x)) for arguments close to pi/4. + Similarly use tan(x-pi/4) = (tan(x)-1)/(tan(x)+1) close to -pi/4. */ + + if (x > 0.68) { + transform = 1; + + x = PI_BY_4_HEAD - x; + + xl = PI_BY_4_TAIL - xx; + + x += xl; + + xx = 0.0; + } + else if (x < -0.68) { + transform = -1; + + x = PI_BY_4_HEAD + x; + + xl = PI_BY_4_TAIL + xx; + + x += xl; + + xx = 0.0; + } + + /* Core Remez [2,3] approximation to tan(x+xx) on the + interval [0,0.68]. */ + + r = x * x + 2.0 * x * xx; + + t1 = x; + + r1 = xx + x * r * (T1 + r * (T2 + r * T3)); + + /* r2 = T4 + r*T5 + r^2*T6 + r^3*T7 */ + r2 = POLY_EVAL_3(r, T4, T5, T6, T7); + + t2 = r1 / r2; + + /* Reconstruct tan(x) in the transformed case. */ + + if (transform) { + double t; + + t = t1 + t2; + + if (recip) { + + return transform * (2 * t / (t - 1) - 1.0); + + } + else { + + return transform * (1.0 - 2 * t / (1 + t)); + + } + } + + if (recip) { + /* Compute -1.0/(t1 + t2) accurately */ + double trec, trec_top, z1, z2, t; + uint64_t u; + + t = t1 + t2; + + u = asuint64(t); + + u &= MASK_LOWER32; + + z1 = asdouble(u); + + z2 = t2 - (z1 - t1); + + trec = -1.0 / t; + + u = asuint64(trec); + + u &= MASK_LOWER32; + + trec_top = asdouble(u); + + return trec_top + trec * ((1.0 + trec_top * z1) + trec_top * z2); + } + else { + + return t1 + t2; + + } +} + + +double ALM_PROTO_OPT(tan)(double x) +{ + double r, rr, t, rhead, rtail, npi2d; + int32_t npi2, region, xneg; + uint64_t ux, uy, ax, xexp, expdiff; + + ux = asuint64(x); + + ax = (ux & ~SIGNBIT_DP64); + + if (ax <= PI_BY_4) { /* abs(x) <= pi/4 */ + + if (ax < SMALL_X) { /* abs(x) < 2.0^(-13) */ + + if (ax < SMALLER_X) {/* abs(x) < 2.0^(-27) */ + + if (ax == ZERO_) { + + return x; + + } + else { + + return __amd_handle_error("tan", __amd_tan, ux, _UNDERFLOW, + AMD_F_UNDERFLOW | AMD_F_INEXACT, + ERANGE, x, 0.0, 1); + + } + } + else { + + return x + (x * x * x * ONE_BY_THREE); + + } + } + else { + + return tan_piby4(x, 0.0, 0); + + } + } + else if (unlikely(((ux & EXPBITS_DP64) == EXPBITS_DP64))) { + + /* x is either NaN or infinity */ + if (ux & MANTBITS_DP64) { + + /* x is NaN */ + if (ux & QNAN_MASK_64) { + + return __amd_handle_error("tan", __amd_tan, ux | QNAN_MASK_64, + _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); + } + else { + + return __amd_handle_error("tan", __amd_tan, ux | QNAN_MASK_64, + _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); + } + + } + else { + /* x is infinity. Return a NaN */ + return __amd_handle_error("tan", __amd_tan, INDEFBITPATT_DP64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + } + + xneg = ux >> 63; + + x = asdouble(ax); + + if (ax < FIVE_e5) { /* x < 5e5 */ + /* For these size arguments we can just carefully subtract the + appropriate multiple of pi/2, using extra precision where + x is close to an exact multiple of pi/2 */ + + xexp = ax >> EXPSHIFTBITS_DP64; + /* How many pi/2 is x a multiple of? */ + if (ax <= FIVE_PI_BY_4) { /* 5pi/4 */ + + if (ax <= THREE_PI_BY_4) /* 3pi/4 */ + npi2 = 1; + else + npi2 = 2; + + npi2d = (double)npi2; + } + else if (ax <= NINE_PI_BY_4) {/* 9pi/4 */ + + if (ax <= SEVEN_PI_BY_4) /* 7pi/4 */ + npi2 = 3; + else + npi2 = 4; + + npi2d = (double)npi2; + } + else { + + npi2d = x * TWO_BY_PI + ALM_SHIFT; + + npi2 = (int32_t)asuint64(npi2d); + + npi2d -= ALM_SHIFT; + + } + + /* Subtract the multiple from x to get an extra-precision remainder */ + rhead = x - npi2d * PI_BY_2_1; + + rtail = npi2d * PI_BY_2_1TAIL; + + uy = asuint64(rhead); + + expdiff = xexp - ((uy & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); + + if (expdiff > 15) { + /* The remainder is pretty small compared with x, which + implies that x is a near multiple of pi/2 + (x matches the multiple to at least 15 bits) */ + t = rhead; + + rtail = npi2d * PI_BY_2_2; + + rhead = t - rtail; + + rtail = npi2d * PI_BY_2_2TAIL - ((t - rhead) - rtail); + + if (expdiff > 48) { + /* x matches a pi/2 multiple to at least 48 bits */ + t = rhead; + + rtail = npi2d * PI_BY_2_3; + + rhead = t - rtail; + + rtail = npi2d * PI_BY_2_3TAIL - ((t - rhead) - rtail); + } + } + + r = rhead - rtail; + + rr = (rhead - r) - rtail; + + region = npi2 & 3; + } + else { + /* Reduce x into range [-pi/4,pi/4] */ + __amd_remainder_piby2(x, &r, &rr, ®ion); + + } + + if (xneg) { + + return -tan_piby4(r, rr, region & 1); + + } + else { + + return tan_piby4(r, rr, region & 1); + + } +} diff --git a/src/native/clrmath/src/opt/tanf.cpp b/src/native/clrmath/src/opt/tanf.cpp new file mode 100644 index 00000000000000..a119a02836c506 --- /dev/null +++ b/src/native/clrmath/src/opt/tanf.cpp @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + /* + * ISO-IEC-10967-2: Elementary Numerical Functions + * Signature: + * float tan(float x) + * + * Spec: + * tanf(0) = 0 + * tanf(-0) = 0 + * tanf(inf) = NaN + * tanf(NaN) = NaN + * + * + ****************************************** + * Implementation Notes + * --------------------- + * + * checks for special cases + * if ( ux = infinity) raise overflow exception and return x + * if x is NaN then raise invalid FP operation exception and return x. + * + * 1. Argument reduction + * if 2.0^(-13) < |x| < pi/4 then + * tan(pi/4-x) = (1-tan(x))/(1+tan(x)) for x close to pi/4 + * tan(x-pi/4) = (tan(x)-1)/(tan(x)+1) close to -pi/4 + * tan(x) is approximated by Core Remez [2,3] approximation to tan(x+xx) on the + * interval [0,0.68]. + * if 2.0^(-27) < |x| < 2.0^(-13) then tan(x) = x + (x * x * x * 1/3) + * if |x| < 2.0^(-27) then underflow + * + * if x < 5e5 then + * Reduce x into range [-pi/4,pi/4] and then compute tan(pi/4-x) + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_types.h" +#include "libm/libm_typehelper.h" +#include "libm/libm_poly.h" + +struct tanf_data_t { + const uint64_t pi_by_4; + const uint64_t five_e5, seven_pi_by_4; + const uint64_t five_pi_by_4, three_pi_by_4, nine_pi_by_4; + const double one_by_three, twobypi, piby2_1, piby2_1tail, invpi; + const double piby2_2, piby2_2tail, shift; + const double piby2_3, piby2_3tail, one_by_six; + const double piby4_lead, piby4_tail; + + double poly_tanf[5]; +}; + +static const tanf_data_t tanf_data = { + /* .pi_by_4 = */ 0x3fe921fb54442d18, + /* .five_e5 = */ 0x411E848000000000, + /* .seven_pi_by_4 = */ 0x4015fdbbe9bba775, + /* .five_pi_by_4 = */ 0x400f6a7a2955385e, + /* .three_pi_by_4 = */ 0x4002d97c7f3321d2, + /* .nine_pi_by_4 = */ 0x401c463abeccb2bb, + /* .one_by_three = */ 0.333333333333333333, + /* .twobypi = */ 6.36619772367581382433e-01, /* 0x3fe45f306dc9c883 */ + /* .piby2_1 = */ 1.57079632673412561417e+00, /* 0x3ff921fb54400000 */ + /* .piby2_1tail = */ 6.07710050650619224932e-11, /* 0x3dd0b4611a626331 */ + /* .invpi = */ 0x1.45f306dc9c883p-2, + /* .piby2_2 = */ 6.07710050630396597660e-11, /* 0x3dd0b4611a600000 */ + /* .piby2_2tail = */ 2.02226624879595063154e-21, + /* .shift = */ 0x1.8p+52, + /* .piby2_3 = */ 2.02226624871116645580e-21, /* 0x3ba3198a2e000000 */ + /* .piby2_3tail = */ 8.47842766036889956997e-32, /* 0x397b839a252049c1 */ + /* .one_by_six = */ 0.1666666666666666666, + /* .piby4_lead = */ 7.85398163397448278999e-01, /* 0x3fe921fb54442d18 */ + /* .piby4_tail = */ 3.06161699786838240164e-17, /* 0x3c81a62633145c06 */ + + /* Polynomial coefficients */ + + /* .poly_tanf = */ { + 0.385296071263995406715129e0, + 0.172032480471481694693109e-1, + 0.115588821434688393452299e+1, + -0.51396505478854532132342e0, + 0.1844239256901656082986661e-1, + }, +}; + +#define PI_BY_4 tanf_data.pi_by_4 +#define ALM_TANF_ZERO (0x0L) +#define ONE_BY_THREE tanf_data.one_by_three +#define FIVE_e5 tanf_data.five_e5 +#define TWO_BY_PI tanf_data.twobypi +#define PI_BY_2_1 tanf_data.piby2_1 +#define PI_BY_2_1TAIL tanf_data.piby2_1tail +#define PI_BY_2_2 tanf_data.piby2_2 +#define PI_BY_2_2TAIL tanf_data.piby2_2tail +#define PI_BY_2_3 tanf_data.piby2_3 +#define PI_BY_2_3TAIL tanf_data.piby2_3tail +#define FIVE_PI_BY_4 tanf_data.five_pi_by_4 +#define THREE_PI_BY_4 tanf_data.three_pi_by_4 +#define NINE_PI_BY_4 tanf_data.nine_pi_by_4 +#define SEVEN_PI_BY_4 tanf_data.seven_pi_by_4 +#define ALM_SHIFT tanf_data.shift +#define PI_BY_4_HEAD tanf_data.piby4_lead +#define PI_BY_4_TAIL tanf_data.piby4_tail + +#define T1 tanf_data.poly_tanf[0] +#define T2 tanf_data.poly_tanf[1] +#define T3 tanf_data.poly_tanf[2] +#define T4 tanf_data.poly_tanf[3] +#define T5 tanf_data.poly_tanf[4] + +#define MASK_LOWER32 0xffffffff00000000UL + +void __amd_remainder_piby2d2f(uint64_t ux, double* r, int* region); + +/* + * tan(x + xx) approximation valid on the interval + * [-pi/4,pi/4]. + * If recip is true return -1/tan(x + xx) instead. + */ +static inline float +tan_piby4(double x, int32_t recip) { + + double r, t, r1, r2; + + /* Core Remez [1,2] approximation to tan(x) on the^M + interval [0,pi/4]. */ + r = x * x; + + r1 = (T1 - T2 * r); + + r2 = (T3 + r * (T4 + r * T5)); + + t = x + x * r * r1 / r2; + + if (recip) + return (float)(-1.0 / t); + else + return (float)t; + +} + +static inline float +tan_piby4i_zero(double x) { + + double r, t, r1, r2; + + /* Core Remez [1,2] approximation to tan(x) on the^M + interval [0,pi/4]. */ + r = x * x; + + r1 = (T1 - T2 * r); + + r2 = (T3 + r * (T4 + r * T5)); + + t = x + x * r * r1 / r2; + + return (float)t; + +} + +static float +__tanf_special_inline(float x) +{ + uint32_t uxf; + + uxf = asuint32(x); + + /* x is either NaN or infinity */ + if (uxf & MANTBITS_SP32) { + /* x is NaN */ + if (uxf & QNAN_MASK_32) + return __amd_handle_errorf("tanf", __amd_tan, uxf | QNAN_MASK_32, + _DOMAIN, AMD_F_NONE, EDOM, x, 0.0f, 1); + + return __amd_handle_errorf("tanf", __amd_tan, uxf | QNAN_MASK_32, + _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0f, 1); + } + + /* x is infinity. Return a NaN */ + return __amd_handle_errorf("tanf", __amd_tan, INDEFBITPATT_SP32, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0f, 1); +} + +#define ALM_TANF_SMALL_X 0x3C000000 +#define ALM_TANF_ARG_MIN 0x39000000 + +static float +__tanf_very_small_x(float x) +{ + uint32_t ax = asuint32(x) & ~SIGNBIT_SP32; + + if (ax == ALM_TANF_ZERO) + return x; + + if (ax < ALM_TANF_SMALL_X) { /* abs(x) < 2.0^(-13) */ + if (ax < ALM_TANF_ARG_MIN) /* abs(x) < 2.0^(-27) */ + return __amd_handle_errorf("tanf", __amd_tan, asuint32(x), _UNDERFLOW, + AMD_F_UNDERFLOW | AMD_F_INEXACT, + ERANGE, x, 0.0, 1); + + /* + * 2^-13 < abs(x) < 2^-27 + * tan(x) = x + x^3 * 0.333333333 + */ + return (float)(x + (x * x * x * ONE_BY_THREE)); + } + + return tan_piby4i_zero(x); +} + +float ALM_PROTO_OPT(tanf)(float x) +{ + double dx, r; + int32_t region, xneg; + uint32_t uxf; + + uxf = asuint32(x); + + xneg = uxf & SIGNBIT_SP32; + + if (unlikely(((uxf & PINFBITPATT_SP32) == PINFBITPATT_SP32))) { + return __tanf_special_inline(x); + } + + /* uxf = abs(uxf) */ + uxf &= ~SIGNBIT_SP32; + + dx = (double)asfloat(uxf); + + uint64_t ax = asuint64(dx); + + if (unlikely(ax >= FIVE_e5)) { + /* Reduce x into range [-pi/4,pi/4] */ + __amd_remainder_piby2d2f(ax, &r, ®ion); + } + else { + + double rhead, rtail, npi2d; + uint32_t npi2; + + if (ax <= PI_BY_4) { /* abs(x) <= pi/4 */ + return __tanf_very_small_x(x); + } + + /* Here on , pi/4 < ax < 5e5 + * For these size arguments we can just carefully subtract the + * appropriate multiple of pi/2, using extra precision where + * x is close to an exact multiple of pi/2 + */ + + npi2d = dx * TWO_BY_PI + ALM_SHIFT; + + npi2 = (uint32_t)asuint64(npi2d); + + npi2d -= ALM_SHIFT; + + /* Subtract the multiple from x to get an extra-precision remainder */ + rhead = dx - npi2d * PI_BY_2_1; + + rtail = npi2d * PI_BY_2_1TAIL; + + r = rhead - rtail; + + region = npi2; + } + + float res = tan_piby4(r, region & 1); + + /* tan(x) = -tan(x) if x is negative */ + res = asfloat(xneg ^ asuint32(res)); + + return res; + +} diff --git a/src/native/clrmath/src/opt/tanhf.cpp b/src/native/clrmath/src/opt/tanhf.cpp new file mode 100644 index 00000000000000..6413d772a2b63c --- /dev/null +++ b/src/native/clrmath/src/opt/tanhf.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + + /* + * ISO-IEC-10967-2: Elementary Numerical Functions + * Signature: + * float tanhf(float x) + * + * Spec: + * tanhf(0) = 0 + * tanhf(-0) = 0 + * tanhf(inf) = 1 + * tanhf(-inf) = -1 + * + * + ****************************************** + * Implementation Notes + * --------------------- + * To compute tanhf(float x) + * Let y = |x| + * The input argument is then reduced to one of these three intervals: + * + * 1. 0 <= y < 1 + * In this case, tanhf(y) is calculated as, + * tanhf(y) = y + C1 * y^3 + C2 * y^5 + C3 * y^7 + C4 * y^9 + + * C5 * y^11 + C6 * y^13 + C7 * y^15 + * + * The polynomial coefficients are derived using fpminmax algorithm. + * + * 2. 1 <= y < 0x1.154246p3 + * In this case, tanhf(y) is calculated as, + * tanhf(y) = 1 - 2/(z + 1), where z = e^(-2 * y) + * + * This can be approximated using the polynomial, + * tanhf(y) = 1.0 + 2 * (z^8 - z^7 + z^6 - z^5 + z^4 - z^3 + z^2 - z) + * + * 3. 0x1.154246p3 <= y < +inf + * In this case, tanhf(y) = 1 + * + * If x < 0, then we use the identity + * tanhf(-x) = -tanhf(x) + * + * Max ULP of current implementation: 1 + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_types.h" +#include "libm/libm_typehelper.h" +#include "libm/libm_poly.h" + +struct tanhf_data_t { + float poly_tanhf[7]; + float max_arg; +}; + +static const tanhf_data_t tanhf_data = { + /* .poly_tanhf = */ { + -0x1.55553p-2, + 0x1.110aeap-3, + -0x1.b94f7ep-5, + 0x1.5fadfcp-6, + -0x1.037056p-7, + 0x1.2b22eap-9, + -0x1.728278p-12, + }, + /* .max_arg = */ 0x1.154246p3, +}; + +#define C1 tanhf_data.poly_tanhf[0] +#define C2 tanhf_data.poly_tanhf[1] +#define C3 tanhf_data.poly_tanhf[2] +#define C4 tanhf_data.poly_tanhf[3] +#define C5 tanhf_data.poly_tanhf[4] +#define C6 tanhf_data.poly_tanhf[5] +#define C7 tanhf_data.poly_tanhf[6] + +#define TANHF_MAX_ARG tanhf_data.max_arg + +#define TANHF_SMALL_ARG 0x39000000 +#define TANHF_SIGN_MASK32 ~(1U<<31) + +float +ALM_PROTO_OPT(tanhf)(float x) +{ + + float y, z, result; + float poly; + uint32_t sign, ux; + + /* Get sign of input argument */ + ux = asuint32(x); + sign = ux & (~TANHF_SIGN_MASK32); + + /* Get absolute value of input argument */ + y = asfloat(ux & TANHF_SIGN_MASK32); + + /* Check for Special cases */ + ux = asuint32(y); + + /* |x| is small enough that tanhf(x) = x */ + if (ux < TANHF_SMALL_ARG) { + + if (ux == POS_ZERO_F32) + /* For +/- 0 */ + return x; + else + /* For underflow */ + return _tanhf_special(x); + + } + else if (ux > PINFBITPATT_SP32) + /* For +/-inf */ + return x + x; + + if (y > TANHF_MAX_ARG) + /* For x > max_arg */ + return asfloat(asuint32(1.0f) ^ sign); + + if (y < 1.0) { + + /* Compute tanhf using the polynomial + y + C1 * y^3 + C2 * y^5 + C3 * y^7 + C4 * y^9 + + C5 * y^11 + C6 * y^13 + C7 * y^15 + */ + result = POLY_EVAL_ODD_15F(y, C1, C2, C3, C4, C5, C6, C7); + + } + else { + + // z = e^(-2 * y) + z = ALM_PROTO(expf)(-2.0f * y); + float z2 = z * z; + float z4 = z2 * z2; + + float a0 = 1.0f - z; + float a1 = 1 + z2; + + float b0 = a0 * a1; + float b1 = z4 * a0 * a1; + + /* tanhf can be approximated using the polynomial + 1.0 + 2 * (z^8 - z^7 + z^6 - z^5 + z^4 - z^3 + z^2 - z) + */ + poly = b0 + b1; + + result = 1.0f - (2.0f * z * poly); + } + + /* Result is -ve if input argument is -ve */ + return asfloat(asuint32(result) ^ sign); + +} diff --git a/src/native/clrmath/src/ref/acos.cpp b/src/native/clrmath/src/ref/acos.cpp new file mode 100644 index 00000000000000..40ccd7ccd00f3a --- /dev/null +++ b/src/native/clrmath/src/ref/acos.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +double FN_PROTOTYPE_REF(acos)(double x) +{ + /* Computes arccos(x). + The argument is first reduced by noting that arccos(x) + is invalid for abs(x) > 1. For denormal and small + arguments arccos(x) = pi/2 to machine accuracy. + Remaining argument ranges are handled as follows. + For abs(x) <= 0.5 use + arccos(x) = pi/2 - arcsin(x) + = pi/2 - (x + x^3*R(x^2)) + where R(x^2) is a rational minimax approximation to + (arcsin(x) - x)/x^3. + For abs(x) > 0.5 exploit the identity: + arccos(x) = pi - 2*arcsin(sqrt(1-x)/2) + together with the above rational approximation, and + reconstruct the terms carefully. + */ + + /* Some constants and split constants. */ + + static const double + pi = 3.1415926535897933e+00, /* 0x400921fb54442d18 */ + piby2 = 1.5707963267948965580e+00, /* 0x3ff921fb54442d18 */ + piby2_head = 1.5707963267948965580e+00, /* 0x3ff921fb54442d18 */ + piby2_tail = 6.12323399573676603587e-17; /* 0x3c91a62633145c07 */ + + double u, y, s = 0.0, r; + int xexp, xnan, transform = 0; + + unsigned long long ux, aux, xneg; + GET_BITS_DP64(x, ux); + aux = ux & ~SIGNBIT_DP64; + xneg = (ux & SIGNBIT_DP64); + xnan = (aux > PINFBITPATT_DP64); + xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; + + /* Special cases */ + + if (xnan) + { +#ifdef WINDOWS + return __amd_handle_error("acos", __amd_acos, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); +#else + //return x + x; /* With invalid if it's a signalling NaN */ + if (ux & QNAN_MASK_64) + return __amd_handle_error("acos", __amd_acos, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); + else + return __amd_handle_error("acos", __amd_acos, ux | 0x0008000000000000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); +#endif + } + else if (xexp < -56) + { /* y small enough that arccos(x) = pi/2 */ + return piby2;//val_with_flags(piby2, AMD_F_INEXACT); + } + else if (xexp >= 0) + { /* abs(x) >= 1.0 */ + if (x == 1.0) + return 0.0; + else if (x == -1.0) + return pi; //val_with_flags(pi, AMD_F_INEXACT); + else +#ifdef WINDOWS + return __amd_handle_error("acos", __amd_acos, INDEFBITPATT_DP64, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); +#else + //return retval_errno_edom(x); + return __amd_handle_error("acos", __amd_acos, INDEFBITPATT_DP64, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); +#endif + } + + if (xneg) y = -x; + else y = x; + + transform = (xexp >= -1); /* abs(x) >= 0.5 */ + + if (transform) + { /* Transform y into the range [0,0.5) */ + r = 0.5 * (1.0 - y); + ASMSQRT(r, s); + y = s; + } + else + r = y * y; + + /* Use a rational approximation for [0.0, 0.5] */ + + u = r * (0.227485835556935010735943483075 + + (-0.445017216867635649900123110649 + + (0.275558175256937652532686256258 + + (-0.0549989809235685841612020091328 + + (0.00109242697235074662306043804220 + + 0.0000482901920344786991880522822991 * r) * r) * r) * r) * r) / + (1.36491501334161032038194214209 + + (-3.28431505720958658909889444194 + + (2.76568859157270989520376345954 + + (-0.943639137032492685763471240072 + + 0.105869422087204370341222318533 * r) * r) * r) * r); + + if (transform) + { /* Reconstruct acos carefully in transformed region */ + if (xneg) return pi - 2.0 * (s + (y * u - piby2_tail)); + else + { + double c, s1; + unsigned long long us; + GET_BITS_DP64(s, us); + PUT_BITS_DP64(0xffffffff00000000 & us, s1); + c = (r - s1 * s1) / (s + s1); + return 2.0 * s1 + (2.0 * c + 2.0 * y * u); + } + } + else + return piby2_head - (x - (piby2_tail - x * u)); +} diff --git a/src/native/clrmath/src/ref/acosf.cpp b/src/native/clrmath/src/ref/acosf.cpp new file mode 100644 index 00000000000000..d67b0ff459df29 --- /dev/null +++ b/src/native/clrmath/src/ref/acosf.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +float FN_PROTOTYPE_REF(acosf)(float x) +{ + /* Computes arccos(x). + The argument is first reduced by noting that arccos(x) + is invalid for abs(x) > 1. For denormal and small + arguments arccos(x) = pi/2 to machine accuracy. + Remaining argument ranges are handled as follows. + For abs(x) <= 0.5 use + arccos(x) = pi/2 - arcsin(x) + = pi/2 - (x + x^3*R(x^2)) + where R(x^2) is a rational minimax approximation to + (arcsin(x) - x)/x^3. + For abs(x) > 0.5 exploit the identity: + arccos(x) = pi - 2*arcsin(sqrt(1-x)/2) + together with the above rational approximation, and + reconstruct the terms carefully. + */ + + /* Some constants and split constants. */ + + static const float + piby2 = 1.5707963705e+00F; /* 0x3fc90fdb */ + static const double + pi = 3.1415926535897933e+00, /* 0x400921fb54442d18 */ + piby2_head = 1.5707963267948965580e+00, /* 0x3ff921fb54442d18 */ + piby2_tail = 6.12323399573676603587e-17; /* 0x3c91a62633145c07 */ + + float u, y, s = 0.0F, r; + int xexp, xnan, transform = 0; + + unsigned int ux, aux, xneg; + + GET_BITS_SP32(x, ux); + aux = ux & ~SIGNBIT_SP32; + xneg = (ux & SIGNBIT_SP32); + xnan = (aux > PINFBITPATT_SP32); + xexp = (int)((ux & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; + + /* Special cases */ + + if (xnan) + { +#ifdef WINDOWS + return __amd_handle_errorf("acosf", __amd_acos, ux | 0x00400000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0F, 1); +#else + //return x + x; /* With invalid if it's a signalling NaN */ + if (ux & QNAN_MASK_32) + return __amd_handle_errorf("acosf", __amd_acos, ux | 0x00400000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0F, 1); + else + return __amd_handle_errorf("acosf", __amd_acos, ux | 0x00400000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0F, 1); + + +#endif + } + else if (xexp < -26) + /* y small enough that arccos(x) = pi/2 */ + return piby2;//valf_with_flags(piby2, AMD_F_INEXACT); + else if (xexp >= 0) + { /* abs(x) >= 1.0 */ + if (x == 1.0F) + return 0.0F; + else if (x == -1.0F) + return (float)pi;//valf_with_flags((float)pi, AMD_F_INEXACT); + else +#ifdef WINDOWS + return __amd_handle_errorf("acosf", __amd_acos, INDEFBITPATT_SP32, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0F, 1); +#else + //return retval_errno_edom(x); + return __amd_handle_errorf("acosf", __amd_acos, INDEFBITPATT_SP32, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0F, 1); +#endif + } + + if (xneg) y = -x; + else y = x; + + transform = (xexp >= -1); /* abs(x) >= 0.5 */ + + if (transform) + { /* Transform y into the range [0,0.5) */ + r = 0.5F * (1.0F - y); + ASMSQRTF(r, s); + y = s; + } + else + r = y * y; + + /* Use a rational approximation for [0.0, 0.5] */ + + u = r * (0.184161606965100694821398249421F + + (-0.0565298683201845211985026327361F + + (-0.0133819288943925804214011424456F - + 0.00396137437848476485201154797087F * r) * r) * r) / + (1.10496961524520294485512696706F - + 0.836411276854206731913362287293F * r); + + if (transform) + { + /* Reconstruct acos carefully in transformed region */ + if (xneg) + return (float)(pi - 2.0 * (s + (y * u - piby2_tail))); + else + { + float c, s1; + unsigned int us; + GET_BITS_SP32(s, us); + PUT_BITS_SP32(0xffff0000 & us, s1); + c = (r - s1 * s1) / (s + s1); + return 2.0F * s1 + (2.0F * c + 2.0F * y * u); + } + } + else + return (float)(piby2_head - (x - (piby2_tail - x * u))); +} diff --git a/src/native/clrmath/src/ref/acosh.cpp b/src/native/clrmath/src/ref/acosh.cpp new file mode 100644 index 00000000000000..3c7856c2f4cdd5 --- /dev/null +++ b/src/native/clrmath/src/ref/acosh.cpp @@ -0,0 +1,407 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_inlines.h" + +#undef _FUNCNAME +#define _FUNCNAME "acosh" +double FN_PROTOTYPE_REF(acosh)(double x) +{ + + unsigned long long ux; + double r, rarg, r1, r2; + int xexp; + + static const unsigned long long + recrteps = 0x4196a09e667f3bcd; /* 1/sqrt(eps) = 9.49062656242515593767e+07 */ + /* log2_lead and log2_tail sum to an extra-precise version + of log(2) */ + + static const double + log2_lead = 6.93147122859954833984e-01, /* 0x3fe62e42e0000000 */ + log2_tail = 5.76999904754328540596e-08; /* 0x3e6efa39ef35793c */ + + + GET_BITS_DP64(x, ux); + + if ((ux & EXPBITS_DP64) == EXPBITS_DP64) + { + /* x is either NaN or infinity */ + if (ux & MANTBITS_DP64) + { + /* x is NaN */ +#ifdef WINDOWS + return __amd_handle_error(_FUNCNAME, __amd_acosh, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); +#else + if (ux & QNAN_MASK_64) + return __amd_handle_error(_FUNCNAME, __amd_acosh, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); + else + return __amd_handle_error(_FUNCNAME, __amd_acosh, ux | 0x0008000000000000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); +#endif + } + else + { + /* x is infinity */ + if (ux & SIGNBIT_DP64) // negative infinity return nan raise error + return __amd_handle_error(_FUNCNAME, __amd_acosh, INDEFBITPATT_DP64, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); + else + return x; + } + } + else if ((ux & SIGNBIT_DP64) || (ux <= 0x3ff0000000000000)) + { + /* x <= 1.0 */ + if (ux == 0x3ff0000000000000) + { + /* x = 1.0; return zero. */ + return 0.0; + } + else + { + /* x is less than 1.0. Return a NaN. */ + return __amd_handle_error(_FUNCNAME, __amd_acosh, INDEFBITPATT_DP64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + } + + + if (ux > recrteps) + { + /* Arguments greater than 1/sqrt(epsilon) in magnitude are + approximated by acosh(x) = ln(2) + ln(x) */ + /* log_kernel_amd(x) returns xexp, r1, r2 such that + log(x) = xexp*log(2) + r1 + r2 */ + log_kernel_amd64(x, ux, &xexp, &r1, &r2); + /* Add (xexp+1) * log(2) to z1,z2 to get the result acosh(x). + The computed r1 is not subject to rounding error because + (xexp+1) has at most 10 significant bits, log(2) has 24 significant + bits, and r1 has up to 24 bits; and the exponents of r1 + and r2 differ by at most 6. */ + r1 = ((xexp + 1) * log2_lead + r1); + r2 = ((xexp + 1) * log2_tail + r2); + return r1 + r2; + } + else if (ux >= 0x4060000000000000) + { + /* 128.0 <= x <= 1/sqrt(epsilon) */ + /* acosh for these arguments is approximated by + acosh(x) = ln(x + sqrt(x*x-1)) */ + rarg = x * x - 1.0; + /* Use assembly instruction to compute r = sqrt(rarg); */ + ASMSQRT(rarg, r); + r += x; + GET_BITS_DP64(r, ux); + log_kernel_amd64(r, ux, &xexp, &r1, &r2); + r1 = (xexp * log2_lead + r1); + r2 = (xexp * log2_tail + r2); + return r1 + r2; + } + else + { + /* 1.0 < x <= 128.0 */ + double u1, u2, v1, v2, w1, w2, hx, tx, t, r, s, p1, p2, a1, a2, c1, c2, + poly; + if (ux >= 0x3ff8000000000000) + { + /* 1.5 <= x <= 128.0 */ + /* We use minimax polynomials, + based on Abramowitz and Stegun 4.6.32 series + expansion for acosh(x), with the log(2x) and 1/(2.2.x^2) + terms removed. We compensate for these two terms later. + */ + t = x * x; + if (ux >= 0x4040000000000000) + { + /* [3,2] for 32.0 <= x <= 128.0 */ + poly = + (0.45995704464157438175e-9 + + (-0.89080839823528631030e-9 + + (-0.10370522395596168095e-27 + + 0.35255386405811106347e-32 * t) * t) * t) / + (0.21941191335882074014e-8 + + (-0.10185073058358334569e-7 + + 0.95019562478430648685e-8 * t) * t); + } + else if (ux >= 0x4020000000000000) + { + /* [3,3] for 8.0 <= x <= 32.0 */ + poly = + (-0.54903656589072526589e-10 + + (0.27646792387218569776e-9 + + (-0.26912957240626571979e-9 - + 0.86712268396736384286e-29 * t) * t) * t) / + (-0.24327683788655520643e-9 + + (0.20633757212593175571e-8 + + (-0.45438330985257552677e-8 + + 0.28707154390001678580e-8 * t) * t) * t); + } + else if (ux >= 0x4010000000000000) + { + /* [4,3] for 4.0 <= x <= 8.0 */ + poly = + (-0.20827370596738166108e-6 + + (0.10232136919220422622e-5 + + (-0.98094503424623656701e-6 + + (-0.11615338819596146799e-18 + + 0.44511847799282297160e-21 * t) * t) * t) * t) / + (-0.92579451630913718588e-6 + + (0.76997374707496606639e-5 + + (-0.16727286999128481170e-4 + + 0.10463413698762590251e-4 * t) * t) * t); + } + else if (ux >= 0x4000000000000000) + { + /* [5,5] for 2.0 <= x <= 4.0 */ + poly = + (-0.122195030526902362060e-7 + + (0.157894522814328933143e-6 + + (-0.579951798420930466109e-6 + + (0.803568881125803647331e-6 + + (-0.373906657221148667374e-6 - + 0.317856399083678204443e-21 * t) * t) * t) * t) * t) / + (-0.516260096352477148831e-7 + + (0.894662592315345689981e-6 + + (-0.475662774453078218581e-5 + + (0.107249291567405130310e-4 + + (-0.107871445525891289759e-4 + + 0.398833767702587224253e-5 * t) * t) * t) * t) * t); + } + else if (ux >= 0x3ffc000000000000) + { + /* [5,4] for 1.75 <= x <= 2.0 */ + poly = + (0.1437926821253825186e-3 + + (-0.1034078230246627213e-2 + + (0.2015310005461823437e-2 + + (-0.1159685218876828075e-2 + + (-0.9267353551307245327e-11 + + 0.2880267770324388034e-12 * t) * t) * t) * t) * t) / + (0.6305521447028109891e-3 + + (-0.6816525887775002944e-2 + + (0.2228081831550003651e-1 + + (-0.2836886105406603318e-1 + + 0.1236997707206036752e-1 * t) * t) * t) * t); + } + else + { + /* [5,4] for 1.5 <= x <= 1.75 */ + poly = + (0.7471936607751750826e-3 + + (-0.4849405284371905506e-2 + + (0.8823068059778393019e-2 + + (-0.4825395461288629075e-2 + + (-0.1001984320956564344e-8 + + 0.4299919281586749374e-10 * t) * t) * t) * t) * t) / + (0.3322359141239411478e-2 + + (-0.3293525930397077675e-1 + + (0.1011351440424239210e0 + + (-0.1227083591622587079e0 + + 0.5147099404383426080e-1 * t) * t) * t) * t); + } + GET_BITS_DP64(x, ux); + log_kernel_amd64(x, ux, &xexp, &r1, &r2); + r1 = ((xexp + 1) * log2_lead + r1); + r2 = ((xexp + 1) * log2_tail + r2); + /* Now (r1,r2) sum to log(2x). Subtract the term + 1/(2.2.x^2) = 0.25/t, and add poly/t, carefully + to maintain precision. (Note that we add poly/t + rather than poly because of the *x factor used + when generating the minimax polynomial) */ + v2 = (poly - 0.25) / t; + r = v2 + r1; + s = ((r1 - r) + v2) + r2; + v1 = r + s; + return v1 + ((r - v1) + s); + } + + /* Here 1.0 <= x <= 1.5. It is hard to maintain accuracy here so + we have to go to great lengths to do so. */ + + /* We compute the value + t = x - 1.0 + sqrt(2.0*(x - 1.0) + (x - 1.0)*(x - 1.0)) + using simulated quad precision. */ + t = x - 1.0; + u1 = t * 2.0; + + /* dekker_mul12(t,t,&v1,&v2); */ + GET_BITS_DP64(t, ux); + ux &= 0xfffffffff8000000; + PUT_BITS_DP64(ux, hx); + tx = t - hx; + v1 = t * t; + v2 = (((hx * hx - v1) + hx * tx) + tx * hx) + tx * tx; + + /* dekker_add2(u1,0.0,v1,v2,&w1,&w2); */ + r = u1 + v1; + s = (((u1 - r) + v1) + v2); + w1 = r + s; + w2 = (r - w1) + s; + + /* dekker_sqrt2(w1,w2,&u1,&u2); */ + ASMSQRT(w1, p1); + GET_BITS_DP64(p1, ux); + ux &= 0xfffffffff8000000; + PUT_BITS_DP64(ux, c1); + c2 = p1 - c1; + a1 = p1 * p1; + a2 = (((c1 * c1 - a1) + c1 * c2) + c2 * c1) + c2 * c2; + p2 = (((w1 - a1) - a2) + w2) * 0.5 / p1; + u1 = p1 + p2; + u2 = (p1 - u1) + p2; + + /* dekker_add2(u1,u2,t,0.0,&v1,&v2); */ + r = u1 + t; + s = (((u1 - r) + t)) + u2; + r1 = r + s; + r2 = (r - r1) + s; + t = r1 + r2; + + /* Check for x close to 1.0. */ + if (x < 1.13) + { + /* Here 1.0 <= x < 1.13 implies r <= 0.656. In this region + we need to take extra care to maintain precision. + We have t = r1 + r2 = (x - 1.0 + sqrt(x*x-1.0)) + to more than basic precision. We use the Taylor series + for log(1+x), with terms after the O(x*x) term + approximated by a [6,6] minimax polynomial. */ + double b1, b2, c1, c2, e1, e2, q1, q2, c, cc, hr1, tr1, hpoly, tpoly, hq1, tq1, hr2, tr2; + poly = + (0.30893760556597282162e-21 + + (0.10513858797132174471e0 + + (0.27834538302122012381e0 + + (0.27223638654807468186e0 + + (0.12038958198848174570e0 + + (0.23357202004546870613e-1 + + (0.15208417992520237648e-2 + + 0.72741030690878441996e-7 * t) * t) * t) * t) * t) * t) * t) / + (0.31541576391396523486e0 + + (0.10715979719991342022e1 + + (0.14311581802952004012e1 + + (0.94928647994421895988e0 + + (0.32396235926176348977e0 + + (0.52566134756985833588e-1 + + 0.30477895574211444963e-2 * t) * t) * t) * t) * t) * t); + + /* Now we can compute the result r = acosh(x) = log1p(t) + using the formula t - 0.5*t*t + poly*t*t. Since t is + represented as r1+r2, the formula becomes + r = r1+r2 - 0.5*(r1+r2)*(r1+r2) + poly*(r1+r2)*(r1+r2). + Expanding out, we get + r = r1 + r2 - (0.5 + poly)*(r1*r1 + 2*r1*r2 + r2*r2) + and ignoring negligible quantities we get + r = r1 + r2 - 0.5*r1*r1 + r1*r2 + poly*t*t + */ + if (x < 1.06) + { + double b, c, e; + b = r1 * r2; + c = 0.5 * r1 * r1; + e = poly * t * t; + /* N.B. the order of additions and subtractions is important */ + r = (((r2 - b) + e) - c) + r1; + return r; + } + else + { + /* For 1.06 <= x <= 1.13 we must evaluate in extended precision + to reach about 1 ulp accuracy (in this range the simple code + above only manages about 1.5 ulp accuracy) */ + + /* Split poly, r1 and r2 into head and tail sections */ + GET_BITS_DP64(poly, ux); + ux &= 0xfffffffff8000000; + PUT_BITS_DP64(ux, hpoly); + tpoly = poly - hpoly; + GET_BITS_DP64(r1, ux); + ux &= 0xfffffffff8000000; + PUT_BITS_DP64(ux, hr1); + tr1 = r1 - hr1; + GET_BITS_DP64(r2, ux); + ux &= 0xfffffffff8000000; + PUT_BITS_DP64(ux, hr2); + tr2 = r2 - hr2; + + /* e = poly*t*t */ + c = poly * r1; + cc = (((hpoly * hr1 - c) + hpoly * tr1) + tpoly * hr1) + tpoly * tr1; + cc = poly * r2 + cc; + q1 = c + cc; + q2 = (c - q1) + cc; + GET_BITS_DP64(q1, ux); + ux &= 0xfffffffff8000000; + PUT_BITS_DP64(ux, hq1); + tq1 = q1 - hq1; + c = q1 * r1; + cc = (((hq1 * hr1 - c) + hq1 * tr1) + tq1 * hr1) + tq1 * tr1; + cc = q1 * r2 + q2 * r1 + cc; + e1 = c + cc; + e2 = (c - e1) + cc; + + /* b = r1*r2 */ + b1 = r1 * r2; + b2 = (((hr1 * hr2 - b1) + hr1 * tr2) + tr1 * hr2) + tr1 * tr2; + + /* c = 0.5*r1*r1 */ + c1 = (0.5 * r1) * r1; + c2 = (((0.5 * hr1 * hr1 - c1) + 0.5 * hr1 * tr1) + 0.5 * tr1 * hr1) + 0.5 * tr1 * tr1; + + /* v = a + d - b */ + r = r1 - b1; + s = (((r1 - r) - b1) - b2) + r2; + v1 = r + s; + v2 = (r - v1) + s; + + /* w = (a + d - b) - c */ + r = v1 - c1; + s = (((v1 - r) - c1) - c2) + v2; + w1 = r + s; + w2 = (r - w1) + s; + + /* u = ((a + d - b) - c) + e */ + r = w1 + e1; + s = (((w1 - r) + e1) + e2) + w2; + u1 = r + s; + u2 = (r - u1) + s; + + /* The result r = acosh(x) */ + r = u1 + u2; + + return r; + } + } + else + { + /* For arguments 1.13 <= x <= 1.5 the log1p function + is good enough */ + return FN_PROTOTYPE(log1p)(t); + } + } +} diff --git a/src/native/clrmath/src/ref/acoshf.cpp b/src/native/clrmath/src/ref/acoshf.cpp new file mode 100644 index 00000000000000..70e6c03ca13938 --- /dev/null +++ b/src/native/clrmath/src/ref/acoshf.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +#undef _FUNCNAME +#define _FUNCNAME "acoshf" +float FN_PROTOTYPE_REF(acoshf)(float x) +{ + + unsigned int ux; + double dx, r, rarg, t; + + static const unsigned int + recrteps = 0x46000000; /* 1/sqrt(eps) = 4.09600000000000000000e+03 */ + + static const double + log2 = 6.93147180559945286227e-01; /* 0x3fe62e42fefa39ef */ + + GET_BITS_SP32(x, ux); + + if ((ux & EXPBITS_SP32) == EXPBITS_SP32) + { + /* x is either NaN or infinity */ + if (ux & MANTBITS_SP32) + { + /* x is NaN */ +#ifdef WINDOWS + return __amd_handle_errorf(_FUNCNAME, __amd_acosh, ux | 0x00400000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0F, 1); +#else + if (ux & QNAN_MASK_32) + return __amd_handle_errorf(_FUNCNAME, __amd_acosh, ux | 0x00400000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0F, 1); + else + return __amd_handle_errorf(_FUNCNAME, __amd_acosh, ux | 0x00400000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0F, 1); +#endif + } + else + { + /* x is infinity */ + if (ux & SIGNBIT_SP32) + /* x is negative infinity. Return a NaN. */ + return __amd_handle_errorf(_FUNCNAME, __amd_acosh, INDEFBITPATT_SP32, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0F, 1); + else + /* Return positive infinity with no signal */ + return x; + } + } + else if ((ux & SIGNBIT_SP32) || (ux < 0x3f800000)) + { + /* x is less than 1.0. Return a NaN. */ + return __amd_handle_errorf(_FUNCNAME, __amd_acosh, INDEFBITPATT_SP32, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0F, 1); + } + + dx = x; + + if (ux > recrteps) + { + /* Arguments greater than 1/sqrt(epsilon) in magnitude are + approximated by acoshf(x) = ln(2) + ln(x) */ + r = FN_PROTOTYPE(log)(dx) + log2; + } + else if (ux > 0x40000000) + { + /* 2.0 <= x <= 1/sqrt(epsilon) */ + /* acoshf for these arguments is approximated by + acoshf(x) = ln(x + sqrt(x*x-1)) */ + rarg = dx * dx - 1.0; + /* Use assembly instruction to compute r = sqrt(rarg); */ + ASMSQRT(rarg, r); + rarg = r + dx; + r = FN_PROTOTYPE(log)(rarg); + } + else + { + /* sqrt(epsilon) <= x <= 2.0 */ + t = dx - 1.0; + rarg = 2.0 * t + t * t; + ASMSQRT(rarg, r); /* r = sqrt(rarg) */ + rarg = t + r; + r = FN_PROTOTYPE(log1p)(rarg); + } + return (float)(r); +} diff --git a/src/native/clrmath/src/ref/asin.cpp b/src/native/clrmath/src/ref/asin.cpp new file mode 100644 index 00000000000000..18e9b40b48a38c --- /dev/null +++ b/src/native/clrmath/src/ref/asin.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +double FN_PROTOTYPE_REF(asin)(double x) +{ + /* Computes arcsin(x). + The argument is first reduced by noting that arcsin(x) + is invalid for abs(x) > 1 and arcsin(-x) = -arcsin(x). + For denormal and small arguments arcsin(x) = x to machine + accuracy. Remaining argument ranges are handled as follows. + For abs(x) <= 0.5 use + arcsin(x) = x + x^3*R(x^2) + where R(x^2) is a rational minimax approximation to + (arcsin(x) - x)/x^3. + For abs(x) > 0.5 exploit the identity: + arcsin(x) = pi/2 - 2*arcsin(sqrt(1-x)/2) + together with the above rational approximation, and + reconstruct the terms carefully. + */ + + /* Some constants and split constants. */ + + static const double + piby2_tail = 6.1232339957367660e-17, /* 0x3c91a62633145c07 */ + hpiby2_head = 7.8539816339744831e-01, /* 0x3fe921fb54442d18 */ + piby2 = 1.5707963267948965e+00; /* 0x3ff921fb54442d18 */ + double u, v, y, s = 0.0, r; + int xexp, xnan, transform = 0; + + unsigned long long ux, aux, xneg; + GET_BITS_DP64(x, ux); + aux = ux & ~SIGNBIT_DP64; + xneg = (ux & SIGNBIT_DP64); + xnan = (aux > PINFBITPATT_DP64); + xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; + + /* Special cases */ + + if (xnan) + { +#ifdef WINDOWS + return __amd_handle_error("asin", __amd_asin, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); +#else + //return x + x; /* With invalid if it's a signalling NaN */ + if (ux & QNAN_MASK_64) + return __amd_handle_error("asin", __amd_asin, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); + else + return __amd_handle_error("asin", __amd_asin, ux | 0x0008000000000000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); +#endif + } + else if (xexp < -28) + { /* y small enough that arcsin(x) = x */ +#ifdef WINDOWS + return x; //val_with_flags(x, AMD_F_INEXACT); +#else + if ((ux == SIGNBIT_DP64) || (ux == 0x0)) + return x; + else + return __amd_handle_error("asin", __amd_asin, ux, _UNDERFLOW, AMD_F_UNDERFLOW | AMD_F_INEXACT, ERANGE, x, 0.0, 1); +#endif + } + else if (xexp >= 0) + { /* abs(x) >= 1.0 */ + if (x == 1.0) + return piby2; //val_with_flags(piby2, AMD_F_INEXACT); + else if (x == -1.0) + return -piby2;//val_with_flags(-piby2, AMD_F_INEXACT); + else +#ifdef WINDOWS + return __amd_handle_error("asin", __amd_asin, INDEFBITPATT_DP64, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); +#else + //return retval_errno_edom(x); + return __amd_handle_error("asin", __amd_asin, INDEFBITPATT_DP64, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); +#endif + } + + if (xneg) y = -x; + else y = x; + + transform = (xexp >= -1); /* abs(x) >= 0.5 */ + + if (transform) + { /* Transform y into the range [0,0.5) */ + r = 0.5 * (1.0 - y); + ASMSQRT(r, s); + y = s; + } + else + r = y * y; + + /* Use a rational approximation for [0.0, 0.5] */ + + u = r * (0.227485835556935010735943483075 + + (-0.445017216867635649900123110649 + + (0.275558175256937652532686256258 + + (-0.0549989809235685841612020091328 + + (0.00109242697235074662306043804220 + + 0.0000482901920344786991880522822991 * r) * r) * r) * r) * r) / + (1.36491501334161032038194214209 + + (-3.28431505720958658909889444194 + + (2.76568859157270989520376345954 + + (-0.943639137032492685763471240072 + + 0.105869422087204370341222318533 * r) * r) * r) * r); + + if (transform) + { /* Reconstruct asin carefully in transformed region */ + { + double c, s1, p, q; + unsigned long long us; + GET_BITS_DP64(s, us); + PUT_BITS_DP64(0xffffffff00000000 & us, s1); + c = (r - s1 * s1) / (s + s1); + p = 2.0 * s * u - (piby2_tail - 2.0 * c); + q = hpiby2_head - 2.0 * s1; + v = hpiby2_head - (p - q); + } + } + else + { +#ifdef WINDOWS + /* Use a temporary variable to prevent VC++ rearranging + y + y*u + into + y * (1 + u) + and getting an incorrectly rounded result */ + double tmp; + tmp = y * u; + v = y + tmp; +#else + v = y + y * u; +#endif + } + + if (xneg) return -v; + else return v; +} diff --git a/src/native/clrmath/src/ref/asinf.cpp b/src/native/clrmath/src/ref/asinf.cpp new file mode 100644 index 00000000000000..15427c13710e55 --- /dev/null +++ b/src/native/clrmath/src/ref/asinf.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +float FN_PROTOTYPE_REF(asinf)(float x) +{ + /* Computes arcsin(x). + The argument is first reduced by noting that arcsin(x) + is invalid for abs(x) > 1 and arcsin(-x) = -arcsin(x). + For denormal and small arguments arcsin(x) = x to machine + accuracy. Remaining argument ranges are handled as follows. + For abs(x) <= 0.5 use + arcsin(x) = x + x^3*R(x^2) + where R(x^2) is a rational minimax approximation to + (arcsin(x) - x)/x^3. + For abs(x) > 0.5 exploit the identity: + arcsin(x) = pi/2 - 2*arcsin(sqrt(1-x)/2) + together with the above rational approximation, and + reconstruct the terms carefully. + */ + + /* Some constants and split constants. */ + + static const float + piby2_tail = 7.5497894159e-08F, /* 0x33a22168 */ + hpiby2_head = 7.8539812565e-01F, /* 0x3f490fda */ + piby2 = 1.5707963705e+00F; /* 0x3fc90fdb */ + float u, v, y, s = 0.0F, r; + int xexp, xnan, transform = 0; + + unsigned int ux, aux, xneg; + GET_BITS_SP32(x, ux); + aux = ux & ~SIGNBIT_SP32; + xneg = (ux & SIGNBIT_SP32); + xnan = (aux > PINFBITPATT_SP32); + xexp = (int)((ux & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; + + /* Special cases */ + + if (xnan) + { +#ifdef WINDOWS + return __amd_handle_errorf("asinf", __amd_asin, ux | 0x00400000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0F, 1); +#else + //return x + x; /* With invalid if it's a signalling NaN */ + if (ux & QNAN_MASK_32) + return __amd_handle_errorf("asinf", __amd_asin, ux | 0x00400000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0F, 1); + else + return __amd_handle_errorf("asinf", __amd_asin, ux | 0x00400000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0F, 1); +#endif + } + else if (xexp < -14) + { + /* y small enough that arcsin(x) = x */ +#ifdef WINDOWS + return x;//valf_with_flags(x, AMD_F_INEXACT); +#else + if ((ux == SIGNBIT_SP32) || (ux == 0x0)) + return x; + else + return __amd_handle_errorf("asinf", __amd_asin, ux, _UNDERFLOW, AMD_F_UNDERFLOW | AMD_F_INEXACT, EDOM, x, 0.0F, 1); +#endif + } + else if (xexp >= 0) + { + /* abs(x) >= 1.0 */ + if (x == 1.0F) + return piby2; //valf_with_flags(piby2, AMD_F_INEXACT); + else if (x == -1.0F) + return -piby2; //valf_with_flags(-piby2, AMD_F_INEXACT); + else +#ifdef WINDOWS + return __amd_handle_errorf("asinf", __amd_asin, INDEFBITPATT_SP32, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0F, 1); +#else + return __amd_handle_errorf("asinf", __amd_asin, INDEFBITPATT_SP32, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0F, 1); + //return retval_errno_edom(x); +#endif + } + + if (xneg) y = -x; + else y = x; + + transform = (xexp >= -1); /* abs(x) >= 0.5 */ + + if (transform) + { /* Transform y into the range [0,0.5) */ + r = 0.5F * (1.0F - y); + ASMSQRTF(r, s); + y = s; + } + else + r = y * y; + + /* Use a rational approximation for [0.0, 0.5] */ + + u = r * (0.184161606965100694821398249421F + + (-0.0565298683201845211985026327361F + + (-0.0133819288943925804214011424456F - + 0.00396137437848476485201154797087F * r) * r) * r) / + (1.10496961524520294485512696706F - + 0.836411276854206731913362287293F * r); + + if (transform) + { + /* Reconstruct asin carefully in transformed region */ + float c, s1, p, q; + unsigned int us; + GET_BITS_SP32(s, us); + PUT_BITS_SP32(0xffff0000 & us, s1); + c = (r - s1 * s1) / (s + s1); + p = 2.0F * s * u - (piby2_tail - 2.0F * c); + q = hpiby2_head - 2.0F * s1; + v = hpiby2_head - (p - q); + } + else + { +#ifdef WINDOWS + /* Use a temporary variable to prevent VC++ rearranging + y + y*u + into + y * (1 + u) + and getting an incorrectly rounded result */ + float tmp; + tmp = y * u; + v = y + tmp; +#else + v = y + y * u; +#endif + } + + if (xneg) return -v; + else return v; +} diff --git a/src/native/clrmath/src/ref/asinh.cpp b/src/native/clrmath/src/ref/asinh.cpp new file mode 100644 index 00000000000000..f46a2534959859 --- /dev/null +++ b/src/native/clrmath/src/ref/asinh.cpp @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_inlines.h" + +#undef _FUNCNAME +#define _FUNCNAME "asinh" +double FN_PROTOTYPE_REF(asinh)(double x) +{ + + unsigned long long ux, ax, xneg; + double absx, r, rarg, t, r1, r2, poly, s, v1, v2; + int xexp; + + static const unsigned long long + rteps = 0x3e46a09e667f3bcd, /* sqrt(eps) = 1.05367121277235086670e-08 */ + recrteps = 0x4196a09e667f3bcd; /* 1/rteps = 9.49062656242515593767e+07 */ + + /* log2_lead and log2_tail sum to an extra-precise version + of log(2) */ + static const double + log2_lead = 6.93147122859954833984e-01, /* 0x3fe62e42e0000000 */ + log2_tail = 5.76999904754328540596e-08; /* 0x3e6efa39ef35793c */ + + + GET_BITS_DP64(x, ux); + ax = ux & ~SIGNBIT_DP64; + xneg = ux & SIGNBIT_DP64; + PUT_BITS_DP64(ax, absx); + + if ((ux & EXPBITS_DP64) == EXPBITS_DP64) + { + /* x is either NaN or infinity */ + if (ux & MANTBITS_DP64) + { +#ifdef WINDOWS + /* x is NaN */ + return __amd_handle_error("asinh", __amd_asinh, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); +#else + if (ux & QNAN_MASK_64) + return __amd_handle_error("asinh", __amd_asinh, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); + else + return __amd_handle_error("asinh", __amd_asinh, ux | 0x0008000000000000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); +#endif + } + else + { + /* x is infinity. Return the same infinity. */ + return x; + } + } + else if (ax < rteps) /* abs(x) < sqrt(epsilon) */ + { + if (ax == 0x0000000000000000) + { + /* x is +/-zero. Return the same zero. */ + return x; + } + else + { + /* Tiny arguments approximated by asinh(x) = x + - avoid slow operations on denormalized numbers */ +#ifdef WINDOWS + return x; //return val_with_flags(x,AMD_F_INEXACT); +#else + return __amd_handle_error("asinh", __amd_asinh, ux, _UNDERFLOW, AMD_F_UNDERFLOW | AMD_F_INEXACT, ERANGE, x, 0.0, 1); +#endif + } + } + + + if (ax <= 0x3ff0000000000000) /* abs(x) <= 1.0 */ + { + /* Arguments less than 1.0 in magnitude are + approximated by [4,4] or [5,4] minimax polynomials + fitted to asinh series 4.6.31 (x < 1) from Abramowitz and Stegun + */ + t = x * x; + if (ax < 0x3fd0000000000000) + { + /* [4,4] for 0 < abs(x) < 0.25 */ + poly = + (-0.12845379283524906084997e0 + + (-0.21060688498409799700819e0 + + (-0.10188951822578188309186e0 + + (-0.13891765817243625541799e-1 - + 0.10324604871728082428024e-3 * t) * t) * t) * t) / + (0.77072275701149440164511e0 + + (0.16104665505597338100747e1 + + (0.11296034614816689554875e1 + + (0.30079351943799465092429e0 + + 0.235224464765951442265117e-1 * t) * t) * t) * t); + } + else if (ax < 0x3fe0000000000000) + { + /* [4,4] for 0.25 <= abs(x) < 0.5 */ + poly = + (-0.12186605129448852495563e0 + + (-0.19777978436593069928318e0 + + (-0.94379072395062374824320e-1 + + (-0.12620141363821680162036e-1 - + 0.903396794842691998748349e-4 * t) * t) * t) * t) / + (0.73119630776696495279434e0 + + (0.15157170446881616648338e1 + + (0.10524909506981282725413e1 + + (0.27663713103600182193817e0 + + 0.21263492900663656707646e-1 * t) * t) * t) * t); + } + else if (ax < 0x3fe8000000000000) + { + /* [4,4] for 0.5 <= abs(x) < 0.75 */ + poly = + (-0.81210026327726247622500e-1 + + (-0.12327355080668808750232e0 + + (-0.53704925162784720405664e-1 + + (-0.63106739048128554465450e-2 - + 0.35326896180771371053534e-4 * t) * t) * t) * t) / + (0.48726015805581794231182e0 + + (0.95890837357081041150936e0 + + (0.62322223426940387752480e0 + + (0.15028684818508081155141e0 + + 0.10302171620320141529445e-1 * t) * t) * t) * t); + } + else + { + /* [5,4] for 0.75 <= abs(x) <= 1.0 */ + poly = + (-0.4638179204422665073e-1 + + (-0.7162729496035415183e-1 + + (-0.3247795155696775148e-1 + + (-0.4225785421291932164e-2 + + (-0.3808984717603160127e-4 + + 0.8023464184964125826e-6 * t) * t) * t) * t) * t) / + (0.2782907534642231184e0 + + (0.5549945896829343308e0 + + (0.3700732511330698879e0 + + (0.9395783438240780722e-1 + + 0.7200057974217143034e-2 * t) * t) * t) * t); + } + return x + x * t * poly; + } + else if (ax < 0x4040000000000000) + { + /* 1.0 <= abs(x) <= 32.0 */ + /* Arguments in this region are approximated by various + minimax polynomials fitted to asinh series 4.6.31 + in Abramowitz and Stegun. + */ + t = x * x; + if (ax >= 0x4020000000000000) + { + /* [3,3] for 8.0 <= abs(x) <= 32.0 */ + poly = + (-0.538003743384069117e-10 + + (-0.273698654196756169e-9 + + (-0.268129826956403568e-9 - + 0.804163374628432850e-29 * t) * t) * t) / + (0.238083376363471960e-9 + + (0.203579344621125934e-8 + + (0.450836980450693209e-8 + + 0.286005148753497156e-8 * t) * t) * t); + } + else if (ax >= 0x4010000000000000) + { + /* [4,3] for 4.0 <= abs(x) <= 8.0 */ + poly = + (-0.178284193496441400e-6 + + (-0.928734186616614974e-6 + + (-0.923318925566302615e-6 + + (-0.776417026702577552e-19 + + 0.290845644810826014e-21 * t) * t) * t) * t) / + (0.786694697277890964e-6 + + (0.685435665630965488e-5 + + (0.153780175436788329e-4 + + 0.984873520613417917e-5 * t) * t) * t); + + } + else if (ax >= 0x4000000000000000) + { + /* [5,4] for 2.0 <= abs(x) <= 4.0 */ + poly = + (-0.209689451648100728e-6 + + (-0.219252358028695992e-5 + + (-0.551641756327550939e-5 + + (-0.382300259826830258e-5 + + (-0.421182121910667329e-17 + + 0.492236019998237684e-19 * t) * t) * t) * t) * t) / + (0.889178444424237735e-6 + + (0.131152171690011152e-4 + + (0.537955850185616847e-4 + + (0.814966175170941864e-4 + + 0.407786943832260752e-4 * t) * t) * t) * t); + } + else if (ax >= 0x3ff8000000000000) + { + /* [5,4] for 1.5 <= abs(x) <= 2.0 */ + poly = + (-0.195436610112717345e-4 + + (-0.233315515113382977e-3 + + (-0.645380957611087587e-3 + + (-0.478948863920281252e-3 + + (-0.805234112224091742e-12 + + 0.246428598194879283e-13 * t) * t) * t) * t) * t) / + (0.822166621698664729e-4 + + (0.135346265620413852e-2 + + (0.602739242861830658e-2 + + (0.972227795510722956e-2 + + 0.510878800983771167e-2 * t) * t) * t) * t); + } + else + { + /* [5,5] for 1.0 <= abs(x) <= 1.5 */ + poly = + (-0.121224194072430701e-4 + + (-0.273145455834305218e-3 + + (-0.152866982560895737e-2 + + (-0.292231744584913045e-2 + + (-0.174670900236060220e-2 - + 0.891754209521081538e-12 * t) * t) * t) * t) * t) / + (0.499426632161317606e-4 + + (0.139591210395547054e-2 + + (0.107665231109108629e-1 + + (0.325809818749873406e-1 + + (0.415222526655158363e-1 + + 0.186315628774716763e-1 * t) * t) * t) * t) * t); + } + log_kernel_amd64(absx, ax, &xexp, &r1, &r2); + r1 = ((xexp + 1) * log2_lead + r1); + r2 = ((xexp + 1) * log2_tail + r2); + /* Now (r1,r2) sum to log(2x). Add the term + 1/(2.2.x^2) = 0.25/t, and add poly/t, carefully + to maintain precision. (Note that we add poly/t + rather than poly because of the *x factor used + when generating the minimax polynomial) */ + v2 = (poly + 0.25) / t; + r = v2 + r1; + s = ((r1 - r) + v2) + r2; + v1 = r + s; + v2 = (r - v1) + s; + r = v1 + v2; + if (xneg) + return -r; + else + return r; + } + else + { + /* abs(x) > 32.0 */ + if (ax > recrteps) + { + /* Arguments greater than 1/sqrt(epsilon) in magnitude are + approximated by asinh(x) = ln(2) + ln(abs(x)), with sign of x */ + /* log_kernel_amd(x) returns xexp, r1, r2 such that + log(x) = xexp*log(2) + r1 + r2 */ + log_kernel_amd64(absx, ax, &xexp, &r1, &r2); + /* Add (xexp+1) * log(2) to z1,z2 to get the result asinh(x). + The computed r1 is not subject to rounding error because + (xexp+1) has at most 10 significant bits, log(2) has 24 significant + bits, and r1 has up to 24 bits; and the exponents of r1 + and r2 differ by at most 6. */ + r1 = ((xexp + 1) * log2_lead + r1); + r2 = ((xexp + 1) * log2_tail + r2); + if (xneg) + return -(r1 + r2); + else + return r1 + r2; + } + else + { + rarg = absx * absx + 1.0; + /* Arguments such that 32.0 <= abs(x) <= 1/sqrt(epsilon) are + approximated by + asinh(x) = ln(abs(x) + sqrt(x*x+1)) + with the sign of x (see Abramowitz and Stegun 4.6.20) */ + /* Use assembly instruction to compute r = sqrt(rarg); */ + ASMSQRT(rarg, r); + r += absx; + GET_BITS_DP64(r, ax); + log_kernel_amd64(r, ax, &xexp, &r1, &r2); + r1 = (xexp * log2_lead + r1); + r2 = (xexp * log2_tail + r2); + if (xneg) + return -(r1 + r2); + else + return r1 + r2; + } + } +} diff --git a/src/native/clrmath/src/ref/asinhf.cpp b/src/native/clrmath/src/ref/asinhf.cpp new file mode 100644 index 00000000000000..1b91d916685c2f --- /dev/null +++ b/src/native/clrmath/src/ref/asinhf.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +#undef _FUNCNAME +#define _FUNCNAME "asinhf" +float FN_PROTOTYPE_REF(asinhf)(float x) +{ + + double dx; + unsigned int ux, ax, xneg; + double absx, r, rarg, t, poly; + + static const unsigned int + rteps = 0x39800000, /* sqrt(eps) = 2.44140625000000000000e-04 */ + recrteps = 0x46000000; /* 1/rteps = 4.09600000000000000000e+03 */ + + static const double + log2 = 6.93147180559945286227e-01; /* 0x3fe62e42fefa39ef */ + + GET_BITS_SP32(x, ux); + ax = ux & ~SIGNBIT_SP32; + xneg = ux & SIGNBIT_SP32; + + if ((ux & EXPBITS_SP32) == EXPBITS_SP32) + { + /* x is either NaN or infinity */ + if (ux & MANTBITS_SP32) + { + /* x is NaN */ +#ifdef WINDOWS + return __amd_handle_errorf(_FUNCNAME, __amd_asinh, ux | 0x00400000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0F, 1); +#else + if (ux & QNAN_MASK_32) + return __amd_handle_errorf(_FUNCNAME, __amd_asinh, ux | 0x00400000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0F, 1); + else + return __amd_handle_errorf(_FUNCNAME, __amd_asinh, ux | 0x00400000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0F, 1); +#endif + } + else + { + /* x is infinity. Return the same infinity. */ + return x; + } + } + else if (ax < rteps) /* abs(x) < sqrt(epsilon) */ + { + if (ax == 0x00000000) + { + /* x is +/-zero. Return the same zero. */ + return x; + } + else + { + /* Tiny arguments approximated by asinhf(x) = x + - avoid slow operations on denormalized numbers */ +#ifdef WINDOWS + return x; //return valf_with_flags(x,AMD_F_INEXACT); +#else + return __amd_handle_errorf(_FUNCNAME, __amd_asinh, ux, _UNDERFLOW, AMD_F_UNDERFLOW | AMD_F_INEXACT, ERANGE, x, 0.0F, 1); +#endif + } + } + + dx = x; + if (xneg) + absx = -dx; + else + absx = dx; + + if (ax <= 0x40800000) /* abs(x) <= 4.0 */ + { + /* Arguments less than 4.0 in magnitude are + approximated by [4,4] minimax polynomials + */ + t = dx * dx; + if (ax <= 0x40000000) /* abs(x) <= 2 */ + poly = + (-0.1152965835871758072e-1 + + (-0.1480204186473758321e-1 + + (-0.5063201055468483248e-2 + + (-0.4162727710583425360e-3 - + 0.1177198915954942694e-5 * t) * t) * t) * t) / + (0.6917795026025976739e-1 + + (0.1199423176003939087e+0 + + (0.6582362487198468066e-1 + + (0.1260024978680227945e-1 + + 0.6284381367285534560e-3 * t) * t) * t) * t); + else + poly = + (-0.185462290695578589e-2 + + (-0.113672533502734019e-2 + + (-0.142208387300570402e-3 + + (-0.339546014993079977e-5 - + 0.151054665394480990e-8 * t) * t) * t) * t) / + (0.111486158580024771e-1 + + (0.117782437980439561e-1 + + (0.325903773532674833e-2 + + (0.255902049924065424e-3 + + 0.434150786948890837e-5 * t) * t) * t) * t); + return (float)(dx + dx * t * poly); + } + else + { + /* abs(x) > 4.0 */ + if (ax > recrteps) + { + /* Arguments greater than 1/sqrt(epsilon) in magnitude are + approximated by asinhf(x) = ln(2) + ln(abs(x)), with sign of x */ + r = FN_PROTOTYPE(log)(absx) + log2; + } + else + { + rarg = absx * absx + 1.0; + /* Arguments such that 4.0 <= abs(x) <= 1/sqrt(epsilon) are + approximated by + asinhf(x) = ln(abs(x) + sqrt(x*x+1)) + with the sign of x (see Abramowitz and Stegun 4.6.20) */ + /* Use assembly instruction to compute r = sqrt(rarg); */ + ASMSQRT(rarg, r); + r += absx; + r = FN_PROTOTYPE(log)(r); + } + if (xneg) + return (float)(-r); + else + return (float)r; + } +} diff --git a/src/native/clrmath/src/ref/atan.cpp b/src/native/clrmath/src/ref/atan.cpp new file mode 100644 index 00000000000000..bd87b42bcc3e7e --- /dev/null +++ b/src/native/clrmath/src/ref/atan.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +double FN_PROTOTYPE_REF(atan)(double x) +{ + + /* Some constants and split constants. */ + + static double piby2 = 1.5707963267948966e+00; /* 0x3ff921fb54442d18 */ + double chi, clo, v, s, q, z; + + /* Find properties of argument x. */ + + unsigned long long ux, aux, xneg; + GET_BITS_DP64(x, ux); + aux = ux & ~SIGNBIT_DP64; + xneg = (ux != aux); + + if (xneg) v = -x; + else v = x; + + /* Argument reduction to range [-7/16,7/16] */ + + if (aux < 0x3e50000000000000) /* v < 2.0^(-26) */ + { + /* x is a good approximation to atan(x) and avoids working on + intermediate denormal numbers */ + if (aux == 0x0000000000000000) + return x; + else +#ifdef WINDOWS + return x; //val_with_flags(x, AMD_F_INEXACT); +#else + return __amd_handle_error("atan", __amd_atan, ux, _UNDERFLOW, AMD_F_UNDERFLOW | AMD_F_INEXACT, ERANGE, x, 0.0, 1); +#endif + } + else if (aux > 0x4003800000000000) /* v > 39./16. */ + { + + if (aux > PINFBITPATT_DP64) + { + /* x is NaN */ +#ifdef WINDOWS + return __amd_handle_error("atan", __amd_atan, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); +#else + return x + x; /* Raise invalid if it's a signalling NaN */ +#endif + } + else if (aux > 0x4370000000000000) + { /* abs(x) > 2^56 => arctan(1/x) is + insignificant compared to piby2 */ + if (xneg) + return -piby2;//val_with_flags(-piby2, AMD_F_INEXACT); + else + return piby2;//val_with_flags(piby2, AMD_F_INEXACT); + } + + x = -1.0 / v; + /* (chi + clo) = arctan(infinity) */ + chi = 1.57079632679489655800e+00; /* 0x3ff921fb54442d18 */ + clo = 6.12323399573676480327e-17; /* 0x3c91a62633145c06 */ + } + else if (aux > 0x3ff3000000000000) /* 39./16. > v > 19./16. */ + { + x = (v - 1.5) / (1.0 + 1.5 * v); + /* (chi + clo) = arctan(1.5) */ + chi = 9.82793723247329054082e-01; /* 0x3fef730bd281f69b */ + clo = 1.39033110312309953701e-17; /* 0x3c7007887af0cbbc */ + } + else if (aux > 0x3fe6000000000000) /* 19./16. > v > 11./16. */ + { + x = (v - 1.0) / (1.0 + v); + /* (chi + clo) = arctan(1.) */ + chi = 7.85398163397448278999e-01; /* 0x3fe921fb54442d18 */ + clo = 3.06161699786838240164e-17; /* 0x3c81a62633145c06 */ + } + else if (aux > 0x3fdc000000000000) /* 11./16. > v > 7./16. */ + { + x = (2.0 * v - 1.0) / (2.0 + v); + /* (chi + clo) = arctan(0.5) */ + chi = 4.63647609000806093515e-01; /* 0x3fddac670561bb4f */ + clo = 2.26987774529616809294e-17; /* 0x3c7a2b7f222f65e0 */ + } + else /* v < 7./16. */ + { + x = v; + chi = 0.0; + clo = 0.0; + } + + /* Core approximation: Remez(4,4) on [-7/16,7/16] */ + + s = x * x; + q = x * s * + (0.268297920532545909e0 + + (0.447677206805497472e0 + + (0.220638780716667420e0 + + (0.304455919504853031e-1 + + 0.142316903342317766e-3 * s) * s) * s) * s) / + (0.804893761597637733e0 + + (0.182596787737507063e1 + + (0.141254259931958921e1 + + (0.424602594203847109e0 + + 0.389525873944742195e-1 * s) * s) * s) * s); + + z = chi - ((q - clo) - x); + + if (xneg) z = -z; + return z; +} diff --git a/src/native/clrmath/src/ref/atan2.cpp b/src/native/clrmath/src/ref/atan2.cpp new file mode 100644 index 00000000000000..11020c4c64edb3 --- /dev/null +++ b/src/native/clrmath/src/ref/atan2.cpp @@ -0,0 +1,748 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_inlines.h" + +double FN_PROTOTYPE_REF(atan2)(double y, double x) +{ + /* Arrays atan_jby256_lead and atan_jby256_tail contain + leading and trailing parts respectively of precomputed + values of atan(j/256), for j = 16, 17, ..., 256. + atan_jby256_lead contains the first 21 bits of precision, + and atan_jby256_tail contains a further 53 bits precision. */ + + static const double atan_jby256_lead[241] = { + 6.24187886714935302734e-02, /* 0x3faff55b00000000 */ + 6.63088560104370117188e-02, /* 0x3fb0f99e00000000 */ + 7.01969265937805175781e-02, /* 0x3fb1f86d00000000 */ + 7.40829110145568847656e-02, /* 0x3fb2f71900000000 */ + 7.79666304588317871094e-02, /* 0x3fb3f59f00000000 */ + 8.18479657173156738281e-02, /* 0x3fb4f3fd00000000 */ + 8.57268571853637695312e-02, /* 0x3fb5f23200000000 */ + 8.96031260490417480469e-02, /* 0x3fb6f03b00000000 */ + 9.34767723083496093750e-02, /* 0x3fb7ee1800000000 */ + 9.73475575447082519531e-02, /* 0x3fb8ebc500000000 */ + 1.01215422153472900391e-01, /* 0x3fb9e94100000000 */ + 1.05080246925354003906e-01, /* 0x3fbae68a00000000 */ + 1.08941912651062011719e-01, /* 0x3fbbe39e00000000 */ + 1.12800359725952148438e-01, /* 0x3fbce07c00000000 */ + 1.16655409336090087891e-01, /* 0x3fbddd2100000000 */ + 1.20507001876831054688e-01, /* 0x3fbed98c00000000 */ + 1.24354958534240722656e-01, /* 0x3fbfd5ba00000000 */ + 1.28199219703674316406e-01, /* 0x3fc068d500000000 */ + 1.32039666175842285156e-01, /* 0x3fc0e6ad00000000 */ + 1.35876297950744628906e-01, /* 0x3fc1646500000000 */ + 1.39708757400512695312e-01, /* 0x3fc1e1fa00000000 */ + 1.43537282943725585938e-01, /* 0x3fc25f6e00000000 */ + 1.47361397743225097656e-01, /* 0x3fc2dcbd00000000 */ + 1.51181221008300781250e-01, /* 0x3fc359e800000000 */ + 1.54996633529663085938e-01, /* 0x3fc3d6ee00000000 */ + 1.58807516098022460938e-01, /* 0x3fc453ce00000000 */ + 1.62613749504089355469e-01, /* 0x3fc4d08700000000 */ + 1.66415214538574218750e-01, /* 0x3fc54d1800000000 */ + 1.70211911201477050781e-01, /* 0x3fc5c98100000000 */ + 1.74003481864929199219e-01, /* 0x3fc645bf00000000 */ + 1.77790164947509765625e-01, /* 0x3fc6c1d400000000 */ + 1.81571602821350097656e-01, /* 0x3fc73dbd00000000 */ + 1.85347914695739746094e-01, /* 0x3fc7b97b00000000 */ + 1.89118742942810058594e-01, /* 0x3fc8350b00000000 */ + 1.92884206771850585938e-01, /* 0x3fc8b06e00000000 */ + 1.96644186973571777344e-01, /* 0x3fc92ba300000000 */ + 2.00398445129394531250e-01, /* 0x3fc9a6a800000000 */ + 2.04147100448608398438e-01, /* 0x3fca217e00000000 */ + 2.07889914512634277344e-01, /* 0x3fca9c2300000000 */ + 2.11626768112182617188e-01, /* 0x3fcb169600000000 */ + 2.15357661247253417969e-01, /* 0x3fcb90d700000000 */ + 2.19082474708557128906e-01, /* 0x3fcc0ae500000000 */ + 2.22801089286804199219e-01, /* 0x3fcc84bf00000000 */ + 2.26513504981994628906e-01, /* 0x3fccfe6500000000 */ + 2.30219483375549316406e-01, /* 0x3fcd77d500000000 */ + 2.33919143676757812500e-01, /* 0x3fcdf11000000000 */ + 2.37612247467041015625e-01, /* 0x3fce6a1400000000 */ + 2.41298794746398925781e-01, /* 0x3fcee2e100000000 */ + 2.44978547096252441406e-01, /* 0x3fcf5b7500000000 */ + 2.48651623725891113281e-01, /* 0x3fcfd3d100000000 */ + 2.52317905426025390625e-01, /* 0x3fd025fa00000000 */ + 2.55977153778076171875e-01, /* 0x3fd061ee00000000 */ + 2.59629487991333007812e-01, /* 0x3fd09dc500000000 */ + 2.63274669647216796875e-01, /* 0x3fd0d97e00000000 */ + 2.66912937164306640625e-01, /* 0x3fd1151a00000000 */ + 2.70543813705444335938e-01, /* 0x3fd1509700000000 */ + 2.74167299270629882812e-01, /* 0x3fd18bf500000000 */ + 2.77783632278442382812e-01, /* 0x3fd1c73500000000 */ + 2.81392335891723632812e-01, /* 0x3fd2025500000000 */ + 2.84993648529052734375e-01, /* 0x3fd23d5600000000 */ + 2.88587331771850585938e-01, /* 0x3fd2783700000000 */ + 2.92173147201538085938e-01, /* 0x3fd2b2f700000000 */ + 2.95751571655273437500e-01, /* 0x3fd2ed9800000000 */ + 2.99322128295898437500e-01, /* 0x3fd3281800000000 */ + 3.02884817123413085938e-01, /* 0x3fd3627700000000 */ + 3.06439399719238281250e-01, /* 0x3fd39cb400000000 */ + 3.09986352920532226562e-01, /* 0x3fd3d6d100000000 */ + 3.13524961471557617188e-01, /* 0x3fd410cb00000000 */ + 3.17055702209472656250e-01, /* 0x3fd44aa400000000 */ + 3.20578098297119140625e-01, /* 0x3fd4845a00000000 */ + 3.24092388153076171875e-01, /* 0x3fd4bdee00000000 */ + 3.27598333358764648438e-01, /* 0x3fd4f75f00000000 */ + 3.31095933914184570312e-01, /* 0x3fd530ad00000000 */ + 3.34585189819335937500e-01, /* 0x3fd569d800000000 */ + 3.38066101074218750000e-01, /* 0x3fd5a2e000000000 */ + 3.41538190841674804688e-01, /* 0x3fd5dbc300000000 */ + 3.45002174377441406250e-01, /* 0x3fd6148400000000 */ + 3.48457098007202148438e-01, /* 0x3fd64d1f00000000 */ + 3.51903676986694335938e-01, /* 0x3fd6859700000000 */ + 3.55341434478759765625e-01, /* 0x3fd6bdea00000000 */ + 3.58770608901977539062e-01, /* 0x3fd6f61900000000 */ + 3.62190723419189453125e-01, /* 0x3fd72e2200000000 */ + 3.65602254867553710938e-01, /* 0x3fd7660700000000 */ + 3.69004726409912109375e-01, /* 0x3fd79dc600000000 */ + 3.72398376464843750000e-01, /* 0x3fd7d56000000000 */ + 3.75782966613769531250e-01, /* 0x3fd80cd400000000 */ + 3.79158496856689453125e-01, /* 0x3fd8442200000000 */ + 3.82525205612182617188e-01, /* 0x3fd87b4b00000000 */ + 3.85882616043090820312e-01, /* 0x3fd8b24d00000000 */ + 3.89230966567993164062e-01, /* 0x3fd8e92900000000 */ + 3.92570018768310546875e-01, /* 0x3fd91fde00000000 */ + 3.95900011062622070312e-01, /* 0x3fd9566d00000000 */ + 3.99220705032348632812e-01, /* 0x3fd98cd500000000 */ + 4.02532100677490234375e-01, /* 0x3fd9c31600000000 */ + 4.05834197998046875000e-01, /* 0x3fd9f93000000000 */ + 4.09126996994018554688e-01, /* 0x3fda2f2300000000 */ + 4.12410259246826171875e-01, /* 0x3fda64ee00000000 */ + 4.15684223175048828125e-01, /* 0x3fda9a9200000000 */ + 4.18948888778686523438e-01, /* 0x3fdad00f00000000 */ + 4.22204017639160156250e-01, /* 0x3fdb056400000000 */ + 4.25449609756469726562e-01, /* 0x3fdb3a9100000000 */ + 4.28685665130615234375e-01, /* 0x3fdb6f9600000000 */ + 4.31912183761596679688e-01, /* 0x3fdba47300000000 */ + 4.35129165649414062500e-01, /* 0x3fdbd92800000000 */ + 4.38336372375488281250e-01, /* 0x3fdc0db400000000 */ + 4.41534280776977539062e-01, /* 0x3fdc421900000000 */ + 4.44722414016723632812e-01, /* 0x3fdc765500000000 */ + 4.47900772094726562500e-01, /* 0x3fdcaa6800000000 */ + 4.51069593429565429688e-01, /* 0x3fdcde5300000000 */ + 4.54228639602661132812e-01, /* 0x3fdd121500000000 */ + 4.57377910614013671875e-01, /* 0x3fdd45ae00000000 */ + 4.60517644882202148438e-01, /* 0x3fdd791f00000000 */ + 4.63647603988647460938e-01, /* 0x3fddac6700000000 */ + 4.66767549514770507812e-01, /* 0x3fdddf8500000000 */ + 4.69877958297729492188e-01, /* 0x3fde127b00000000 */ + 4.72978591918945312500e-01, /* 0x3fde454800000000 */ + 4.76069211959838867188e-01, /* 0x3fde77eb00000000 */ + 4.79150056838989257812e-01, /* 0x3fdeaa6500000000 */ + 4.82221126556396484375e-01, /* 0x3fdedcb600000000 */ + 4.85282421112060546875e-01, /* 0x3fdf0ede00000000 */ + 4.88333940505981445312e-01, /* 0x3fdf40dd00000000 */ + 4.91375446319580078125e-01, /* 0x3fdf72b200000000 */ + 4.94406938552856445312e-01, /* 0x3fdfa45d00000000 */ + 4.97428894042968750000e-01, /* 0x3fdfd5e000000000 */ + 5.00440597534179687500e-01, /* 0x3fe0039c00000000 */ + 5.03442764282226562500e-01, /* 0x3fe01c3400000000 */ + 5.06434917449951171875e-01, /* 0x3fe034b700000000 */ + 5.09417057037353515625e-01, /* 0x3fe04d2500000000 */ + 5.12389183044433593750e-01, /* 0x3fe0657e00000000 */ + 5.15351772308349609375e-01, /* 0x3fe07dc300000000 */ + 5.18304347991943359375e-01, /* 0x3fe095f300000000 */ + 5.21246910095214843750e-01, /* 0x3fe0ae0e00000000 */ + 5.24179458618164062500e-01, /* 0x3fe0c61400000000 */ + 5.27101993560791015625e-01, /* 0x3fe0de0500000000 */ + 5.30014991760253906250e-01, /* 0x3fe0f5e200000000 */ + 5.32917976379394531250e-01, /* 0x3fe10daa00000000 */ + 5.35810947418212890625e-01, /* 0x3fe1255d00000000 */ + 5.38693904876708984375e-01, /* 0x3fe13cfb00000000 */ + 5.41567325592041015625e-01, /* 0x3fe1548500000000 */ + 5.44430732727050781250e-01, /* 0x3fe16bfa00000000 */ + 5.47284126281738281250e-01, /* 0x3fe1835a00000000 */ + 5.50127506256103515625e-01, /* 0x3fe19aa500000000 */ + 5.52961349487304687500e-01, /* 0x3fe1b1dc00000000 */ + 5.55785179138183593750e-01, /* 0x3fe1c8fe00000000 */ + 5.58598995208740234375e-01, /* 0x3fe1e00b00000000 */ + 5.61403274536132812500e-01, /* 0x3fe1f70400000000 */ + 5.64197540283203125000e-01, /* 0x3fe20de800000000 */ + 5.66981792449951171875e-01, /* 0x3fe224b700000000 */ + 5.69756031036376953125e-01, /* 0x3fe23b7100000000 */ + 5.72520732879638671875e-01, /* 0x3fe2521700000000 */ + 5.75275897979736328125e-01, /* 0x3fe268a900000000 */ + 5.78021049499511718750e-01, /* 0x3fe27f2600000000 */ + 5.80756187438964843750e-01, /* 0x3fe2958e00000000 */ + 5.83481788635253906250e-01, /* 0x3fe2abe200000000 */ + 5.86197376251220703125e-01, /* 0x3fe2c22100000000 */ + 5.88903427124023437500e-01, /* 0x3fe2d84c00000000 */ + 5.91599464416503906250e-01, /* 0x3fe2ee6200000000 */ + 5.94285964965820312500e-01, /* 0x3fe3046400000000 */ + 5.96962928771972656250e-01, /* 0x3fe31a5200000000 */ + 5.99629878997802734375e-01, /* 0x3fe3302b00000000 */ + 6.02287292480468750000e-01, /* 0x3fe345f000000000 */ + 6.04934692382812500000e-01, /* 0x3fe35ba000000000 */ + 6.07573032379150390625e-01, /* 0x3fe3713d00000000 */ + 6.10201358795166015625e-01, /* 0x3fe386c500000000 */ + 6.12820148468017578125e-01, /* 0x3fe39c3900000000 */ + 6.15428924560546875000e-01, /* 0x3fe3b19800000000 */ + 6.18028640747070312500e-01, /* 0x3fe3c6e400000000 */ + 6.20618820190429687500e-01, /* 0x3fe3dc1c00000000 */ + 6.23198986053466796875e-01, /* 0x3fe3f13f00000000 */ + 6.25770092010498046875e-01, /* 0x3fe4064f00000000 */ + 6.28331184387207031250e-01, /* 0x3fe41b4a00000000 */ + 6.30883216857910156250e-01, /* 0x3fe4303200000000 */ + 6.33425712585449218750e-01, /* 0x3fe4450600000000 */ + 6.35958671569824218750e-01, /* 0x3fe459c600000000 */ + 6.38482093811035156250e-01, /* 0x3fe46e7200000000 */ + 6.40995979309082031250e-01, /* 0x3fe4830a00000000 */ + 6.43500804901123046875e-01, /* 0x3fe4978f00000000 */ + 6.45996093750000000000e-01, /* 0x3fe4ac0000000000 */ + 6.48482322692871093750e-01, /* 0x3fe4c05e00000000 */ + 6.50959014892578125000e-01, /* 0x3fe4d4a800000000 */ + 6.53426170349121093750e-01, /* 0x3fe4e8de00000000 */ + 6.55884265899658203125e-01, /* 0x3fe4fd0100000000 */ + 6.58332824707031250000e-01, /* 0x3fe5111000000000 */ + 6.60772323608398437500e-01, /* 0x3fe5250c00000000 */ + 6.63202762603759765625e-01, /* 0x3fe538f500000000 */ + 6.65623664855957031250e-01, /* 0x3fe54cca00000000 */ + 6.68035984039306640625e-01, /* 0x3fe5608d00000000 */ + 6.70438766479492187500e-01, /* 0x3fe5743c00000000 */ + 6.72832489013671875000e-01, /* 0x3fe587d800000000 */ + 6.75216674804687500000e-01, /* 0x3fe59b6000000000 */ + 6.77592277526855468750e-01, /* 0x3fe5aed600000000 */ + 6.79958820343017578125e-01, /* 0x3fe5c23900000000 */ + 6.82316303253173828125e-01, /* 0x3fe5d58900000000 */ + 6.84664726257324218750e-01, /* 0x3fe5e8c600000000 */ + 6.87004089355468750000e-01, /* 0x3fe5fbf000000000 */ + 6.89334869384765625000e-01, /* 0x3fe60f0800000000 */ + 6.91656589508056640625e-01, /* 0x3fe6220d00000000 */ + 6.93969249725341796875e-01, /* 0x3fe634ff00000000 */ + 6.96272850036621093750e-01, /* 0x3fe647de00000000 */ + 6.98567867279052734375e-01, /* 0x3fe65aab00000000 */ + 7.00854301452636718750e-01, /* 0x3fe66d6600000000 */ + 7.03131675720214843750e-01, /* 0x3fe6800e00000000 */ + 7.05400466918945312500e-01, /* 0x3fe692a400000000 */ + 7.07660198211669921875e-01, /* 0x3fe6a52700000000 */ + 7.09911346435546875000e-01, /* 0x3fe6b79800000000 */ + 7.12153911590576171875e-01, /* 0x3fe6c9f700000000 */ + 7.14387893676757812500e-01, /* 0x3fe6dc4400000000 */ + 7.16613292694091796875e-01, /* 0x3fe6ee7f00000000 */ + 7.18829631805419921875e-01, /* 0x3fe700a700000000 */ + 7.21037864685058593750e-01, /* 0x3fe712be00000000 */ + 7.23237514495849609375e-01, /* 0x3fe724c300000000 */ + 7.25428581237792968750e-01, /* 0x3fe736b600000000 */ + 7.27611064910888671875e-01, /* 0x3fe7489700000000 */ + 7.29785442352294921875e-01, /* 0x3fe75a6700000000 */ + 7.31950759887695312500e-01, /* 0x3fe76c2400000000 */ + 7.34108448028564453125e-01, /* 0x3fe77dd100000000 */ + 7.36257076263427734375e-01, /* 0x3fe78f6b00000000 */ + 7.38397598266601562500e-01, /* 0x3fe7a0f400000000 */ + 7.40530014038085937500e-01, /* 0x3fe7b26c00000000 */ + 7.42654323577880859375e-01, /* 0x3fe7c3d300000000 */ + 7.44770050048828125000e-01, /* 0x3fe7d52800000000 */ + 7.46877670288085937500e-01, /* 0x3fe7e66c00000000 */ + 7.48976707458496093750e-01, /* 0x3fe7f79e00000000 */ + 7.51068115234375000000e-01, /* 0x3fe808c000000000 */ + 7.53150939941406250000e-01, /* 0x3fe819d000000000 */ + 7.55226135253906250000e-01, /* 0x3fe82ad000000000 */ + 7.57292747497558593750e-01, /* 0x3fe83bbe00000000 */ + 7.59351730346679687500e-01, /* 0x3fe84c9c00000000 */ + 7.61402606964111328125e-01, /* 0x3fe85d6900000000 */ + 7.63445377349853515625e-01, /* 0x3fe86e2500000000 */ + 7.65480041503906250000e-01, /* 0x3fe87ed000000000 */ + 7.67507076263427734375e-01, /* 0x3fe88f6b00000000 */ + 7.69526004791259765625e-01, /* 0x3fe89ff500000000 */ + 7.71537303924560546875e-01, /* 0x3fe8b06f00000000 */ + 7.73540973663330078125e-01, /* 0x3fe8c0d900000000 */ + 7.75536537170410156250e-01, /* 0x3fe8d13200000000 */ + 7.77523994445800781250e-01, /* 0x3fe8e17a00000000 */ + 7.79504299163818359375e-01, /* 0x3fe8f1b300000000 */ + 7.81476497650146484375e-01, /* 0x3fe901db00000000 */ + 7.83441066741943359375e-01, /* 0x3fe911f300000000 */ + 7.85398006439208984375e-01 }; /* 0x3fe921fb00000000 */ + + static const double atan_jby256_tail[241] = { + 2.13244638182005395671e-08, /* 0x3e56e59fbd38db2c */ + 3.89093864761712760656e-08, /* 0x3e64e3aa54dedf96 */ + 4.44780900009437454576e-08, /* 0x3e67e105ab1bda88 */ + 1.15344768460112754160e-08, /* 0x3e48c5254d013fd0 */ + 3.37271051945395312705e-09, /* 0x3e2cf8ab3ad62670 */ + 2.40857608736109859459e-08, /* 0x3e59dca4bec80468 */ + 1.85853810450623807768e-08, /* 0x3e53f4b5ec98a8da */ + 5.14358299969225078306e-08, /* 0x3e6b9d49619d81fe */ + 8.85023985412952486748e-09, /* 0x3e43017887460934 */ + 1.59425154214358432060e-08, /* 0x3e511e3eca0b9944 */ + 1.95139937737755753164e-08, /* 0x3e54f3f73c5a332e */ + 2.64909755273544319715e-08, /* 0x3e5c71c8ae0e00a6 */ + 4.43388037881231070144e-08, /* 0x3e67cde0f86fbdc7 */ + 2.14757072421821274557e-08, /* 0x3e570f328c889c72 */ + 2.61049792670754218852e-08, /* 0x3e5c07ae9b994efe */ + 7.81439350674466302231e-09, /* 0x3e40c8021d7b1698 */ + 3.60125207123751024094e-08, /* 0x3e635585edb8cb22 */ + 6.15276238179343767917e-08, /* 0x3e70842567b30e96 */ + 9.54387964641184285058e-08, /* 0x3e799e811031472e */ + 3.02789566851502754129e-08, /* 0x3e6041821416bcee */ + 1.16888650949870856331e-07, /* 0x3e7f6086e4dc96f4 */ + 1.07580956468653338863e-08, /* 0x3e471a535c5f1b58 */ + 8.33454265379535427653e-08, /* 0x3e765f743fe63ca1 */ + 1.10790279272629526068e-07, /* 0x3e7dbd733472d014 */ + 1.08394277896366207424e-07, /* 0x3e7d18cc4d8b0d1d */ + 9.22176086126841098800e-08, /* 0x3e78c12553c8fb29 */ + 7.90938592199048786990e-08, /* 0x3e753b49e2e8f991 */ + 8.66445407164293125637e-08, /* 0x3e77422ae148c141 */ + 1.40839973537092438671e-08, /* 0x3e4e3ec269df56a8 */ + 1.19070438507307600689e-07, /* 0x3e7ff6754e7e0ac9 */ + 6.40451663051716197071e-08, /* 0x3e7131267b1b5aad */ + 1.08338682076343674522e-07, /* 0x3e7d14fa403a94bc */ + 3.52999550187922736222e-08, /* 0x3e62f396c089a3d8 */ + 1.05983273930043077202e-07, /* 0x3e7c731d78fa95bb */ + 1.05486124078259553339e-07, /* 0x3e7c50f385177399 */ + 5.82167732281776477773e-08, /* 0x3e6f41409c6f2c20 */ + 1.08696483983403942633e-07, /* 0x3e7d2d90c4c39ec0 */ + 4.47335086122377542835e-08, /* 0x3e680420696f2106 */ + 1.26896287162615723528e-08, /* 0x3e4b40327943a2e8 */ + 4.06534471589151404531e-08, /* 0x3e65d35e02f3d2a2 */ + 3.84504846300557026690e-08, /* 0x3e64a498288117b0 */ + 3.60715006404807269080e-08, /* 0x3e635da119afb324 */ + 6.44725903165522722801e-08, /* 0x3e714e85cdb9a908 */ + 3.63749249976409461305e-08, /* 0x3e638754e5547b9a */ + 1.03901294413833913794e-07, /* 0x3e7be40ae6ce3246 */ + 6.25379756302167880580e-08, /* 0x3e70c993b3bea7e7 */ + 6.63984302368488828029e-08, /* 0x3e71d2dd89ac3359 */ + 3.21844598971548278059e-08, /* 0x3e61476603332c46 */ + 1.16030611712765830905e-07, /* 0x3e7f25901bac55b7 */ + 1.17464622142347730134e-07, /* 0x3e7f881b7c826e28 */ + 7.54604017965808996596e-08, /* 0x3e7441996d698d20 */ + 1.49234929356206556899e-07, /* 0x3e8407ac521ea089 */ + 1.41416924523217430259e-07, /* 0x3e82fb0c6c4b1723 */ + 2.13308065617483489011e-07, /* 0x3e8ca135966a3e18 */ + 5.04230937933302320146e-08, /* 0x3e6b1218e4d646e4 */ + 5.45874922281655519035e-08, /* 0x3e6d4e72a350d288 */ + 1.51849028914786868886e-07, /* 0x3e84617e2f04c329 */ + 3.09004308703769273010e-08, /* 0x3e6096ec41e82650 */ + 9.67574548184738317664e-08, /* 0x3e79f91f25773e6e */ + 4.02508285529322212824e-08, /* 0x3e659c0820f1d674 */ + 3.01222268096861091157e-08, /* 0x3e602bf7a2df1064 */ + 2.36189860670079288680e-07, /* 0x3e8fb36bfc40508f */ + 1.14095158111080887695e-07, /* 0x3e7ea08f3f8dc892 */ + 7.42349089746573467487e-08, /* 0x3e73ed6254656a0e */ + 5.12515583196230380184e-08, /* 0x3e6b83f5e5e69c58 */ + 2.19290391828763918102e-07, /* 0x3e8d6ec2af768592 */ + 3.83263512187553886471e-08, /* 0x3e6493889a226f94 */ + 1.61513486284090523855e-07, /* 0x3e85ad8fa65279ba */ + 5.09996743535589922261e-08, /* 0x3e6b615784d45434 */ + 1.23694037861246766534e-07, /* 0x3e809a184368f145 */ + 8.23367955351123783984e-08, /* 0x3e761a2439b0d91c */ + 1.07591766213053694014e-07, /* 0x3e7ce1a65e39a978 */ + 1.42789947524631815640e-07, /* 0x3e832a39a93b6a66 */ + 1.32347123024711878538e-07, /* 0x3e81c3699af804e7 */ + 2.17626067316598149229e-08, /* 0x3e575e0f4e44ede8 */ + 2.34454866923044288656e-07, /* 0x3e8f77ced1a7a83b */ + 2.82966370261766916053e-09, /* 0x3e284e7f0cb1b500 */ + 2.29300919890907632975e-07, /* 0x3e8ec6b838b02dfe */ + 1.48428270450261284915e-07, /* 0x3e83ebf4dfbeda87 */ + 1.87937408574313982512e-07, /* 0x3e89397aed9cb475 */ + 6.13685946813334055347e-08, /* 0x3e707937bc239c54 */ + 1.98585022733583817493e-07, /* 0x3e8aa754553131b6 */ + 7.68394131623752961662e-08, /* 0x3e74a05d407c45dc */ + 1.28119052312436745644e-07, /* 0x3e8132231a206dd0 */ + 7.02119104719236502733e-08, /* 0x3e72d8ecfdd69c88 */ + 9.87954793820636301943e-08, /* 0x3e7a852c74218606 */ + 1.72176752381034986217e-07, /* 0x3e871bf2baeebb50 */ + 1.12877225146169704119e-08, /* 0x3e483d7db7491820 */ + 5.33549829555851737993e-08, /* 0x3e6ca50d92b6da14 */ + 2.13833275710816521345e-08, /* 0x3e56f5cde8530298 */ + 1.16243518048290556393e-07, /* 0x3e7f343198910740 */ + 6.29926408369055877943e-08, /* 0x3e70e8d241ccd80a */ + 6.45429039328021963791e-08, /* 0x3e71535ac619e6c8 */ + 8.64001922814281933403e-08, /* 0x3e77316041c36cd2 */ + 9.50767572202325800240e-08, /* 0x3e7985a000637d8e */ + 5.80851497508121135975e-08, /* 0x3e6f2f29858c0a68 */ + 1.82350561135024766232e-07, /* 0x3e8879847f96d909 */ + 1.98948680587390608655e-07, /* 0x3e8ab3d319e12e42 */ + 7.83548663450197659846e-08, /* 0x3e75088162dfc4c2 */ + 3.04374234486798594427e-08, /* 0x3e605749a1cd9d8c */ + 2.76135725629797411787e-08, /* 0x3e5da65c6c6b8618 */ + 4.32610105454203065470e-08, /* 0x3e6739bf7df1ad64 */ + 5.17107515324127256994e-08, /* 0x3e6bc31252aa3340 */ + 2.82398327875841444660e-08, /* 0x3e5e528191ad3aa8 */ + 1.87482469524195595399e-07, /* 0x3e8929d93df19f18 */ + 2.97481891662714096139e-08, /* 0x3e5ff11eb693a080 */ + 9.94421570843584316402e-09, /* 0x3e455ae3f145a3a0 */ + 1.07056210730391848428e-07, /* 0x3e7cbcd8c6c0ca82 */ + 6.25589580466881163081e-08, /* 0x3e70cb04d425d304 */ + 9.56641013869464593803e-08, /* 0x3e79adfcab5be678 */ + 1.88056307148355440276e-07, /* 0x3e893d90c5662508 */ + 8.38850689379557880950e-08, /* 0x3e768489bd35ff40 */ + 5.01215865527674122924e-09, /* 0x3e3586ed3da2b7e0 */ + 1.74166095998522089762e-07, /* 0x3e87604d2e850eee */ + 9.96779574395363585849e-08, /* 0x3e7ac1d12bfb53d8 */ + 5.98432026368321460686e-09, /* 0x3e39b3d468274740 */ + 1.18362922366887577169e-07, /* 0x3e7fc5d68d10e53c */ + 1.86086833284154215946e-07, /* 0x3e88f9e51884becb */ + 1.97671457251348941011e-07, /* 0x3e8a87f0869c06d1 */ + 1.42447160717199237159e-07, /* 0x3e831e7279f685fa */ + 1.05504240785546574184e-08, /* 0x3e46a8282f9719b0 */ + 3.13335218371639189324e-08, /* 0x3e60d2724a8a44e0 */ + 1.96518418901914535399e-07, /* 0x3e8a60524b11ad4e */ + 2.17692035039173536059e-08, /* 0x3e575fdf832750f0 */ + 2.15613114426529981675e-07, /* 0x3e8cf06902e4cd36 */ + 5.68271098300441214948e-08, /* 0x3e6e82422d4f6d10 */ + 1.70331455823369124256e-08, /* 0x3e524a091063e6c0 */ + 9.17590028095709583247e-08, /* 0x3e78a1a172dc6f38 */ + 2.77266304112916566247e-07, /* 0x3e929b6619f8a92d */ + 9.37041937614656939690e-08, /* 0x3e79274d9c1b70c8 */ + 1.56116346368316796511e-08, /* 0x3e50c34b1fbb7930 */ + 4.13967433808382727413e-08, /* 0x3e6639866c20eb50 */ + 1.70164749185821616276e-07, /* 0x3e86d6d0f6832e9e */ + 4.01708788545600086008e-07, /* 0x3e9af54def99f25e */ + 2.59663539226050551563e-07, /* 0x3e916cfc52a00262 */ + 2.22007487655027469542e-07, /* 0x3e8dcc1e83569c32 */ + 2.90542250809644081369e-07, /* 0x3e937f7a551ed425 */ + 4.67720537666628903341e-07, /* 0x3e9f6360adc98887 */ + 2.79799803956772554802e-07, /* 0x3e92c6ec8d35a2c1 */ + 2.07344552327432547723e-07, /* 0x3e8bd44df84cb036 */ + 2.54705698692735196368e-07, /* 0x3e9117cf826e310e */ + 4.26848589539548450728e-07, /* 0x3e9ca533f332cfc9 */ + 2.52506723633552216197e-07, /* 0x3e90f208509dbc2e */ + 2.14684129933849704964e-07, /* 0x3e8cd07d93c945de */ + 3.20134822201596505431e-07, /* 0x3e957bdfd67e6d72 */ + 9.93537565749855712134e-08, /* 0x3e7aab89c516c658 */ + 3.70792944827917252327e-08, /* 0x3e63e823b1a1b8a0 */ + 1.41772749369083698972e-07, /* 0x3e8307464a9d6d3c */ + 4.22446601490198804306e-07, /* 0x3e9c5993cd438843 */ + 4.11818433724801511540e-07, /* 0x3e9ba2fca02ab554 */ + 1.19976381502605310519e-07, /* 0x3e801a5b6983a268 */ + 3.43703078571520905265e-08, /* 0x3e6273d1b350efc8 */ + 1.66128705555453270379e-07, /* 0x3e864c238c37b0c6 */ + 5.00499610023283006540e-08, /* 0x3e6aded07370a300 */ + 1.75105139941208062123e-07, /* 0x3e878091197eb47e */ + 7.70807146729030327334e-08, /* 0x3e74b0f245e0dabc */ + 2.45918607526895836121e-07, /* 0x3e9080d9794e2eaf */ + 2.18359020958626199345e-07, /* 0x3e8d4ec242b60c76 */ + 8.44342887976445333569e-09, /* 0x3e4221d2f940caa0 */ + 1.07506148687888629299e-07, /* 0x3e7cdbc42b2bba5c */ + 5.36544954316820904572e-08, /* 0x3e6cce37bb440840 */ + 3.39109101518396596341e-07, /* 0x3e96c1d999cf1dd0 */ + 2.60098720293920613340e-08, /* 0x3e5bed8a07eb0870 */ + 8.42678991664621455827e-08, /* 0x3e769ed88f490e3c */ + 5.36972237470183633197e-08, /* 0x3e6cd41719b73ef0 */ + 4.28192558171921681288e-07, /* 0x3e9cbc4ac95b41b7 */ + 2.71535491483955143294e-07, /* 0x3e9238f1b890f5d7 */ + 7.84094998145075780203e-08, /* 0x3e750c4282259cc4 */ + 3.43880599134117431863e-07, /* 0x3e9713d2de87b3e2 */ + 1.32878065060366481043e-07, /* 0x3e81d5a7d2255276 */ + 4.18046802627967629428e-07, /* 0x3e9c0dfd48227ac1 */ + 2.65042411765766019424e-07, /* 0x3e91c964dab76753 */ + 1.70383695347518643694e-07, /* 0x3e86de56d5704496 */ + 1.54096497259613515678e-07, /* 0x3e84aeb71fd19968 */ + 2.36543402412459813461e-07, /* 0x3e8fbf91c57b1918 */ + 4.38416350106876736790e-07, /* 0x3e9d6bef7fbe5d9a */ + 3.03892161339927775731e-07, /* 0x3e9464d3dc249066 */ + 3.31136771605664899240e-07, /* 0x3e9638e2ec4d9073 */ + 6.49494294526590682218e-08, /* 0x3e716f4a7247ea7c */ + 4.10423429887181345747e-09, /* 0x3e31a0a740f1d440 */ + 1.70831640869113847224e-07, /* 0x3e86edbb0114a33c */ + 1.10811512657909180966e-07, /* 0x3e7dbee8bf1d513c */ + 3.23677724749783611964e-07, /* 0x3e95b8bdb0248f73 */ + 3.55662734259192678528e-07, /* 0x3e97de3d3f5eac64 */ + 2.30102333489738219140e-07, /* 0x3e8ee24187ae448a */ + 4.47429004000738629714e-07, /* 0x3e9e06c591ec5192 */ + 7.78167135617329598659e-08, /* 0x3e74e3861a332738 */ + 9.90345291908535415737e-08, /* 0x3e7a9599dcc2bfe4 */ + 5.85800913143113728314e-08, /* 0x3e6f732fbad43468 */ + 4.57859062410871843857e-07, /* 0x3e9eb9f573b727d9 */ + 3.67993069723390929794e-07, /* 0x3e98b212a2eb9897 */ + 2.90836464322977276043e-07, /* 0x3e9384884c167215 */ + 2.51621574250131388318e-07, /* 0x3e90e2d363020051 */ + 2.75789824740652815545e-07, /* 0x3e92820879fbd022 */ + 3.88985776250314403593e-07, /* 0x3e9a1ab9893e4b30 */ + 1.40214080183768019611e-07, /* 0x3e82d1b817a24478 */ + 3.23451432223550478373e-08, /* 0x3e615d7b8ded4878 */ + 9.15979180730608444470e-08, /* 0x3e78968f9db3a5e4 */ + 3.44371402498640470421e-07, /* 0x3e971c4171fe135f */ + 3.40401897215059498077e-07, /* 0x3e96d80f605d0d8c */ + 1.06431813453707950243e-07, /* 0x3e7c91f043691590 */ + 1.46204238932338846248e-07, /* 0x3e839f8a15fce2b2 */ + 9.94610376972039046878e-09, /* 0x3e455beda9d94b80 */ + 2.01711528092681771039e-07, /* 0x3e8b12c15d60949a */ + 2.72027977986191568296e-07, /* 0x3e924167b312bfe3 */ + 2.48402602511693757964e-07, /* 0x3e90ab8633070277 */ + 1.58480011219249621715e-07, /* 0x3e854554ebbc80ee */ + 3.00372828113368713281e-08, /* 0x3e60204aef5a4bb8 */ + 3.67816204583541976394e-07, /* 0x3e98af08c679cf2c */ + 2.46169793032343824291e-07, /* 0x3e90852a330ae6c8 */ + 1.70080468270204253247e-07, /* 0x3e86d3eb9ec32916 */ + 1.67806717763872914315e-07, /* 0x3e8685cb7fcbbafe */ + 2.67715622006907942620e-07, /* 0x3e91f751c1e0bd95 */ + 2.14411342550299170574e-08, /* 0x3e5705b1b0f72560 */ + 4.11228221283669073277e-07, /* 0x3e9b98d8d808ca92 */ + 3.52311752396749662260e-08, /* 0x3e62ea22c75cc980 */ + 3.52718000397367821054e-07, /* 0x3e97aba62bca0350 */ + 4.38857387992911129814e-07, /* 0x3e9d73833442278c */ + 3.22574606753482540743e-07, /* 0x3e95a5ca1fb18bf9 */ + 3.28730371182804296828e-08, /* 0x3e61a6092b6ecf28 */ + 7.56672470607639279700e-08, /* 0x3e744fd049aac104 */ + 3.26750155316369681821e-09, /* 0x3e2c114fd8df5180 */ + 3.21724445362095284743e-07, /* 0x3e95972f130feae5 */ + 1.06639427371776571151e-07, /* 0x3e7ca034a55fe198 */ + 3.41020788139524715063e-07, /* 0x3e96e2b149990227 */ + 1.00582838631232552824e-07, /* 0x3e7b00000294592c */ + 3.68439433859276640065e-07, /* 0x3e98b9bdc442620e */ + 2.20403078342388012027e-07, /* 0x3e8d94fdfabf3e4e */ + 1.62841467098298142534e-07, /* 0x3e85db30b145ad9a */ + 2.25325348296680733838e-07, /* 0x3e8e3e1eb95022b0 */ + 4.37462238226421614339e-07, /* 0x3e9d5b8b45442bd6 */ + 3.52055880555040706500e-07, /* 0x3e97a046231ecd2e */ + 4.75614398494781776825e-07, /* 0x3e9feafe3ef55232 */ + 3.60998399033215317516e-07, /* 0x3e9839e7bfd78267 */ + 3.79292434611513945954e-08, /* 0x3e645cf49d6fa900 */ + 1.29859015528549300061e-08, /* 0x3e4be3132b27f380 */ + 3.15927546985474913188e-07, /* 0x3e9533980bb84f9f */ + 2.28533679887379668031e-08, /* 0x3e5889e2ce3ba390 */ + 1.17222541823553133877e-07, /* 0x3e7f7778c3ad0cc8 */ + 1.51991208405464415857e-07, /* 0x3e846660cec4eba2 */ + 1.56958239325240655564e-07 }; /* 0x3e85110b4611a626 */ + + /* Some constants and split constants. */ + + static double pi = 3.1415926535897932e+00, /* 0x400921fb54442d18 */ + piby2 = 1.5707963267948966e+00, /* 0x3ff921fb54442d18 */ + piby4 = 7.8539816339744831e-01, /* 0x3fe921fb54442d18 */ + three_piby4 = 2.3561944901923449e+00, /* 0x4002d97c7f3321d2 */ + pi_head = 3.1415926218032836e+00, /* 0x400921fb50000000 */ + pi_tail = 3.1786509547056392e-08, /* 0x3e6110b4611a6263 */ + piby2_head = 1.5707963267948965e+00, /* 0x3ff921fb54442d18 */ + piby2_tail = 6.1232339957367660e-17; /* 0x3c91a62633145c07 */ + + double u, v, vbyu, q1, q2, s, u1, vu1, u2, vu2, uu, c, r; + unsigned int swap_vu, index, xzero, yzero, xnan, ynan, xinf, yinf; + int m, xexp, yexp, diffexp; + + /* Find properties of arguments x and y. */ + + unsigned long long ux, ui, aux, xneg, uy, auy, yneg; + + GET_BITS_DP64(x, ux); + GET_BITS_DP64(y, uy); + aux = ux & ~SIGNBIT_DP64; + auy = uy & ~SIGNBIT_DP64; + xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); + yexp = (int)((uy & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); + xneg = ux & SIGNBIT_DP64; + yneg = uy & SIGNBIT_DP64; + xzero = (aux == 0); + yzero = (auy == 0); + xnan = (aux > PINFBITPATT_DP64); + ynan = (auy > PINFBITPATT_DP64); + xinf = (aux == PINFBITPATT_DP64); + yinf = (auy == PINFBITPATT_DP64); + + diffexp = yexp - xexp; + + /* Special cases */ + + if (xnan) +#ifdef WINDOWS + return __amd_handle_error("atan2", __amd_atan2, ux | 0x0008000000000000, _DOMAIN, 0, + EDOM, x, y, 2); +#else + return x + x; /* Raise invalid if it's a signalling NaN */ +#endif + else if (ynan) +#ifdef WINDOWS + return __amd_handle_error("atan2", __amd_atan2, uy | 0x0008000000000000, _DOMAIN, 0, + EDOM, x, y, 2); +#else + return y + y; /* Raise invalid if it's a signalling NaN */ +#endif + else if (yzero) + { /* Zero y gives +-0 for positive x + and +-pi for negative x */ + if (xneg) + { + + if (yneg) return -pi;//return val_with_flags(-pi,AMD_F_INEXACT); + else return pi; //val_with_flags(pi,AMD_F_INEXACT); + } + else return y; + } + else if (xzero) + { /* Zero x gives +- pi/2 + depending on sign of y */ + if (yneg) return -piby2;//val_with_flags(-piby2,AMD_F_INEXACT); + else return piby2;//val_with_flags(piby2,AMD_F_INEXACT); + } + + /* Scale up both x and y if they are both below 1/4. + This avoids any possible later denormalised arithmetic. */ + + if ((xexp < 1021 && yexp < 1021)) + { + scaleUpDouble1024(ux, &ux); + scaleUpDouble1024(uy, &uy); + PUT_BITS_DP64(ux, x); + PUT_BITS_DP64(uy, y); + xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); + yexp = (int)((uy & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); + diffexp = yexp - xexp; + } + + if (diffexp > 56) + { /* abs(y)/abs(x) > 2^56 => arctan(x/y) + is insignificant compared to piby2 */ + if (yneg) return -piby2; //return val_with_flags(-piby2,AMD_F_INEXACT); + else return piby2; //return val_with_flags(piby2,AMD_F_INEXACT); + } + else if (diffexp < -28 && (!xneg)) + { /* x positive and dominant over y by a factor of 2^28. + In this case atan(y/x) is y/x to machine accuracy. */ + + if (diffexp < -1074) /* Result underflows */ + { + if (yneg) +#ifdef WINDOWS + return -0.0; //val_with_flags(-0.0,AMD_F_INEXACT | AMD_F_UNDERFLOW); + else + return 0.0; //val_with_flags(0.0,AMD_F_INEXACT | AMD_F_UNDERFLOW); +#else + return __amd_handle_error("atan2", __amd_atan2, 0x8000000000000000, _UNDERFLOW, AMD_F_INEXACT | AMD_F_UNDERFLOW, ERANGE, x, y, 2); + else + return __amd_handle_error("atan2", __amd_atan2, 0x0000000000000000, _UNDERFLOW, AMD_F_INEXACT | AMD_F_UNDERFLOW, ERANGE, x, y, 2); +#endif + } + else + { + if (diffexp < -1022) + { + /* Result will likely be denormalized */ + y = scaleDouble_1(y, 100); + y /= x; + /* Now y is 2^100 times the true result. Scale it back down. */ + GET_BITS_DP64(y, uy); + scaleDownDouble(uy, 100, &uy); + PUT_BITS_DP64(uy, y); + if ((uy & EXPBITS_DP64) == 0) + return y; // val_with_flags(y, AMD_F_INEXACT | AMD_F_UNDERFLOW); + else + return y; + } + else + return y / x; + } + } + else if (diffexp < -56 && xneg) + { /* abs(x)/abs(y) > 2^56 and x < 0 => arctan(y/x) + is insignificant compared to pi */ + if (yneg) return -pi; // return val_with_flags(-pi,AMD_F_INEXACT); + else return pi; // return val_with_flags(pi,AMD_F_INEXACT); + } + else if (yinf && xinf) + { /* If abs(x) and abs(y) are both infinity + return +-pi/4 or +- 3pi/4 according to + signs. */ + if (xneg) + { + if (yneg) return -three_piby4; // return val_with_flags(-three_piby4,AMD_F_INEXACT); + else return three_piby4;//return val_with_flags(three_piby4,AMD_F_INEXACT); + } + else + { + if (yneg) return -piby4; // return val_with_flags(-piby4,AMD_F_INEXACT); + else return piby4; //return val_with_flags(piby4,AMD_F_INEXACT); + } + } + + /* General case: take absolute values of arguments */ + + u = x; v = y; + if (xneg) u = -x; + if (yneg) v = -y; + + /* Swap u and v if necessary to obtain 0 < v < u. Compute v/u. */ + + swap_vu = (u < v); + if (swap_vu) { uu = u; u = v; v = uu; } + vbyu = v / u; + + if (vbyu > 0.0625) + { /* General values of v/u. Use a look-up + table and series expansion. */ + + index = (int)(256 * vbyu + 0.5); + q1 = atan_jby256_lead[index - 16]; + q2 = atan_jby256_tail[index - 16]; + c = index * 1. / 256; + GET_BITS_DP64(u, ui); + m = (int)((ui & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; + u = scaleDouble_2(u, -m); + v = scaleDouble_2(v, -m); + GET_BITS_DP64(u, ui); + PUT_BITS_DP64(0xfffffffff8000000 & ui, u1); /* 26 leading bits of u */ + u2 = u - u1; + + r = ((v - c * u1) - c * u2) / (u + c * v); + + /* Polynomial approximation to atan(r) */ + + s = r * r; + q2 = q2 + r - r * (s * (0.33333333333224095522 - s * (0.19999918038989143496))); + } + else if (vbyu < 1.e-8) + { /* v/u is small enough that atan(v/u) = v/u */ + q1 = 0.0; + q2 = vbyu; + } + else /* vbyu <= 0.0625 */ + { + /* Small values of v/u. Use a series expansion + computed carefully to minimise cancellation */ + + GET_BITS_DP64(u, ui); + PUT_BITS_DP64(0xffffffff00000000 & ui, u1); + GET_BITS_DP64(vbyu, ui); + PUT_BITS_DP64(0xffffffff00000000 & ui, vu1); + u2 = u - u1; + vu2 = vbyu - vu1; + + q1 = 0.0; + s = vbyu * vbyu; + q2 = vbyu + + ((((v - u1 * vu1) - u2 * vu1) - u * vu2) / u - + (vbyu * s * (0.33333333333333170500 - + s * (0.19999999999393223405 - + s * (0.14285713561807169030 - + s * (0.11110736283514525407 - + s * (0.90029810285449784439E-01))))))); + } + + /* Tidy-up according to which quadrant the arguments lie in */ + + if (swap_vu) { q1 = piby2_head - q1; q2 = piby2_tail - q2; } + if (xneg) { q1 = pi_head - q1; q2 = pi_tail - q2; } + q1 = q1 + q2; + + if (yneg) q1 = -q1; + + return q1; +} diff --git a/src/native/clrmath/src/ref/atan2f.cpp b/src/native/clrmath/src/ref/atan2f.cpp new file mode 100644 index 00000000000000..dafd9755184e4e --- /dev/null +++ b/src/native/clrmath/src/ref/atan2f.cpp @@ -0,0 +1,479 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" +#include "libm/libm_inlines.h" + +float FN_PROTOTYPE_REF(atan2f)(float fy, float fx) +{ + /* Array atan_jby256 contains precomputed values of atan(j/256), + for j = 16, 17, ..., 256. */ + + static const double atan_jby256[241] = { + 6.24188099959573430842e-02, /* 0x3faff55bb72cfde9 */ + 6.63088949198234745008e-02, /* 0x3fb0f99ea71d52a6 */ + 7.01969710718705064423e-02, /* 0x3fb1f86dbf082d58 */ + 7.40829225490337306415e-02, /* 0x3fb2f719318a4a9a */ + 7.79666338315423007588e-02, /* 0x3fb3f59f0e7c559d */ + 8.18479898030765457007e-02, /* 0x3fb4f3fd677292fb */ + 8.57268757707448092464e-02, /* 0x3fb5f2324fd2d7b2 */ + 8.96031774848717321724e-02, /* 0x3fb6f03bdcea4b0c */ + 9.34767811585894559112e-02, /* 0x3fb7ee182602f10e */ + 9.73475734872236708739e-02, /* 0x3fb8ebc54478fb28 */ + 1.01215441667466668485e-01, /* 0x3fb9e94153cfdcf1 */ + 1.05080273416329528224e-01, /* 0x3fbae68a71c722b8 */ + 1.08941956989865793015e-01, /* 0x3fbbe39ebe6f07c3 */ + 1.12800381201659388752e-01, /* 0x3fbce07c5c3cca32 */ + 1.16655435441069349478e-01, /* 0x3fbddd21701eba6e */ + 1.20507009691224548087e-01, /* 0x3fbed98c2190043a */ + 1.24354994546761424279e-01, /* 0x3fbfd5ba9aac2f6d */ + 1.28199281231298117811e-01, /* 0x3fc068d584212b3d */ + 1.32039761614638734288e-01, /* 0x3fc0e6adccf40881 */ + 1.35876328229701304195e-01, /* 0x3fc1646541060850 */ + 1.39708874289163620386e-01, /* 0x3fc1e1fafb043726 */ + 1.43537293701821222491e-01, /* 0x3fc25f6e171a535c */ + 1.47361481088651630200e-01, /* 0x3fc2dcbdb2fba1ff */ + 1.51181331798580037562e-01, /* 0x3fc359e8edeb99a3 */ + 1.54996741923940972718e-01, /* 0x3fc3d6eee8c6626c */ + 1.58807608315631065832e-01, /* 0x3fc453cec6092a9e */ + 1.62613828597948567589e-01, /* 0x3fc4d087a9da4f17 */ + 1.66415301183114927586e-01, /* 0x3fc54d18ba11570a */ + 1.70211925285474380276e-01, /* 0x3fc5c9811e3ec269 */ + 1.74003600935367680469e-01, /* 0x3fc645bfffb3aa73 */ + 1.77790228992676047071e-01, /* 0x3fc6c1d4898933d8 */ + 1.81571711160032150945e-01, /* 0x3fc73dbde8a7d201 */ + 1.85347949995694760705e-01, /* 0x3fc7b97b4bce5b02 */ + 1.89118848926083965578e-01, /* 0x3fc8350be398ebc7 */ + 1.92884312257974643856e-01, /* 0x3fc8b06ee2879c28 */ + 1.96644245190344985064e-01, /* 0x3fc92ba37d050271 */ + 2.00398553825878511514e-01, /* 0x3fc9a6a8e96c8626 */ + 2.04147145182116990236e-01, /* 0x3fca217e601081a5 */ + 2.07889927202262986272e-01, /* 0x3fca9c231b403279 */ + 2.11626808765629753628e-01, /* 0x3fcb1696574d780b */ + 2.15357699697738047551e-01, /* 0x3fcb90d7529260a2 */ + 2.19082510780057748701e-01, /* 0x3fcc0ae54d768466 */ + 2.22801153759394493514e-01, /* 0x3fcc84bf8a742e6d */ + 2.26513541356919617664e-01, /* 0x3fccfe654e1d5395 */ + 2.30219587276843717927e-01, /* 0x3fcd77d5df205736 */ + 2.33919206214733416127e-01, /* 0x3fcdf110864c9d9d */ + 2.37612313865471241892e-01, /* 0x3fce6a148e96ec4d */ + 2.41298826930858800743e-01, /* 0x3fcee2e1451d980c */ + 2.44978663126864143473e-01, /* 0x3fcf5b75f92c80dd */ + 2.48651741190513253521e-01, /* 0x3fcfd3d1fc40dbe4 */ + 2.52317980886427151166e-01, /* 0x3fd025fa510665b5 */ + 2.55977303013005474952e-01, /* 0x3fd061eea03d6290 */ + 2.59629629408257511791e-01, /* 0x3fd09dc597d86362 */ + 2.63274882955282396590e-01, /* 0x3fd0d97ee509acb3 */ + 2.66912987587400396539e-01, /* 0x3fd1151a362431c9 */ + 2.70543868292936529052e-01, /* 0x3fd150973a9ce546 */ + 2.74167451119658789338e-01, /* 0x3fd18bf5a30bf178 */ + 2.77783663178873208022e-01, /* 0x3fd1c735212dd883 */ + 2.81392432649178403370e-01, /* 0x3fd2025567e47c95 */ + 2.84993688779881237938e-01, /* 0x3fd23d562b381041 */ + 2.88587361894077354396e-01, /* 0x3fd278372057ef45 */ + 2.92173383391398755471e-01, /* 0x3fd2b2f7fd9b5fe2 */ + 2.95751685750431536626e-01, /* 0x3fd2ed987a823cfe */ + 2.99322202530807379706e-01, /* 0x3fd328184fb58951 */ + 3.02884868374971361060e-01, /* 0x3fd362773707ebcb */ + 3.06439619009630070945e-01, /* 0x3fd39cb4eb76157b */ + 3.09986391246883430384e-01, /* 0x3fd3d6d129271134 */ + 3.13525122985043869228e-01, /* 0x3fd410cbad6c7d32 */ + 3.17055753209146973237e-01, /* 0x3fd44aa436c2af09 */ + 3.20578221991156986359e-01, /* 0x3fd4845a84d0c21b */ + 3.24092470489871664618e-01, /* 0x3fd4bdee586890e6 */ + 3.27598440950530811477e-01, /* 0x3fd4f75f73869978 */ + 3.31096076704132047386e-01, /* 0x3fd530ad9951cd49 */ + 3.34585322166458920545e-01, /* 0x3fd569d88e1b4cd7 */ + 3.38066122836825466713e-01, /* 0x3fd5a2e0175e0f4e */ + 3.41538425296541714449e-01, /* 0x3fd5dbc3fbbe768d */ + 3.45002177207105076295e-01, /* 0x3fd614840309cfe1 */ + 3.48457327308122011278e-01, /* 0x3fd64d1ff635c1c5 */ + 3.51903825414964732676e-01, /* 0x3fd685979f5fa6fd */ + 3.55341622416168290144e-01, /* 0x3fd6bdeac9cbd76c */ + 3.58770670270572189509e-01, /* 0x3fd6f61941e4def0 */ + 3.62190922004212156882e-01, /* 0x3fd72e22d53aa2a9 */ + 3.65602331706966821034e-01, /* 0x3fd7660752817501 */ + 3.69004854528964421068e-01, /* 0x3fd79dc6899118d1 */ + 3.72398446676754202311e-01, /* 0x3fd7d5604b63b3f7 */ + 3.75783065409248884237e-01, /* 0x3fd80cd46a14b1d0 */ + 3.79158669033441808605e-01, /* 0x3fd84422b8df95d7 */ + 3.82525216899905096124e-01, /* 0x3fd87b4b0c1ebedb */ + 3.85882669398073752109e-01, /* 0x3fd8b24d394a1b25 */ + 3.89230987951320717144e-01, /* 0x3fd8e92916f5cde8 */ + 3.92570135011828580396e-01, /* 0x3fd91fde7cd0c662 */ + 3.95900074055262896078e-01, /* 0x3fd9566d43a34907 */ + 3.99220769575252543149e-01, /* 0x3fd98cd5454d6b18 */ + 4.02532187077682512832e-01, /* 0x3fd9c3165cc58107 */ + 4.05834293074804064450e-01, /* 0x3fd9f93066168001 */ + 4.09127055079168300278e-01, /* 0x3fda2f233e5e530b */ + 4.12410441597387267265e-01, /* 0x3fda64eec3cc23fc */ + 4.15684422123729413467e-01, /* 0x3fda9a92d59e98cf */ + 4.18948967133552840902e-01, /* 0x3fdad00f5422058b */ + 4.22204048076583571270e-01, /* 0x3fdb056420ae9343 */ + 4.25449637370042266227e-01, /* 0x3fdb3a911da65c6c */ + 4.28685708391625730496e-01, /* 0x3fdb6f962e737efb */ + 4.31912235472348193799e-01, /* 0x3fdba473378624a5 */ + 4.35129193889246812521e-01, /* 0x3fdbd9281e528191 */ + 4.38336559857957774877e-01, /* 0x3fdc0db4c94ec9ef */ + 4.41534310525166673322e-01, /* 0x3fdc42191ff11eb6 */ + 4.44722423960939305942e-01, /* 0x3fdc76550aad71f8 */ + 4.47900879150937292206e-01, /* 0x3fdcaa6872f3631b */ + 4.51069655988523443568e-01, /* 0x3fdcde53432c1350 */ + 4.54228735266762495559e-01, /* 0x3fdd121566b7f2ad */ + 4.57378098670320809571e-01, /* 0x3fdd45aec9ec862b */ + 4.60517728767271039558e-01, /* 0x3fdd791f5a1226f4 */ + 4.63647609000806093515e-01, /* 0x3fddac670561bb4f */ + 4.66767723680866497560e-01, /* 0x3fdddf85bb026974 */ + 4.69878057975686880265e-01, /* 0x3fde127b6b0744af */ + 4.72978597903265574054e-01, /* 0x3fde4548066cf51a */ + 4.76069330322761219421e-01, /* 0x3fde77eb7f175a34 */ + 4.79150242925822533735e-01, /* 0x3fdeaa65c7cf28c4 */ + 4.82221324227853687105e-01, /* 0x3fdedcb6d43f8434 */ + 4.85282563559221225002e-01, /* 0x3fdf0ede98f393cf */ + 4.88333951056405479729e-01, /* 0x3fdf40dd0b541417 */ + 4.91375477653101910835e-01, /* 0x3fdf72b221a4e495 */ + 4.94407135071275316562e-01, /* 0x3fdfa45dd3029258 */ + 4.97428915812172245392e-01, /* 0x3fdfd5e0175fdf83 */ + 5.00440813147294050189e-01, /* 0x3fe0039c73c1a40b */ + 5.03442821109336358099e-01, /* 0x3fe01c341e82422d */ + 5.06434934483096732549e-01, /* 0x3fe034b709250488 */ + 5.09417148796356245022e-01, /* 0x3fe04d25314342e5 */ + 5.12389460310737621107e-01, /* 0x3fe0657e94db30cf */ + 5.15351866012543347040e-01, /* 0x3fe07dc3324e9b38 */ + 5.18304363603577900044e-01, /* 0x3fe095f30861a58f */ + 5.21246951491958210312e-01, /* 0x3fe0ae0e1639866c */ + 5.24179628782913242802e-01, /* 0x3fe0c6145b5b43da */ + 5.27102395269579471204e-01, /* 0x3fe0de05d7aa6f7c */ + 5.30015251423793132268e-01, /* 0x3fe0f5e28b67e295 */ + 5.32918198386882147055e-01, /* 0x3fe10daa77307a0d */ + 5.35811237960463593311e-01, /* 0x3fe1255d9bfbd2a8 */ + 5.38694372597246617929e-01, /* 0x3fe13cfbfb1b056e */ + 5.41567605391844897333e-01, /* 0x3fe1548596376469 */ + 5.44430940071603086672e-01, /* 0x3fe16bfa6f5137e1 */ + 5.47284380987436924748e-01, /* 0x3fe1835a88be7c13 */ + 5.50127933104692989907e-01, /* 0x3fe19aa5e5299f99 */ + 5.52961601994028217888e-01, /* 0x3fe1b1dc87904284 */ + 5.55785393822313511514e-01, /* 0x3fe1c8fe7341f64f */ + 5.58599315343562330405e-01, /* 0x3fe1e00babdefeb3 */ + 5.61403373889889367732e-01, /* 0x3fe1f7043557138a */ + 5.64197577362497537656e-01, /* 0x3fe20de813e823b1 */ + 5.66981934222700489912e-01, /* 0x3fe224b74c1d192a */ + 5.69756453482978431069e-01, /* 0x3fe23b71e2cc9e6a */ + 5.72521144698072359525e-01, /* 0x3fe25217dd17e501 */ + 5.75276017956117824426e-01, /* 0x3fe268a940696da6 */ + 5.78021083869819540801e-01, /* 0x3fe27f261273d1b3 */ + 5.80756353567670302596e-01, /* 0x3fe2958e59308e30 */ + 5.83481838685214859730e-01, /* 0x3fe2abe21aded073 */ + 5.86197551356360535557e-01, /* 0x3fe2c2215e024465 */ + 5.88903504204738026395e-01, /* 0x3fe2d84c2961e48b */ + 5.91599710335111383941e-01, /* 0x3fe2ee628406cbca */ + 5.94286183324841177367e-01, /* 0x3fe30464753b090a */ + 5.96962937215401501234e-01, /* 0x3fe31a52048874be */ + 5.99629986503951384336e-01, /* 0x3fe3302b39b78856 */ + 6.02287346134964152178e-01, /* 0x3fe345f01cce37bb */ + 6.04935031491913965951e-01, /* 0x3fe35ba0b60eccce */ + 6.07573058389022313541e-01, /* 0x3fe3713d0df6c503 */ + 6.10201443063065118722e-01, /* 0x3fe386c52d3db11e */ + 6.12820202165241245673e-01, /* 0x3fe39c391cd41719 */ + 6.15429352753104952356e-01, /* 0x3fe3b198e5e2564a */ + 6.18028912282561737612e-01, /* 0x3fe3c6e491c78dc4 */ + 6.20618898599929469384e-01, /* 0x3fe3dc1c2a188504 */ + 6.23199329934065904268e-01, /* 0x3fe3f13fb89e96f4 */ + 6.25770224888563042498e-01, /* 0x3fe4064f47569f48 */ + 6.28331602434009650615e-01, /* 0x3fe41b4ae06fea41 */ + 6.30883481900321840818e-01, /* 0x3fe430328e4b26d5 */ + 6.33425882969144482537e-01, /* 0x3fe445065b795b55 */ + 6.35958825666321447834e-01, /* 0x3fe459c652badc7f */ + 6.38482330354437466191e-01, /* 0x3fe46e727efe4715 */ + 6.40996417725432032775e-01, /* 0x3fe4830aeb5f7bfd */ + 6.43501108793284370968e-01, /* 0x3fe4978fa3269ee1 */ + 6.45996424886771558604e-01, /* 0x3fe4ac00b1c71762 */ + 6.48482387642300484032e-01, /* 0x3fe4c05e22de94e4 */ + 6.50959018996812410762e-01, /* 0x3fe4d4a8023414e8 */ + 6.53426341180761927063e-01, /* 0x3fe4e8de5bb6ec04 */ + 6.55884376711170835605e-01, /* 0x3fe4fd013b7dd17e */ + 6.58333148384755983962e-01, /* 0x3fe51110adc5ed81 */ + 6.60772679271132590273e-01, /* 0x3fe5250cbef1e9fa */ + 6.63202992706093175102e-01, /* 0x3fe538f57b89061e */ + 6.65624112284960989250e-01, /* 0x3fe54ccaf0362c8f */ + 6.68036061856020157990e-01, /* 0x3fe5608d29c70c34 */ + 6.70438865514021320458e-01, /* 0x3fe5743c352b33b9 */ + 6.72832547593763097282e-01, /* 0x3fe587d81f732fba */ + 6.75217132663749830535e-01, /* 0x3fe59b60f5cfab9d */ + 6.77592645519925151909e-01, /* 0x3fe5aed6c5909517 */ + 6.79959111179481823228e-01, /* 0x3fe5c2399c244260 */ + 6.82316554874748071313e-01, /* 0x3fe5d58987169b18 */ + 6.84665002047148862907e-01, /* 0x3fe5e8c6941043cf */ + 6.87004478341244895212e-01, /* 0x3fe5fbf0d0d5cc49 */ + 6.89335009598845749323e-01, /* 0x3fe60f084b46e05e */ + 6.91656621853199760075e-01, /* 0x3fe6220d115d7b8d */ + 6.93969341323259825138e-01, /* 0x3fe634ff312d1f3b */ + 6.96273194408023488045e-01, /* 0x3fe647deb8e20b8f */ + 6.98568207680949848637e-01, /* 0x3fe65aabb6c07b02 */ + 7.00854407884450081312e-01, /* 0x3fe66d663923e086 */ + 7.03131821924453670469e-01, /* 0x3fe6800e4e7e2857 */ + 7.05400476865049030906e-01, /* 0x3fe692a40556fb6a */ + 7.07660399923197958039e-01, /* 0x3fe6a5276c4b0575 */ + 7.09911618463524796141e-01, /* 0x3fe6b798920b3d98 */ + 7.12154159993178659249e-01, /* 0x3fe6c9f7855c3198 */ + 7.14388052156768926793e-01, /* 0x3fe6dc44551553ae */ + 7.16613322731374569052e-01, /* 0x3fe6ee7f10204aef */ + 7.18829999621624415873e-01, /* 0x3fe700a7c5784633 */ + 7.21038110854851588272e-01, /* 0x3fe712be84295198 */ + 7.23237684576317874097e-01, /* 0x3fe724c35b4fae7b */ + 7.25428749044510712274e-01, /* 0x3fe736b65a172dff */ + 7.27611332626510676214e-01, /* 0x3fe748978fba8e0f */ + 7.29785463793429123314e-01, /* 0x3fe75a670b82d8d8 */ + 7.31951171115916565668e-01, /* 0x3fe76c24dcc6c6c0 */ + 7.34108483259739652560e-01, /* 0x3fe77dd112ea22c7 */ + 7.36257428981428097003e-01, /* 0x3fe78f6bbd5d315e */ + 7.38398037123989547936e-01, /* 0x3fe7a0f4eb9c19a2 */ + 7.40530336612692630105e-01, /* 0x3fe7b26cad2e50fd */ + 7.42654356450917929600e-01, /* 0x3fe7c3d311a6092b */ + 7.44770125716075148681e-01, /* 0x3fe7d528289fa093 */ + 7.46877673555587429099e-01, /* 0x3fe7e66c01c114fd */ + 7.48977029182941400620e-01, /* 0x3fe7f79eacb97898 */ + 7.51068221873802288613e-01, /* 0x3fe808c03940694a */ + 7.53151280962194302759e-01, /* 0x3fe819d0b7158a4c */ + 7.55226235836744863583e-01, /* 0x3fe82ad036000005 */ + 7.57293115936992444759e-01, /* 0x3fe83bbec5cdee22 */ + 7.59351950749757920178e-01, /* 0x3fe84c9c7653f7ea */ + 7.61402769805578416573e-01, /* 0x3fe85d69576cc2c5 */ + 7.63445602675201784315e-01, /* 0x3fe86e2578f87ae5 */ + 7.65480478966144461950e-01, /* 0x3fe87ed0eadc5a2a */ + 7.67507428319308182552e-01, /* 0x3fe88f6bbd023118 */ + 7.69526480405658186434e-01, /* 0x3fe89ff5ff57f1f7 */ + 7.71537664922959498526e-01, /* 0x3fe8b06fc1cf3dfe */ + 7.73541011592573490852e-01, /* 0x3fe8c0d9145cf49d */ + 7.75536550156311621507e-01, /* 0x3fe8d13206f8c4ca */ + 7.77524310373347682379e-01, /* 0x3fe8e17aa99cc05d */ + 7.79504322017186335181e-01, /* 0x3fe8f1b30c44f167 */ + 7.81476614872688268854e-01, /* 0x3fe901db3eeef187 */ + 7.83441218733151756304e-01, /* 0x3fe911f35199833b */ + 7.85398163397448278999e-01 }; /* 0x3fe921fb54442d18 */ + + /* Some constants. */ + + static double pi = 3.1415926535897932e+00, /* 0x400921fb54442d18 */ + piby2 = 1.5707963267948966e+00, /* 0x3ff921fb54442d18 */ + piby4 = 7.8539816339744831e-01, /* 0x3fe921fb54442d18 */ + three_piby4 = 2.3561944901923449e+00; /* 0x4002d97c7f3321d2 */ + + double u, v, vbyu, q, s, uu, r; + unsigned int swap_vu, index, xzero, yzero, xnan, ynan, xinf, yinf; + int xexp, yexp, diffexp; + unsigned long long uy; + + double x; + double y; + unsigned int ufx, aufx, xneg; + unsigned int ufy, aufy, yneg; + + GET_BITS_SP32(fy, ufy); + GET_BITS_SP32(fx, ufx); + + xneg = ufx & SIGNBIT_SP32; + yneg = ufy & SIGNBIT_SP32; + aufx = ufx & ~SIGNBIT_SP32; + aufy = ufy & ~SIGNBIT_SP32; + + xzero = (aufx == 0); + yzero = (aufy == 0); + xnan = (aufx > PINFBITPATT_SP32); + ynan = (aufy > PINFBITPATT_SP32); + xinf = (aufx == PINFBITPATT_SP32); + yinf = (aufy == PINFBITPATT_SP32); + + xexp = (int)((ufx & EXPBITS_SP32) >> EXPSHIFTBITS_SP32); + yexp = (int)((ufy & EXPBITS_SP32) >> EXPSHIFTBITS_SP32); + + + diffexp = yexp - xexp; + + + /* Special cases */ + + if (xnan) +#ifdef WINDOWS + { + + return __amd_handle_errorf("atan2f", __amd_atan2, ufx | 0x00400000, _DOMAIN, 0, EDOM, fx, fy, 2); + } +#else + return fx + fx; /* Raise invalid if it's a signalling NaN */ +#endif + else if (ynan) +#ifdef WINDOWS + { + + return __amd_handle_errorf("atan2f", __amd_atan2, ufy | 0x00400000, _DOMAIN, 0, EDOM, fx, fy, 2); + } +#else + return (fy + fy); /* Raise invalid if it's a signalling NaN */ +#endif + else if (yzero) + { /* Zero y gives +-0 for positive x + and +-pi for negative x */ + if (xneg) + { + if (yneg) return (float)-pi; // return valf_with_flags((float)-pi, AMD_F_INEXACT); + else return (float)pi; // return valf_with_flags((float)pi, AMD_F_INEXACT); + } + else return fy; + } + else if (xzero) + { /* Zero x gives +- pi/2 + depending on sign of y */ + if (yneg) return (float)-piby2; //return valf_with_flags((float)-piby2, AMD_F_INEXACT); + else return (float)piby2; //valf_with_flags((float)piby2, AMD_F_INEXACT); + } + + + x = fx; + y = fy; + + /* Find properties of arguments x and y. */ + + + + + + + if (diffexp > 26) + { /* abs(y)/abs(x) > 2^26 => arctan(x/y) + is insignificant compared to piby2 */ + if (yneg) return (float)-piby2; //return valf_with_flags((float)-piby2, AMD_F_INEXACT); + else return (float)piby2; //return valf_with_flags((float)piby2, AMD_F_INEXACT); + } + else if (diffexp < -13 && (!xneg)) + { /* x positive and dominant over y by a factor of 2^13. + In this case atan(y/x) is y/x to machine accuracy. */ + + if (diffexp < -150) /* Result underflows */ + { + if (yneg) +#ifdef WINDOWS + return -0.0F; //return valf_with_flags(-0.0F, AMD_F_INEXACT | AMD_F_UNDERFLOW); + else + return 0.0F; //return valf_with_flags(0.0F, AMD_F_INEXACT | AMD_F_UNDERFLOW); +#else + return __amd_handle_errorf("atan2f", __amd_atan2, 0x80000000, _UNDERFLOW, AMD_F_INEXACT | AMD_F_UNDERFLOW, ERANGE, fx, fy, 2); + else + return __amd_handle_errorf("atan2f", __amd_atan2, 0x00000000, _UNDERFLOW, AMD_F_INEXACT | AMD_F_UNDERFLOW, ERANGE, fx, fy, 2); + +#endif + } + else + { + if (diffexp < -126) + { + /* Result will likely be denormalized */ + y = scaleDouble_1(y, 100); + y /= x; + /* Now y is 2^100 times the true result. Scale it back down. */ + GET_BITS_DP64(y, uy); + scaleDownDouble(uy, 100, &uy); + PUT_BITS_DP64(uy, y); + if ((uy & EXPBITS_DP64) == 0) + return (float)y; //return valf_with_flags((float)y, AMD_F_INEXACT | AMD_F_UNDERFLOW); + else + return (float)y; + } + else + return (float)(y / x); + } + } + else if (diffexp < -26 && xneg) + { /* abs(x)/abs(y) > 2^56 and x < 0 => arctan(y/x) + is insignificant compared to pi */ + if (yneg) return (float)-pi; // return valf_with_flags((float)-pi, AMD_F_INEXACT); + else return (float)pi;// return valf_with_flags((float)pi, AMD_F_INEXACT); + } + else if (yinf && xinf) + { /* If abs(x) and abs(y) are both infinity + return +-pi/4 or +- 3pi/4 according to + signs. */ + if (xneg) + { + if (yneg) return (float)-three_piby4; // return valf_with_flags((float)-three_piby4, AMD_F_INEXACT); + else return (float)three_piby4; //return valf_with_flags((float)three_piby4, AMD_F_INEXACT); + } + else + { + if (yneg) return (float)-piby4; //return valf_with_flags((float)-piby4, AMD_F_INEXACT); + else return (float)piby4; //return valf_with_flags((float)piby4, AMD_F_INEXACT); + } + } + + /* General case: take absolute values of arguments */ + + u = x; v = y; + if (xneg) u = -x; + if (yneg) v = -y; + + /* Swap u and v if necessary to obtain 0 < v < u. Compute v/u. */ + + swap_vu = (u < v); + if (swap_vu) { uu = u; u = v; v = uu; } + vbyu = v / u; + + if (vbyu > 0.0625) + { /* General values of v/u. Use a look-up + table and series expansion. */ + + index = (int)(256 * vbyu + 0.5); + r = (256 * v - index * u) / (256 * u + index * v); + + /* Polynomial approximation to atan(vbyu) */ + + s = r * r; + q = atan_jby256[index - 16] + r - r * s * 0.33333333333224095522; + } + else if (vbyu < 1.e-4) + { /* v/u is small enough that atan(v/u) = v/u */ + q = vbyu; + } + else /* vbyu <= 0.0625 */ + { + /* Small values of v/u. Use a series expansion */ + + s = vbyu * vbyu; + q = vbyu - + vbyu * s * (0.33333333333333170500 - + s * (0.19999999999393223405 - + s * 0.14285713561807169030)); + } + + /* Tidy-up according to which quadrant the arguments lie in */ + + if (swap_vu) { q = piby2 - q; } + if (xneg) { q = pi - q; } + if (yneg) q = -q; + return (float)q; +} diff --git a/src/native/clrmath/src/ref/atanf.cpp b/src/native/clrmath/src/ref/atanf.cpp new file mode 100644 index 00000000000000..2c4d788593446b --- /dev/null +++ b/src/native/clrmath/src/ref/atanf.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +float FN_PROTOTYPE_REF(atanf)(float fx) +{ + + /* Some constants and split constants. */ + + static double piby2 = 1.5707963267948966e+00; /* 0x3ff921fb54442d18 */ + + double c, v, s, q, z; + unsigned int xnan, fux, faux; + unsigned long long ux, aux, xneg; + double x; + GET_BITS_SP32(fx, fux); + faux = fux & ~SIGNBIT_SP32; + + xnan = (faux > PINFBITPATT_SP32); + + if (xnan) + { + /* x is NaN */ +#ifdef WINDOWS + return __amd_handle_errorf("atanf", __amd_atan, fux | 0x00400000, _DOMAIN, 0, EDOM, fx, 0.0, 1); +#else + return fx + fx; /* Raise invalid if it's a signalling NaN */ +#endif + } + + + + x = fx; + GET_BITS_DP64(x, ux); + /* Find properties of argument fx. */ + + + aux = ux & ~SIGNBIT_DP64; + xneg = ux & SIGNBIT_DP64; + + v = x; + if (xneg) v = -x; + + /* Argument reduction to range [-7/16,7/16] */ + + if (aux < 0x3ec0000000000000) /* v < 2.0^(-19) */ + { + /* x is a good approximation to atan(x) */ + if (aux == 0x0000000000000000) + return fx; + else +#ifdef WINDOWS + return fx; //valf_with_flags(fx, AMD_F_INEXACT); +#else + return __amd_handle_errorf("atanf", __amd_atan, fux, _UNDERFLOW, AMD_F_UNDERFLOW | AMD_F_INEXACT, ERANGE, fx, 0.0, 1); + +#endif + } + else if (aux < 0x3fdc000000000000) /* v < 7./16. */ + { + x = v; + c = 0.0; + } + else if (aux < 0x3fe6000000000000) /* v < 11./16. */ + { + x = (2.0 * v - 1.0) / (2.0 + v); + /* c = arctan(0.5) */ + c = 4.63647609000806093515e-01; /* 0x3fddac670561bb4f */ + } + else if (aux < 0x3ff3000000000000) /* v < 19./16. */ + { + x = (v - 1.0) / (1.0 + v); + /* c = arctan(1.) */ + c = 7.85398163397448278999e-01; /* 0x3fe921fb54442d18 */ + } + else if (aux < 0x4003800000000000) /* v < 39./16. */ + { + x = (v - 1.5) / (1.0 + 1.5 * v); + /* c = arctan(1.5) */ + c = 9.82793723247329054082e-01; /* 0x3fef730bd281f69b */ + } + else + { + if (aux > 0x4190000000000000) + { /* abs(x) > 2^26 => arctan(1/x) is + insignificant compared to piby2 */ + if (xneg) + return (float)-piby2; //valf_with_flags((float)-piby2, AMD_F_INEXACT); + else + return (float)piby2;//valf_with_flags((float)piby2, AMD_F_INEXACT); + } + + x = -1.0 / v; + /* c = arctan(infinity) */ + c = 1.57079632679489655800e+00; /* 0x3ff921fb54442d18 */ + } + + /* Core approximation: Remez(2,2) on [-7/16,7/16] */ + + s = x * x; + q = x * s * + (0.296528598819239217902158651186e0 + + (0.192324546402108583211697690500e0 + + 0.470677934286149214138357545549e-2 * s) * s) / + (0.889585796862432286486651434570e0 + + (0.111072499995399550138837673349e1 + + 0.299309699959659728404442796915e0 * s) * s); + + z = c - (q - x); + + if (xneg) z = -z; + return (float)z; +} diff --git a/src/native/clrmath/src/ref/atanh.cpp b/src/native/clrmath/src/ref/atanh.cpp new file mode 100644 index 00000000000000..43d3d49ec067a0 --- /dev/null +++ b/src/native/clrmath/src/ref/atanh.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +#undef _FUNCNAME +#define _FUNCNAME "atanh" +double FN_PROTOTYPE_REF(atanh)(double x) +{ + + unsigned long long ux, ax; + double r, absx, t, poly; + + + GET_BITS_DP64(x, ux); + ax = ux & ~SIGNBIT_DP64; + PUT_BITS_DP64(ax, absx); + + if ((ux & EXPBITS_DP64) == EXPBITS_DP64) + { + /* x is either NaN or infinity */ + if (ux & MANTBITS_DP64) + { + /* x is NaN */ +#ifdef WINDOWS + return __amd_handle_error(_FUNCNAME, __amd_atanh, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); +#else + if (ux & QNAN_MASK_64) + return __amd_handle_error(_FUNCNAME, __amd_atanh, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); + else + return __amd_handle_error(_FUNCNAME, __amd_atanh, ux | 0x0008000000000000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); +#endif + } + else + { + /* x is infinity; return a NaN */ + + return __amd_handle_error(_FUNCNAME, __amd_atanh, INDEFBITPATT_DP64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + } + else if (ax >= 0x3ff0000000000000) + { + if (ax > 0x3ff0000000000000) + { + /* abs(x) > 1.0; return NaN */ + return __amd_handle_error(_FUNCNAME, __amd_atanh, INDEFBITPATT_DP64, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0, 1); + } + else if (ux == 0x3ff0000000000000) + { + /* x = +1.0; return infinity with the same sign as x + and set the divbyzero status flag */ + return __amd_handle_error(_FUNCNAME, __amd_atanh, PINFBITPATT_DP64, _DOMAIN, + AMD_F_DIVBYZERO, EDOM, x, 0.0, 1); + } + else + { + /* x = -1.0; return infinity with the same sign as x */ + return __amd_handle_error(_FUNCNAME, __amd_atanh, NINFBITPATT_DP64, _DOMAIN, + AMD_F_DIVBYZERO, EDOM, x, 0.0, 1); + } + } + + + if (ax < 0x3e30000000000000) + { + if (ax == 0x0000000000000000) + { + /* x is +/-zero. Return the same zero. */ + return x; + } + else + { + /* Arguments smaller than 2^(-28) in magnitude are + approximated by atanh(x) = x, raising inexact flag. */ +#ifdef WINDOWS + return x;//return val_with_flags(x, AMD_F_INEXACT); +#else + return __amd_handle_error(_FUNCNAME, __amd_atanh, ux, _UNDERFLOW, AMD_F_UNDERFLOW | AMD_F_INEXACT, ERANGE, x, 0.0, 1); +#endif + } + } + else + { + if (ax < 0x3fe0000000000000) + { + /* Arguments up to 0.5 in magnitude are + approximated by a [5,5] minimax polynomial */ + t = x * x; + poly = + (0.47482573589747356373e0 + + (-0.11028356797846341457e1 + + (0.88468142536501647470e0 + + (-0.28180210961780814148e0 + + (0.28728638600548514553e-1 - + 0.10468158892753136958e-3 * t) * t) * t) * t) * t) / + (0.14244772076924206909e1 + + (-0.41631933639693546274e1 + + (0.45414700626084508355e1 + + (-0.22608883748988489342e1 + + (0.49561196555503101989e0 - + 0.35861554370169537512e-1 * t) * t) * t) * t) * t); + return x + x * t * poly; + } + else + { + /* abs(x) >= 0.5 */ + /* Note that + atanh(x) = 0.5 * ln((1+x)/(1-x)) + (see Abramowitz and Stegun 4.6.22). + For greater accuracy we use the variant formula + atanh(x) = log(1 + 2x/(1-x)) = log1p(2x/(1-x)). + */ + r = (2.0 * absx) / (1.0 - absx); + r = 0.5 * FN_PROTOTYPE(log1p)(r); + if (ux & SIGNBIT_DP64) + /* Argument x is negative */ + return -r; + else + return r; + } + } +} diff --git a/src/native/clrmath/src/ref/atanhf.cpp b/src/native/clrmath/src/ref/atanhf.cpp new file mode 100644 index 00000000000000..10bcdd73738652 --- /dev/null +++ b/src/native/clrmath/src/ref/atanhf.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +#undef _FUNCNAME +#define _FUNCNAME "atanhf" +float FN_PROTOTYPE_REF(atanhf)(float x) +{ + + double dx; + unsigned int ux, ax; + double r, t, poly; + + GET_BITS_SP32(x, ux); + ax = ux & ~SIGNBIT_SP32; + + if ((ux & EXPBITS_SP32) == EXPBITS_SP32) + { + /* x is either NaN or infinity */ + if (ux & MANTBITS_SP32) + { + /* x is NaN */ +#ifdef WINDOWS + return __amd_handle_errorf(_FUNCNAME, __amd_tanh, ux | 0x00400000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0F, 1); +#else + if (ux & QNAN_MASK_32) + return __amd_handle_errorf(_FUNCNAME, __amd_tanh, ux | 0x00400000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0F, 1); + else + return __amd_handle_errorf(_FUNCNAME, __amd_tanh, ux | 0x00400000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0F, 1); +#endif + } + else + { + /* x is infinity; return a NaN */ + return __amd_handle_errorf(_FUNCNAME, __amd_tanh, INDEFBITPATT_SP32, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0F, 1); + + } + } + else if (ax >= 0x3f800000) + { + if (ax > 0x3f800000) + { + /* abs(x) > 1.0; return NaN */ + return __amd_handle_errorf(_FUNCNAME, __amd_tanh, INDEFBITPATT_SP32, _DOMAIN, + AMD_F_INVALID, EDOM, x, 0.0F, 1); + } + else if (ux == 0x3f800000) + { + /* x = +1.0; return infinity with the same sign as x + and set the divbyzero status flag */ + return __amd_handle_errorf(_FUNCNAME, __amd_tanh, PINFBITPATT_SP32, _DOMAIN, + AMD_F_DIVBYZERO, EDOM, x, 0.0F, 1); + } + else + { + /* x = -1.0; return infinity with the same sign as x */ + return __amd_handle_errorf(_FUNCNAME, __amd_tanh, NINFBITPATT_SP32, _DOMAIN, + AMD_F_DIVBYZERO, EDOM, x, 0.0F, 1); + } + } + + if (ax < 0x39000000) + { + if (ax == 0x00000000) + { + /* x is +/-zero. Return the same zero. */ + return x; + } + else + { + /* Arguments smaller than 2^(-13) in magnitude are + approximated by atanhf(x) = x, raising inexact flag. */ +#ifdef WINDOWS + return x; // return valf_with_flags(x, AMD_F_INEXACT); +#else + return __amd_handle_errorf(_FUNCNAME, __amd_tanh, ux, _UNDERFLOW, AMD_F_UNDERFLOW | AMD_F_INEXACT, ERANGE, x, 0.0F, 1); +#endif + } + } + else + { + dx = x; + if (ax < 0x3f000000) + { + /* Arguments up to 0.5 in magnitude are + approximated by a [2,2] minimax polynomial */ + t = dx * dx; + poly = + (0.39453629046e0 + + (-0.28120347286e0 + + 0.92834212715e-2 * t) * t) / + (0.11836088638e1 + + (-0.15537744551e1 + + 0.45281890445e0 * t) * t); + return (float)(dx + dx * t * poly); + } + else + { + /* abs(x) >= 0.5 */ + /* Note that + atanhf(x) = 0.5 * ln((1+x)/(1-x)) + (see Abramowitz and Stegun 4.6.22). + For greater accuracy we use the variant formula + atanhf(x) = log(1 + 2x/(1-x)) = log1p(2x/(1-x)). + */ + if (ux & SIGNBIT_SP32) + { + /* Argument x is negative */ + r = (-2.0 * dx) / (1.0 + dx); + r = 0.5 * FN_PROTOTYPE(log1p)(r); + return (float)-r; + } + else + { + r = (2.0 * dx) / (1.0 - dx); + r = 0.5 * FN_PROTOTYPE(log1p)(r); + return (float)r; + } + } + } +} diff --git a/src/native/clrmath/src/ref/ceil.cpp b/src/native/clrmath/src/ref/ceil.cpp new file mode 100644 index 00000000000000..66d0d0291e45da --- /dev/null +++ b/src/native/clrmath/src/ref/ceil.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +double FN_PROTOTYPE_REF(ceil)(double x) +{ + double r; + long long rexp, xneg; + unsigned long long ux, ax, ur, mask; + + GET_BITS_DP64(x, ux); + /*ax is |x|*/ + ax = ux & (~SIGNBIT_DP64); + /*xneg stores the sign of the input x*/ + xneg = (ux != ax); + /*The range is divided into + > 2^53. ceil will either the number itself or Nan + always returns a QNan. Raises exception if input is a SNan + < 1.0 If 0.0 then return with the appropriate sign + If input is less than -0.0 and greater than -1.0 then return -0.0 + If input is greater than 0.0 and less than 1.0 then return 1.0 + 1.0 < |x| < 2^53 + appropriately check the exponent and set the return Value by shifting + */ + if (ax >= 0x4340000000000000) /* abs(x) > 2^53*/ + { + /* abs(x) is either NaN, infinity, or >= 2^53 */ + if (ax > 0x7ff0000000000000) + /* x is NaN */ +#ifdef WINDOWS + return __amd_handle_error("ceil", __amd_ceil, ux | 0x0008000000000000, _DOMAIN, 0, EDOM, x, 0.0, 1); +#else + { + if (!(ax & 0x0008000000000000))// x is snan + return __amd_handle_error("ceil", __amd_ceil, ux | 0x0008000000000000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); + else + return x; + } +#endif + + else + return x; + } + else if (ax < 0x3ff0000000000000) /* abs(x) < 1.0 */ + { + if (ax == 0x0000000000000000) + /* x is +zero or -zero; return the same zero */ + return x; + else if (xneg) /* x < 0.0; return -0.0 */ + { + PUT_BITS_DP64(0x8000000000000000, r); + return r; + } + else + return 1.0; + } + else + { + /*Get the exponent for the floating point number. Should be between 0 and 53*/ + rexp = ((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; + /* Mask out the bits of r that we don't want */ + mask = 1; + mask = (mask << (EXPSHIFTBITS_DP64 - rexp)) - 1; + /*Keeps the exponent part and the required mantissa.*/ + ur = (ux & ~mask); + PUT_BITS_DP64(ur, r); + if (xneg || (ur == ux)) + return r; + else + /* We threw some bits away and x was positive */ + return r + 1.0; + } + +} diff --git a/src/native/clrmath/src/ref/ceilf.cpp b/src/native/clrmath/src/ref/ceilf.cpp new file mode 100644 index 00000000000000..384b072049d34a --- /dev/null +++ b/src/native/clrmath/src/ref/ceilf.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +float FN_PROTOTYPE_REF(ceilf)(float x) +{ + float r; + int rexp, xneg; + unsigned int ux, ax, ur, mask; + + GET_BITS_SP32(x, ux); + /*ax is |x|*/ + ax = ux & (~SIGNBIT_SP32); + /*xneg stores the sign of the input x*/ + xneg = (ux != ax); + /*The range is divided into + > 2^24. ceil will either the number itself or Nan + always returns a QNan. Raises exception if input is a SNan + < 1.0 If 0.0 then return with the appropriate sign + If input is less than -0.0 and greater than -1.0 then return -0.0 + If input is greater than 0.0 and less than 1.0 then return 1.0 + 1.0 < |x| < 2^24 + appropriately check the exponent and set the return Value by shifting + */ + if (ax >= 0x4b800000) /* abs(x) > 2^24*/ + { + /* abs(x) is either NaN, infinity, or >= 2^24 */ + if (ax > 0x7f800000) + /* x is NaN */ +#ifdef WINDOWS + return __amd_handle_errorf("ceilf", __amd_ceil, ux | 0x00400000, _DOMAIN, 0, EDOM, x, 0.0, 1); +#else + if (!(ax & 0x00400000)) //x is snan + return __amd_handle_errorf("ceilf", __amd_ceil, ux | 0x00400000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); + else + return x; +#endif + + else + return x; + } + else if (ax < 0x3f800000) /* abs(x) < 1.0 */ + { + if (ax == 0x00000000) + /* x is +zero or -zero; return the same zero */ + return x; + else if (xneg) /* x < 0.0 */ + return -0.0F; + else + return 1.0F; + } + else + { + rexp = ((ux & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; + /* Mask out the bits of r that we don't want */ + mask = (1 << (EXPSHIFTBITS_SP32 - rexp)) - 1; + /*Keeps the exponent part and the required mantissa.*/ + ur = (ux & ~mask); + PUT_BITS_SP32(ur, r); + + if (xneg || (ux == ur)) return r; + else + /* We threw some bits away and x was positive */ + return r + 1.0F; + } +} diff --git a/src/native/clrmath/src/ref/cosh.cpp b/src/native/clrmath/src/ref/cosh.cpp new file mode 100644 index 00000000000000..91eec1ae438642 --- /dev/null +++ b/src/native/clrmath/src/ref/cosh.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_inlines.h" +#include "libm/libm_special.h" + +double FN_PROTOTYPE_REF(cosh)(double x) +{ + /* + Derived from sinh subroutine + + After dealing with special cases the computation is split into + regions as follows: + + abs(x) >= max_cosh_arg: + cosh(x) = sign(x)*Inf + + abs(x) >= small_threshold: + cosh(x) = sign(x)*exp(abs(x))/2 computed using the + splitexp and scaleDouble functions as for exp_amd(). + + abs(x) < small_threshold: + compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0))) + cosh(x) is then sign(x)*z. */ + + static const double + max_cosh_arg = 7.10475860073943977113e+02, /* 0x408633ce8fb9f87e */ + thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */ + log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */ + log2_by_32_tail = 5.68948749532545630390e-11, /* 0x3dcf473de6af278e */ + // small_threshold = 8*BASEDIGITS_DP64*0.30102999566398119521373889; + small_threshold = 20.0; + /* (8*BASEDIGITS_DP64*log10of2) ' exp(-x) insignificant c.f. exp(x) */ + + /* Lead and tail tabulated values of sinh(i) and cosh(i) + for i = 0,...,36. The lead part has 26 leading bits. */ + + static const double sinh_lead[37] = { + 0.00000000000000000000e+00, /* 0x0000000000000000 */ + 1.17520117759704589844e+00, /* 0x3ff2cd9fc0000000 */ + 3.62686038017272949219e+00, /* 0x400d03cf60000000 */ + 1.00178747177124023438e+01, /* 0x40240926e0000000 */ + 2.72899169921875000000e+01, /* 0x403b4a3800000000 */ + 7.42032089233398437500e+01, /* 0x40528d0160000000 */ + 2.01713153839111328125e+02, /* 0x406936d228000000 */ + 5.48316116333007812500e+02, /* 0x4081228768000000 */ + 1.49047882080078125000e+03, /* 0x409749ea50000000 */ + 4.05154187011718750000e+03, /* 0x40afa71570000000 */ + 1.10132326660156250000e+04, /* 0x40c5829dc8000000 */ + 2.99370708007812500000e+04, /* 0x40dd3c4488000000 */ + 8.13773945312500000000e+04, /* 0x40f3de1650000000 */ + 2.21206695312500000000e+05, /* 0x410b00b590000000 */ + 6.01302140625000000000e+05, /* 0x412259ac48000000 */ + 1.63450865625000000000e+06, /* 0x4138f0cca8000000 */ + 4.44305525000000000000e+06, /* 0x4150f2ebd0000000 */ + 1.20774762500000000000e+07, /* 0x4167093488000000 */ + 3.28299845000000000000e+07, /* 0x417f4f2208000000 */ + 8.92411500000000000000e+07, /* 0x419546d8f8000000 */ + 2.42582596000000000000e+08, /* 0x41aceb0888000000 */ + 6.59407856000000000000e+08, /* 0x41c3a6e1f8000000 */ + 1.79245641600000000000e+09, /* 0x41dab5adb8000000 */ + 4.87240166400000000000e+09, /* 0x41f226af30000000 */ + 1.32445608960000000000e+10, /* 0x4208ab7fb0000000 */ + 3.60024494080000000000e+10, /* 0x4220c3d390000000 */ + 9.78648043520000000000e+10, /* 0x4236c93268000000 */ + 2.66024116224000000000e+11, /* 0x424ef822f0000000 */ + 7.23128516608000000000e+11, /* 0x42650bba30000000 */ + 1.96566712320000000000e+12, /* 0x427c9aae40000000 */ + 5.34323724288000000000e+12, /* 0x4293704708000000 */ + 1.45244246507520000000e+13, /* 0x42aa6b7658000000 */ + 3.94814795284480000000e+13, /* 0x42c1f43fc8000000 */ + 1.07321789251584000000e+14, /* 0x42d866f348000000 */ + 2.91730863685632000000e+14, /* 0x42f0953e28000000 */ + 7.93006722514944000000e+14, /* 0x430689e220000000 */ + 2.15561576592179200000e+15 }; /* 0x431ea215a0000000 */ + + static const double sinh_tail[37] = { + 0.00000000000000000000e+00, /* 0x0000000000000000 */ + 1.60467555584448807892e-08, /* 0x3e513ae6096a0092 */ + 2.76742892754807136947e-08, /* 0x3e5db70cfb79a640 */ + 2.09697499555224576530e-07, /* 0x3e8c2526b66dc067 */ + 2.04940252448908240062e-07, /* 0x3e8b81b18647f380 */ + 1.65444891522700935932e-06, /* 0x3ebbc1cdd1e1eb08 */ + 3.53116789999998198721e-06, /* 0x3ecd9f201534fb09 */ + 6.94023870987375490695e-06, /* 0x3edd1c064a4e9954 */ + 4.98876893611587449271e-06, /* 0x3ed4eca65d06ea74 */ + 3.19656024605152215752e-05, /* 0x3f00c259bcc0ecc5 */ + 2.08687768377236501204e-04, /* 0x3f2b5a6647cf9016 */ + 4.84668088325403796299e-05, /* 0x3f09691adefb0870 */ + 1.17517985422733832468e-03, /* 0x3f53410fc29cde38 */ + 6.90830086959560562415e-04, /* 0x3f46a31a50b6fb3c */ + 1.45697262451506548420e-03, /* 0x3f57defc71805c40 */ + 2.99859023684906737806e-02, /* 0x3f9eb49fd80e0bab */ + 1.02538800507941396667e-02, /* 0x3f84fffc7bcd5920 */ + 1.26787628407699110022e-01, /* 0x3fc03a93b6c63435 */ + 6.86652479544033744752e-02, /* 0x3fb1940bb255fd1c */ + 4.81593627621056619148e-01, /* 0x3fded26e14260b50 */ + 1.70489513795397629181e+00, /* 0x3ffb47401fc9f2a2 */ + 1.12416073482258713767e+01, /* 0x40267bb3f55634f1 */ + 7.06579578070110514432e+00, /* 0x401c435ff8194ddc */ + 5.91244512999659974639e+01, /* 0x404d8fee052ba63a */ + 1.68921736147050694399e+02, /* 0x40651d7edccde3f6 */ + 2.60692936262073658327e+02, /* 0x40704b1644557d1a */ + 3.62419382134885609048e+02, /* 0x4076a6b5ca0a9dc4 */ + 4.07689930834187271103e+03, /* 0x40afd9cc72249aba */ + 1.55377375868385224749e+04, /* 0x40ce58de693edab5 */ + 2.53720210371943067003e+04, /* 0x40d8c70158ac6363 */ + 4.78822310734952334315e+04, /* 0x40e7614764f43e20 */ + 1.81871712615542812273e+05, /* 0x4106337db36fc718 */ + 5.62892347580489004031e+05, /* 0x41212d98b1f611e2 */ + 6.41374032312148716301e+05, /* 0x412392bc108b37cc */ + 7.57809544070145115256e+06, /* 0x415ce87bdc3473dc */ + 3.64177136406482197344e+06, /* 0x414bc8d5ae99ad14 */ + 7.63580561355670914054e+06 }; /* 0x415d20d76744835c */ + + static const double cosh_lead[37] = { + 1.00000000000000000000e+00, /* 0x3ff0000000000000 */ + 1.54308062791824340820e+00, /* 0x3ff8b07550000000 */ + 3.76219564676284790039e+00, /* 0x400e18fa08000000 */ + 1.00676617622375488281e+01, /* 0x402422a490000000 */ + 2.73082327842712402344e+01, /* 0x403b4ee858000000 */ + 7.42099475860595703125e+01, /* 0x40528d6fc8000000 */ + 2.01715633392333984375e+02, /* 0x406936e678000000 */ + 5.48317031860351562500e+02, /* 0x4081228948000000 */ + 1.49047915649414062500e+03, /* 0x409749eaa8000000 */ + 4.05154199218750000000e+03, /* 0x40afa71580000000 */ + 1.10132329101562500000e+04, /* 0x40c5829dd0000000 */ + 2.99370708007812500000e+04, /* 0x40dd3c4488000000 */ + 8.13773945312500000000e+04, /* 0x40f3de1650000000 */ + 2.21206695312500000000e+05, /* 0x410b00b590000000 */ + 6.01302140625000000000e+05, /* 0x412259ac48000000 */ + 1.63450865625000000000e+06, /* 0x4138f0cca8000000 */ + 4.44305525000000000000e+06, /* 0x4150f2ebd0000000 */ + 1.20774762500000000000e+07, /* 0x4167093488000000 */ + 3.28299845000000000000e+07, /* 0x417f4f2208000000 */ + 8.92411500000000000000e+07, /* 0x419546d8f8000000 */ + 2.42582596000000000000e+08, /* 0x41aceb0888000000 */ + 6.59407856000000000000e+08, /* 0x41c3a6e1f8000000 */ + 1.79245641600000000000e+09, /* 0x41dab5adb8000000 */ + 4.87240166400000000000e+09, /* 0x41f226af30000000 */ + 1.32445608960000000000e+10, /* 0x4208ab7fb0000000 */ + 3.60024494080000000000e+10, /* 0x4220c3d390000000 */ + 9.78648043520000000000e+10, /* 0x4236c93268000000 */ + 2.66024116224000000000e+11, /* 0x424ef822f0000000 */ + 7.23128516608000000000e+11, /* 0x42650bba30000000 */ + 1.96566712320000000000e+12, /* 0x427c9aae40000000 */ + 5.34323724288000000000e+12, /* 0x4293704708000000 */ + 1.45244246507520000000e+13, /* 0x42aa6b7658000000 */ + 3.94814795284480000000e+13, /* 0x42c1f43fc8000000 */ + 1.07321789251584000000e+14, /* 0x42d866f348000000 */ + 2.91730863685632000000e+14, /* 0x42f0953e28000000 */ + 7.93006722514944000000e+14, /* 0x430689e220000000 */ + 2.15561576592179200000e+15 }; /* 0x431ea215a0000000 */ + + static const double cosh_tail[37] = { + 0.00000000000000000000e+00, /* 0x0000000000000000 */ + 6.89700037027478056904e-09, /* 0x3e3d9f5504c2bd28 */ + 4.43207835591715833630e-08, /* 0x3e67cb66f0a4c9fd */ + 2.33540217013828929694e-07, /* 0x3e8f58617928e588 */ + 5.17452463948269748331e-08, /* 0x3e6bc7d000c38d48 */ + 9.38728274131605919153e-07, /* 0x3eaf7f9d4e329998 */ + 2.73012191010840495544e-06, /* 0x3ec6e6e464885269 */ + 3.29486051438996307950e-06, /* 0x3ecba3a8b946c154 */ + 4.75803746362771416375e-06, /* 0x3ed3f4e76110d5a4 */ + 3.33050940471947692369e-05, /* 0x3f017622515a3e2b */ + 9.94707313972136215365e-06, /* 0x3ee4dc4b528af3d0 */ + 6.51685096227860253398e-05, /* 0x3f11156278615e10 */ + 1.18132406658066663359e-03, /* 0x3f535ad50ed821f5 */ + 6.93090416366541877541e-04, /* 0x3f46b61055f2935c */ + 1.45780415323416845386e-03, /* 0x3f57e2794a601240 */ + 2.99862082708111758744e-02, /* 0x3f9eb4b45f6aadd3 */ + 1.02539925859688602072e-02, /* 0x3f85000b967b3698 */ + 1.26787669807076286421e-01, /* 0x3fc03a940fadc092 */ + 6.86652631843830962843e-02, /* 0x3fb1940bf3bf874c */ + 4.81593633223853068159e-01, /* 0x3fded26e1a2a2110 */ + 1.70489514001513020602e+00, /* 0x3ffb4740205796d6 */ + 1.12416073489841270572e+01, /* 0x40267bb3f55cb85d */ + 7.06579578098005001152e+00, /* 0x401c435ff81e18ac */ + 5.91244513000686140458e+01, /* 0x404d8fee052bdea4 */ + 1.68921736147088438429e+02, /* 0x40651d7edccde926 */ + 2.60692936262087528121e+02, /* 0x40704b1644557e0e */ + 3.62419382134890611269e+02, /* 0x4076a6b5ca0a9e1c */ + 4.07689930834187453002e+03, /* 0x40afd9cc72249abe */ + 1.55377375868385224749e+04, /* 0x40ce58de693edab5 */ + 2.53720210371943103382e+04, /* 0x40d8c70158ac6364 */ + 4.78822310734952334315e+04, /* 0x40e7614764f43e20 */ + 1.81871712615542812273e+05, /* 0x4106337db36fc718 */ + 5.62892347580489004031e+05, /* 0x41212d98b1f611e2 */ + 6.41374032312148716301e+05, /* 0x412392bc108b37cc */ + 7.57809544070145115256e+06, /* 0x415ce87bdc3473dc */ + 3.64177136406482197344e+06, /* 0x414bc8d5ae99ad14 */ + 7.63580561355670914054e+06 }; /* 0x415d20d76744835c */ + + unsigned long long ux, aux, xneg; + double y, z, z1, z2; + int m; + + /* Special cases */ + + GET_BITS_DP64(x, ux); + aux = ux & ~SIGNBIT_DP64; + if (aux < 0x3e30000000000000) /* |x| small enough that cosh(x) = 1 */ + { + return 1.0; + } + else if (aux >= PINFBITPATT_DP64) /* |x| is NaN or Inf */ + { + if (aux > PINFBITPATT_DP64) /* |x| is a NaN? */ + { +#ifdef WINDOWS + return __amd_handle_error("cosh", __amd_cosh, ux | QNANBITPATT_DP64, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); +#else + return x + x; +#endif + } + else /* x is infinity */ + { + PUT_BITS_DP64(PINFBITPATT_DP64, x); + return x; + } + } + + + xneg = (aux != ux); + + y = x; + if (xneg) y = -x; + + if (y >= max_cosh_arg) + { + /* Return +/-infinity with overflow flag */ + return __amd_handle_error("cosh", __amd_cosh, PINFBITPATT_DP64, _OVERFLOW, AMD_F_OVERFLOW, EDOM, x, 0.0, 1); + } + else if (y >= small_threshold) + { + /* In this range y is large enough so that + the negative exponential is negligible, + so cosh(y) is approximated by sign(x)*exp(y)/2. The + code below is an inlined version of that from + exp() with two changes (it operates on + y instead of x, and the division by 2 is + done by reducing m by 1). */ + + splitexp(y, 1.0, thirtytwo_by_log2, log2_by_32_lead, + log2_by_32_tail, &m, &z1, &z2); + m -= 1; + + if (m >= EMIN_DP64 && m <= EMAX_DP64) + z = scaleDouble_1((z1 + z2), m); + else + z = scaleDouble_2((z1 + z2), m); + } + else + { + /* In this range we find the integer part y0 of y + and the increment dy = y - y0. We then compute + + z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy) + z = cosh(y) = cosh(y0)cosh(dy) + sinh(y0)sinh(dy) + + where sinh(y0) and cosh(y0) are tabulated above. */ + + int ind; + double dy, dy2, sdy, cdy; + + ind = (int)y; + dy = y - ind; + + dy2 = dy * dy; + sdy = dy * dy2 * (0.166666666666666667013899e0 + + (0.833333333333329931873097e-2 + + (0.198412698413242405162014e-3 + + (0.275573191913636406057211e-5 + + (0.250521176994133472333666e-7 + + (0.160576793121939886190847e-9 + + 0.7746188980094184251527126e-12 * dy2) * dy2) * dy2) * dy2) * dy2) * dy2); + + cdy = dy2 * (0.500000000000000005911074e0 + + (0.416666666666660876512776e-1 + + (0.138888888889814854814536e-2 + + (0.248015872460622433115785e-4 + + (0.275573350756016588011357e-6 + + (0.208744349831471353536305e-8 + + 0.1163921388172173692062032e-10 * dy2) * dy2) * dy2) * dy2) * dy2) * dy2); + + /* At this point sinh(dy) is approximated by dy + sdy, and cosh(dy) is approximated by 1 + cdy. + Shift some significant bits from dy to cdy. */ +#if 0 + double sdy1, sdy2; + GET_BITS_DP64(dy, ux); + ux &= 0xfffffffff8000000; + PUT_BITS_DP64(ux, sdy1); // sdy1 is upper 53-27=26 significant bits of dy. + sdy2 = sdy + (dy - sdy1); // sdy2 is sdy + lower bits of dy + + z = ((((((cosh_tail[ind] * cdy + sinh_tail[ind] * sdy2) + + sinh_tail[ind] * sdy1) + cosh_tail[ind]) + + cosh_lead[ind] * cdy) + sinh_lead[ind] * sdy2) + + sinh_lead[ind] * sdy1) + cosh_lead[ind]; +#else + z = ((((((cosh_tail[ind] * cdy + sinh_tail[ind] * sdy) + + sinh_tail[ind] * dy) + cosh_tail[ind]) + + cosh_lead[ind] * cdy) + sinh_lead[ind] * sdy) + + sinh_lead[ind] * dy) + cosh_lead[ind]; +#endif + } + + return z; +} diff --git a/src/native/clrmath/src/ref/floor.cpp b/src/native/clrmath/src/ref/floor.cpp new file mode 100644 index 00000000000000..1f110c52a14d42 --- /dev/null +++ b/src/native/clrmath/src/ref/floor.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +double FN_PROTOTYPE_REF(floor)(double x) +{ + double r; + long long rexp, xneg; + + + unsigned long long ux, ax, ur, mask; + + GET_BITS_DP64(x, ux); + ax = ux & (~SIGNBIT_DP64); + xneg = (ux != ax); + + if (ax >= 0x4340000000000000) + { + /* abs(x) is either NaN, infinity, or >= 2^53 */ + if (ax > 0x7ff0000000000000) + { + /* x is NaN */ +#ifdef WINDOWS + return __amd_handle_error("floor", __amd_floor, ux | 0x0008000000000000, _DOMAIN, 0, EDOM, x, 0.0, 1); +#else + if (!(ax & 0x0008000000000000)) //x is snan + return __amd_handle_error("floor", __amd_floor, ux | 0x0008000000000000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); + else // x is qnan or inf + return x; +#endif + } + else + return x; + } + else if (ax < 0x3ff0000000000000) /* abs(x) < 1.0 */ + { + if (ax == 0x0000000000000000) + /* x is +zero or -zero; return the same zero */ + return x; + else if (xneg) /* x < 0.0 */ + return -1.0; + else + return 0.0; + } + else + { + r = x; + rexp = ((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; + /* Mask out the bits of r that we don't want */ + mask = 1; + mask = (mask << (EXPSHIFTBITS_DP64 - rexp)) - 1; + ur = (ux & ~mask); + PUT_BITS_DP64(ur, r); + if (xneg && (ur != ux)) + /* We threw some bits away and x was negative */ + return r - 1.0; + else + return r; + } + +} diff --git a/src/native/clrmath/src/ref/floorf.cpp b/src/native/clrmath/src/ref/floorf.cpp new file mode 100644 index 00000000000000..fdf2682a248571 --- /dev/null +++ b/src/native/clrmath/src/ref/floorf.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +float FN_PROTOTYPE_REF(floorf)(float x) +{ + float r; + int rexp, xneg; + unsigned int ux, ax, ur, mask; + + GET_BITS_SP32(x, ux); + ax = ux & (~SIGNBIT_SP32); + xneg = (ux != ax); + + if (ax >= 0x4b800000) + { + /* abs(x) is either NaN, infinity, or >= 2^24 */ + if (ax > 0x7f800000) + { + /* x is NaN */ +#ifdef WINDOWS + return __amd_handle_errorf("floorf", __amd_floor, ux | 0x00400000, _DOMAIN, 0, EDOM, x, 0.0, 1); +#else + if (!(ax & 0x00400000)) //x is snan + return __amd_handle_errorf("floorf", __amd_floor, ux | 0x00400000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); + else // x is qnan or inf + return x; +#endif + } + else + return x; + } + else if (ax < 0x3f800000) /* abs(x) < 1.0 */ + { + if (ax == 0x00000000) + /* x is +zero or -zero; return the same zero */ + return x; + else if (xneg) /* x < 0.0 */ + return -1.0F; + else + return 0.0F; + } + else + { + rexp = ((ux & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; + /* Mask out the bits of r that we don't want */ + mask = (1 << (EXPSHIFTBITS_SP32 - rexp)) - 1; + ur = (ux & ~mask); + PUT_BITS_SP32(ur, r); + if (xneg && (ux != ur)) + /* We threw some bits away and x was negative */ + return r - 1.0F; + else + return r; + } +} diff --git a/src/native/clrmath/src/ref/ilogb.cpp b/src/native/clrmath/src/ref/ilogb.cpp new file mode 100644 index 00000000000000..74489bb8b563b8 --- /dev/null +++ b/src/native/clrmath/src/ref/ilogb.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +int FN_PROTOTYPE_REF(ilogb)(double x) +{ + + + /* Check for input range */ + UT64 checkbits; + int expbits; + U64 manbits; + U64 zerovalue; + /* Clear the sign bit and check if the value is zero nan or inf.*/ + checkbits.f64 = x; + zerovalue = (checkbits.u64 & ~SIGNBIT_DP64); + + if (zerovalue == 0) + { + /* Raise exception as the number zero*/ + __amd_handle_error("ilogb", __amd_log, (unsigned long long)INT_MIN, _SING, AMD_F_DIVBYZERO, ERANGE, x, 0.0, 1); + return INT_MIN; + } + + if (zerovalue == EXPBITS_DP64) + { + /* Raise exception as the number is inf */ + if (x < 0.0) + __amd_handle_error("ilogbf", __amd_log, (unsigned int)INT_MAX, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); + else + __amd_handle_error("ilogbf", __amd_log, (unsigned int)INT_MAX, 0, AMD_F_NONE, 0, x, 0.0, 1); + return INT_MAX; + } + + if (zerovalue > EXPBITS_DP64) + { + /* Raise exception as the number is nan */ +#ifdef WINDOWS + __amd_handle_error("ilogb", __amd_log, (unsigned long long)INT_MIN, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); + return INT_MIN; +#else + //x = x+x; + //x+x is not sufficient here since we return an integer and in + //optimization mode the compiler tends to optimize out the + //x+x operation if done. + if (zerovalue >= 0x7ff8000000000000) + __amd_handle_error("ilogb", __amd_log, (unsigned long long)INT_MIN, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); + else + __amd_handle_error("ilogb", __amd_log, (unsigned long long)INT_MIN, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); + return INT_MIN; +#endif + } + + expbits = (int)((checkbits.u64 << 1) >> 53); + + if (expbits == 0 && (checkbits.u64 & MANTBITS_DP64) != 0) + { + /* the value is denormalized */ + manbits = checkbits.u64 & MANTBITS_DP64; + expbits = EMIN_DP64; + while (manbits < IMPBIT_DP64) + { + manbits <<= 1; + expbits--; + } + } + else + { + expbits -= EXPBIAS_DP64; + } + + + return expbits; +} diff --git a/src/native/clrmath/src/ref/ilogbf.cpp b/src/native/clrmath/src/ref/ilogbf.cpp new file mode 100644 index 00000000000000..8fb5ac8aae39cd --- /dev/null +++ b/src/native/clrmath/src/ref/ilogbf.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +int FN_PROTOTYPE_REF(ilogbf)(float x) +{ + + /* Check for input range */ + UT32 checkbits; + int expbits; + U32 manbits; + U32 zerovalue; + checkbits.f32 = x; + + /* Clear the sign bit and check if the value is zero nan or inf.*/ + zerovalue = (checkbits.u32 & ~SIGNBIT_SP32); + + if (zerovalue == 0) + { + /* Raise domain error as the number zero*/ + __amd_handle_errorf("ilogbf", __amd_log, (unsigned int)INT_MIN, _SING, AMD_F_DIVBYZERO, ERANGE, x, 0.0, 1); + return INT_MIN; + } + + if (zerovalue == EXPBITS_SP32) + { + /* Raise domain error as the number is inf */ + //if negative inf raise an exception + //if positive inf don't raise and exception + if (x < 0.0) + __amd_handle_errorf("ilogbf", __amd_log, (unsigned int)INT_MAX, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); + else + __amd_handle_errorf("ilogbf", __amd_log, (unsigned int)INT_MAX, 0, AMD_F_NONE, 0, x, 0.0, 1); + return INT_MAX; + } + + if (zerovalue > EXPBITS_SP32) + { + /* Raise exception as the number is inf */ +#ifdef WINDOWS + __amd_handle_errorf("ilogbf", __amd_log, (unsigned int)INT_MIN, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); + return INT_MIN; +#else + //x = x+x; + //x+x is not sufficient here since we return an integer and in + //optimization mode the compiler tends to optimize out the + //x+x operation if done. + if (zerovalue >= 0x7fC00000) + __amd_handle_errorf("ilogbf", __amd_log, (unsigned int)INT_MIN, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); + else + __amd_handle_errorf("ilogbf", __amd_log, (unsigned int)INT_MIN, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); + return INT_MIN; +#endif + } + + expbits = (int)((checkbits.u32 << 1) >> 24); + + if (expbits == 0 && (checkbits.u32 & MANTBITS_SP32) != 0) + { + /* the value is denormalized */ + manbits = checkbits.u32 & MANTBITS_SP32; + expbits = EMIN_SP32; + while (manbits < IMPBIT_SP32) + { + manbits <<= 1; + expbits--; + } + } + else + { + expbits -= EXPBIAS_SP32; + } + + return expbits; +} diff --git a/src/native/clrmath/src/ref/modf.cpp b/src/native/clrmath/src/ref/modf.cpp new file mode 100644 index 00000000000000..5d83e0616a6f2b --- /dev/null +++ b/src/native/clrmath/src/ref/modf.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +double FN_PROTOTYPE_REF(modf)(double x, double* iptr) +{ + /* modf splits the argument x into integer and fraction parts, + each with the same sign as x. */ + + + long long xexp; + unsigned long long ux, ax, mask; + + GET_BITS_DP64(x, ux); + ax = ux & (~SIGNBIT_DP64); + + if (ax >= 0x4340000000000000) + { + /* abs(x) is either NaN, infinity, or >= 2^53 */ + if (ax > 0x7ff0000000000000) + { + /* x is NaN */ + *iptr = x; +#ifdef WINDOWS + return __amd_handle_error("modf", __amd_modf, ux | 0x0008000000000000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); +#else + return x + x; +#endif + } + else + { + /* x is infinity or large. Return zero with the sign of x */ + *iptr = x; + PUT_BITS_DP64(ux & SIGNBIT_DP64, x); + return x; + } + } + else if (ax < 0x3ff0000000000000) + { + /* abs(x) < 1.0. Set iptr to zero with the sign of x + and return x. */ + PUT_BITS_DP64(ux & SIGNBIT_DP64, *iptr); + return x; + } + else + { + double r; + unsigned long long ur; + xexp = ((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; + /* Mask out the bits of x that we don't want */ + mask = 1; + mask = (mask << (EXPSHIFTBITS_DP64 - xexp)) - 1; + PUT_BITS_DP64(ux & ~mask, *iptr); + r = x - *iptr; + GET_BITS_DP64(r, ur); + PUT_BITS_DP64(((ux & SIGNBIT_DP64) | ur), r); + return r; + } + +} diff --git a/src/native/clrmath/src/ref/modff.cpp b/src/native/clrmath/src/ref/modff.cpp new file mode 100644 index 00000000000000..b24595864a38a7 --- /dev/null +++ b/src/native/clrmath/src/ref/modff.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_special.h" + +float FN_PROTOTYPE_REF(modff)(float x, float* iptr) +{ + /* modff splits the argument x into integer and fraction parts, + each with the same sign as x. */ + + unsigned int ux, mask; + int xexp; + + GET_BITS_SP32(x, ux); + xexp = ((ux & (~SIGNBIT_SP32)) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; + + if (xexp < 0) + { + /* abs(x) < 1.0. Set iptr to zero with the sign of x + and return x. */ + PUT_BITS_SP32(ux & SIGNBIT_SP32, *iptr); + return x; + } + else if (xexp < EXPSHIFTBITS_SP32) + { + float r; + unsigned int ur; + /* x lies between 1.0 and 2**(24) */ + /* Mask out the bits of x that we don't want */ + mask = (1 << (EXPSHIFTBITS_SP32 - xexp)) - 1; + PUT_BITS_SP32(ux & ~mask, *iptr); + r = x - *iptr; + GET_BITS_SP32(r, ur); + PUT_BITS_SP32(((ux & SIGNBIT_SP32) | ur), r); + return r; + } + else if ((ux & (~SIGNBIT_SP32)) > 0x7f800000) + { + /* x is NaN */ + *iptr = x; +#ifdef WINDOWS + return __amd_handle_errorf("modff", __amd_logb, ux | QNAN_MASK_32, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); /* Raise invalid if it is a signalling NaN */ +#else + return x + x; +#endif + } + else + { + /* x is infinity or large. Set iptr to x and return zero + with the sign of x. */ + *iptr = x; + PUT_BITS_SP32(ux & SIGNBIT_SP32, x); + return x; + } +} diff --git a/src/native/clrmath/src/ref/sinh.cpp b/src/native/clrmath/src/ref/sinh.cpp new file mode 100644 index 00000000000000..5e24ea535e6a54 --- /dev/null +++ b/src/native/clrmath/src/ref/sinh.cpp @@ -0,0 +1,337 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_inlines.h" +#include "libm/libm_special.h" + +double FN_PROTOTYPE_REF(sinh)(double x) +{ + /* + After dealing with special cases the computation is split into + regions as follows: + + abs(x) >= max_sinh_arg: + sinh(x) = sign(x)*Inf + + abs(x) >= small_threshold: + sinh(x) = sign(x)*exp(abs(x))/2 computed using the + splitexp and scaleDouble functions as for exp_amd(). + + abs(x) < small_threshold: + compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0))) + sinh(x) is then sign(x)*z. */ + + static const double + max_sinh_arg = 7.10475860073943977113e+02, /* 0x408633ce8fb9f87e */ + thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */ + log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */ + log2_by_32_tail = 5.68948749532545630390e-11, /* 0x3dcf473de6af278e */ + small_threshold = 8 * BASEDIGITS_DP64 * 0.30102999566398119521373889; + /* (8*BASEDIGITS_DP64*log10of2) ' exp(-x) insignificant c.f. exp(x) */ + + /* Lead and tail tabulated values of sinh(i) and cosh(i) + for i = 0,...,36. The lead part has 26 leading bits. */ + + static const double sinh_lead[37] = { + 0.00000000000000000000e+00, /* 0x0000000000000000 */ + 1.17520117759704589844e+00, /* 0x3ff2cd9fc0000000 */ + 3.62686038017272949219e+00, /* 0x400d03cf60000000 */ + 1.00178747177124023438e+01, /* 0x40240926e0000000 */ + 2.72899169921875000000e+01, /* 0x403b4a3800000000 */ + 7.42032089233398437500e+01, /* 0x40528d0160000000 */ + 2.01713153839111328125e+02, /* 0x406936d228000000 */ + 5.48316116333007812500e+02, /* 0x4081228768000000 */ + 1.49047882080078125000e+03, /* 0x409749ea50000000 */ + 4.05154187011718750000e+03, /* 0x40afa71570000000 */ + 1.10132326660156250000e+04, /* 0x40c5829dc8000000 */ + 2.99370708007812500000e+04, /* 0x40dd3c4488000000 */ + 8.13773945312500000000e+04, /* 0x40f3de1650000000 */ + 2.21206695312500000000e+05, /* 0x410b00b590000000 */ + 6.01302140625000000000e+05, /* 0x412259ac48000000 */ + 1.63450865625000000000e+06, /* 0x4138f0cca8000000 */ + 4.44305525000000000000e+06, /* 0x4150f2ebd0000000 */ + 1.20774762500000000000e+07, /* 0x4167093488000000 */ + 3.28299845000000000000e+07, /* 0x417f4f2208000000 */ + 8.92411500000000000000e+07, /* 0x419546d8f8000000 */ + 2.42582596000000000000e+08, /* 0x41aceb0888000000 */ + 6.59407856000000000000e+08, /* 0x41c3a6e1f8000000 */ + 1.79245641600000000000e+09, /* 0x41dab5adb8000000 */ + 4.87240166400000000000e+09, /* 0x41f226af30000000 */ + 1.32445608960000000000e+10, /* 0x4208ab7fb0000000 */ + 3.60024494080000000000e+10, /* 0x4220c3d390000000 */ + 9.78648043520000000000e+10, /* 0x4236c93268000000 */ + 2.66024116224000000000e+11, /* 0x424ef822f0000000 */ + 7.23128516608000000000e+11, /* 0x42650bba30000000 */ + 1.96566712320000000000e+12, /* 0x427c9aae40000000 */ + 5.34323724288000000000e+12, /* 0x4293704708000000 */ + 1.45244246507520000000e+13, /* 0x42aa6b7658000000 */ + 3.94814795284480000000e+13, /* 0x42c1f43fc8000000 */ + 1.07321789251584000000e+14, /* 0x42d866f348000000 */ + 2.91730863685632000000e+14, /* 0x42f0953e28000000 */ + 7.93006722514944000000e+14, /* 0x430689e220000000 */ + 2.15561576592179200000e+15 }; /* 0x431ea215a0000000 */ + + static const double sinh_tail[37] = { + 0.00000000000000000000e+00, /* 0x0000000000000000 */ + 1.60467555584448807892e-08, /* 0x3e513ae6096a0092 */ + 2.76742892754807136947e-08, /* 0x3e5db70cfb79a640 */ + 2.09697499555224576530e-07, /* 0x3e8c2526b66dc067 */ + 2.04940252448908240062e-07, /* 0x3e8b81b18647f380 */ + 1.65444891522700935932e-06, /* 0x3ebbc1cdd1e1eb08 */ + 3.53116789999998198721e-06, /* 0x3ecd9f201534fb09 */ + 6.94023870987375490695e-06, /* 0x3edd1c064a4e9954 */ + 4.98876893611587449271e-06, /* 0x3ed4eca65d06ea74 */ + 3.19656024605152215752e-05, /* 0x3f00c259bcc0ecc5 */ + 2.08687768377236501204e-04, /* 0x3f2b5a6647cf9016 */ + 4.84668088325403796299e-05, /* 0x3f09691adefb0870 */ + 1.17517985422733832468e-03, /* 0x3f53410fc29cde38 */ + 6.90830086959560562415e-04, /* 0x3f46a31a50b6fb3c */ + 1.45697262451506548420e-03, /* 0x3f57defc71805c40 */ + 2.99859023684906737806e-02, /* 0x3f9eb49fd80e0bab */ + 1.02538800507941396667e-02, /* 0x3f84fffc7bcd5920 */ + 1.26787628407699110022e-01, /* 0x3fc03a93b6c63435 */ + 6.86652479544033744752e-02, /* 0x3fb1940bb255fd1c */ + 4.81593627621056619148e-01, /* 0x3fded26e14260b50 */ + 1.70489513795397629181e+00, /* 0x3ffb47401fc9f2a2 */ + 1.12416073482258713767e+01, /* 0x40267bb3f55634f1 */ + 7.06579578070110514432e+00, /* 0x401c435ff8194ddc */ + 5.91244512999659974639e+01, /* 0x404d8fee052ba63a */ + 1.68921736147050694399e+02, /* 0x40651d7edccde3f6 */ + 2.60692936262073658327e+02, /* 0x40704b1644557d1a */ + 3.62419382134885609048e+02, /* 0x4076a6b5ca0a9dc4 */ + 4.07689930834187271103e+03, /* 0x40afd9cc72249aba */ + 1.55377375868385224749e+04, /* 0x40ce58de693edab5 */ + 2.53720210371943067003e+04, /* 0x40d8c70158ac6363 */ + 4.78822310734952334315e+04, /* 0x40e7614764f43e20 */ + 1.81871712615542812273e+05, /* 0x4106337db36fc718 */ + 5.62892347580489004031e+05, /* 0x41212d98b1f611e2 */ + 6.41374032312148716301e+05, /* 0x412392bc108b37cc */ + 7.57809544070145115256e+06, /* 0x415ce87bdc3473dc */ + 3.64177136406482197344e+06, /* 0x414bc8d5ae99ad14 */ + 7.63580561355670914054e+06 }; /* 0x415d20d76744835c */ + + static const double cosh_lead[37] = { + 1.00000000000000000000e+00, /* 0x3ff0000000000000 */ + 1.54308062791824340820e+00, /* 0x3ff8b07550000000 */ + 3.76219564676284790039e+00, /* 0x400e18fa08000000 */ + 1.00676617622375488281e+01, /* 0x402422a490000000 */ + 2.73082327842712402344e+01, /* 0x403b4ee858000000 */ + 7.42099475860595703125e+01, /* 0x40528d6fc8000000 */ + 2.01715633392333984375e+02, /* 0x406936e678000000 */ + 5.48317031860351562500e+02, /* 0x4081228948000000 */ + 1.49047915649414062500e+03, /* 0x409749eaa8000000 */ + 4.05154199218750000000e+03, /* 0x40afa71580000000 */ + 1.10132329101562500000e+04, /* 0x40c5829dd0000000 */ + 2.99370708007812500000e+04, /* 0x40dd3c4488000000 */ + 8.13773945312500000000e+04, /* 0x40f3de1650000000 */ + 2.21206695312500000000e+05, /* 0x410b00b590000000 */ + 6.01302140625000000000e+05, /* 0x412259ac48000000 */ + 1.63450865625000000000e+06, /* 0x4138f0cca8000000 */ + 4.44305525000000000000e+06, /* 0x4150f2ebd0000000 */ + 1.20774762500000000000e+07, /* 0x4167093488000000 */ + 3.28299845000000000000e+07, /* 0x417f4f2208000000 */ + 8.92411500000000000000e+07, /* 0x419546d8f8000000 */ + 2.42582596000000000000e+08, /* 0x41aceb0888000000 */ + 6.59407856000000000000e+08, /* 0x41c3a6e1f8000000 */ + 1.79245641600000000000e+09, /* 0x41dab5adb8000000 */ + 4.87240166400000000000e+09, /* 0x41f226af30000000 */ + 1.32445608960000000000e+10, /* 0x4208ab7fb0000000 */ + 3.60024494080000000000e+10, /* 0x4220c3d390000000 */ + 9.78648043520000000000e+10, /* 0x4236c93268000000 */ + 2.66024116224000000000e+11, /* 0x424ef822f0000000 */ + 7.23128516608000000000e+11, /* 0x42650bba30000000 */ + 1.96566712320000000000e+12, /* 0x427c9aae40000000 */ + 5.34323724288000000000e+12, /* 0x4293704708000000 */ + 1.45244246507520000000e+13, /* 0x42aa6b7658000000 */ + 3.94814795284480000000e+13, /* 0x42c1f43fc8000000 */ + 1.07321789251584000000e+14, /* 0x42d866f348000000 */ + 2.91730863685632000000e+14, /* 0x42f0953e28000000 */ + 7.93006722514944000000e+14, /* 0x430689e220000000 */ + 2.15561576592179200000e+15 }; /* 0x431ea215a0000000 */ + + static const double cosh_tail[37] = { + 0.00000000000000000000e+00, /* 0x0000000000000000 */ + 6.89700037027478056904e-09, /* 0x3e3d9f5504c2bd28 */ + 4.43207835591715833630e-08, /* 0x3e67cb66f0a4c9fd */ + 2.33540217013828929694e-07, /* 0x3e8f58617928e588 */ + 5.17452463948269748331e-08, /* 0x3e6bc7d000c38d48 */ + 9.38728274131605919153e-07, /* 0x3eaf7f9d4e329998 */ + 2.73012191010840495544e-06, /* 0x3ec6e6e464885269 */ + 3.29486051438996307950e-06, /* 0x3ecba3a8b946c154 */ + 4.75803746362771416375e-06, /* 0x3ed3f4e76110d5a4 */ + 3.33050940471947692369e-05, /* 0x3f017622515a3e2b */ + 9.94707313972136215365e-06, /* 0x3ee4dc4b528af3d0 */ + 6.51685096227860253398e-05, /* 0x3f11156278615e10 */ + 1.18132406658066663359e-03, /* 0x3f535ad50ed821f5 */ + 6.93090416366541877541e-04, /* 0x3f46b61055f2935c */ + 1.45780415323416845386e-03, /* 0x3f57e2794a601240 */ + 2.99862082708111758744e-02, /* 0x3f9eb4b45f6aadd3 */ + 1.02539925859688602072e-02, /* 0x3f85000b967b3698 */ + 1.26787669807076286421e-01, /* 0x3fc03a940fadc092 */ + 6.86652631843830962843e-02, /* 0x3fb1940bf3bf874c */ + 4.81593633223853068159e-01, /* 0x3fded26e1a2a2110 */ + 1.70489514001513020602e+00, /* 0x3ffb4740205796d6 */ + 1.12416073489841270572e+01, /* 0x40267bb3f55cb85d */ + 7.06579578098005001152e+00, /* 0x401c435ff81e18ac */ + 5.91244513000686140458e+01, /* 0x404d8fee052bdea4 */ + 1.68921736147088438429e+02, /* 0x40651d7edccde926 */ + 2.60692936262087528121e+02, /* 0x40704b1644557e0e */ + 3.62419382134890611269e+02, /* 0x4076a6b5ca0a9e1c */ + 4.07689930834187453002e+03, /* 0x40afd9cc72249abe */ + 1.55377375868385224749e+04, /* 0x40ce58de693edab5 */ + 2.53720210371943103382e+04, /* 0x40d8c70158ac6364 */ + 4.78822310734952334315e+04, /* 0x40e7614764f43e20 */ + 1.81871712615542812273e+05, /* 0x4106337db36fc718 */ + 5.62892347580489004031e+05, /* 0x41212d98b1f611e2 */ + 6.41374032312148716301e+05, /* 0x412392bc108b37cc */ + 7.57809544070145115256e+06, /* 0x415ce87bdc3473dc */ + 3.64177136406482197344e+06, /* 0x414bc8d5ae99ad14 */ + 7.63580561355670914054e+06 }; /* 0x415d20d76744835c */ + + unsigned long long ux, aux, xneg; + double y, z, z1, z2; + int m; + + /* Special cases */ + + GET_BITS_DP64(x, ux); + aux = ux & ~SIGNBIT_DP64; + if (aux < 0x3e30000000000000) /* |x| small enough that sinh(x) = x */ + { + if (aux == 0x0000000000000000) + { + /* x is +/-zero. Return the same zero. */ + return x; + } + else + { + +#ifdef WINDOWS + return x; +#else + return __amd_handle_error("sinh", __amd_sinh, ux, _UNDERFLOW, AMD_F_INEXACT | AMD_F_UNDERFLOW, ERANGE, x, 0.0, 1); +#endif + } + } + else if (aux == 0x7ff0000000000000) /* |x| is Inf */ + { + return x; + } + else if (aux > 0x7ff0000000000000) /* |x| is NaN */ + { +#ifdef WINDOWS + return __amd_handle_error("sinh", __amd_sinh, ux | QNANBITPATT_DP64, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); +#else + return x + x; +#endif + } + + + xneg = (aux != ux); + + y = x; + if (xneg) y = -x; + + if (y >= max_sinh_arg) + { + /* Return +/-infinity with overflow flag */ + if (xneg) + return __amd_handle_error("sinh", __amd_sinh, NINFBITPATT_DP64, _OVERFLOW, AMD_F_OVERFLOW, ERANGE, x, 0.0, 1); + else + return __amd_handle_error("sinh", __amd_sinh, PINFBITPATT_DP64, _OVERFLOW, AMD_F_OVERFLOW, ERANGE, x, 0.0, 1); + + } + else if (y >= small_threshold) + { + /* In this range y is large enough so that + the negative exponential is negligible, + so sinh(y) is approximated by sign(x)*exp(y)/2. The + code below is an inlined version of that from + exp() with two changes (it operates on + y instead of x, and the division by 2 is + done by reducing m by 1). */ + + splitexp(y, 1.0, thirtytwo_by_log2, log2_by_32_lead, + log2_by_32_tail, &m, &z1, &z2); + m -= 1; + + if (m >= EMIN_DP64 && m <= EMAX_DP64) + z = scaleDouble_1((z1 + z2), m); + else + z = scaleDouble_2((z1 + z2), m); + } + else + { + /* In this range we find the integer part y0 of y + and the increment dy = y - y0. We then compute + + z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy) + + where sinh(y0) and cosh(y0) are tabulated above. */ + + int ind; + double dy, dy2, sdy, cdy, sdy1, sdy2; + + ind = (int)y; + dy = y - ind; + + dy2 = dy * dy; + sdy = dy * dy2 * (0.166666666666666667013899e0 + + (0.833333333333329931873097e-2 + + (0.198412698413242405162014e-3 + + (0.275573191913636406057211e-5 + + (0.250521176994133472333666e-7 + + (0.160576793121939886190847e-9 + + 0.7746188980094184251527126e-12 * dy2) * dy2) * dy2) * dy2) * dy2) * dy2); + + cdy = dy2 * (0.500000000000000005911074e0 + + (0.416666666666660876512776e-1 + + (0.138888888889814854814536e-2 + + (0.248015872460622433115785e-4 + + (0.275573350756016588011357e-6 + + (0.208744349831471353536305e-8 + + 0.1163921388172173692062032e-10 * dy2) * dy2) * dy2) * dy2) * dy2) * dy2); + + /* At this point sinh(dy) is approximated by dy + sdy. + Shift some significant bits from dy to sdy. */ + + GET_BITS_DP64(dy, ux); + ux &= 0xfffffffff8000000; + PUT_BITS_DP64(ux, sdy1); + sdy2 = sdy + (dy - sdy1); + + z = ((((((cosh_tail[ind] * sdy2 + sinh_tail[ind] * cdy) + + cosh_tail[ind] * sdy1) + sinh_tail[ind]) + + cosh_lead[ind] * sdy2) + sinh_lead[ind] * cdy) + + cosh_lead[ind] * sdy1) + sinh_lead[ind]; + } + + if (xneg) z = -z; + return z; +} diff --git a/src/native/clrmath/src/ref/sinhf.cpp b/src/native/clrmath/src/ref/sinhf.cpp new file mode 100644 index 00000000000000..c8680cb42a6d9f --- /dev/null +++ b/src/native/clrmath/src/ref/sinhf.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_inlines.h" +#include "libm/libm_special.h" + +float FN_PROTOTYPE_REF(sinhf)(float fx) +{ + /* + After dealing with special cases the computation is split into + regions as follows: + + abs(x) >= max_sinh_arg: + sinh(x) = sign(x)*Inf + + abs(x) >= small_threshold: + sinh(x) = sign(x)*exp(abs(x))/2 computed using the + splitexp and scaleDouble functions as for exp_amd(). + + abs(x) < small_threshold: + compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0))) + sinh(x) is then sign(x)*z. */ + + static const double + /* The max argument of sinhf, but stored as a double */ + max_sinh_arg = 8.94159862922329438106e+01, /* 0x40565a9f84f82e63 */ + thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */ + log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */ + log2_by_32_tail = 5.68948749532545630390e-11, /* 0x3dcf473de6af278e */ + small_threshold = 8 * BASEDIGITS_DP64 * 0.30102999566398119521373889; + /* (8*BASEDIGITS_DP64*log10of2) ' exp(-x) insignificant c.f. exp(x) */ + + /* Tabulated values of sinh(i) and cosh(i) for i = 0,...,36. */ + + static const double sinh_lead[37] = { + 0.00000000000000000000e+00, /* 0x0000000000000000 */ + 1.17520119364380137839e+00, /* 0x3ff2cd9fc44eb982 */ + 3.62686040784701857476e+00, /* 0x400d03cf63b6e19f */ + 1.00178749274099008204e+01, /* 0x40240926e70949ad */ + 2.72899171971277496596e+01, /* 0x403b4a3803703630 */ + 7.42032105777887522891e+01, /* 0x40528d0166f07374 */ + 2.01713157370279219549e+02, /* 0x406936d22f67c805 */ + 5.48316123273246489589e+02, /* 0x408122876ba380c9 */ + 1.49047882578955000099e+03, /* 0x409749ea514eca65 */ + 4.05154190208278987484e+03, /* 0x40afa7157430966f */ + 1.10132328747033916443e+04, /* 0x40c5829dced69991 */ + 2.99370708492480553105e+04, /* 0x40dd3c4488cb48d6 */ + 8.13773957064298447222e+04, /* 0x40f3de1654d043f0 */ + 2.21206696003330085659e+05, /* 0x410b00b5916a31a5 */ + 6.01302142081972560845e+05, /* 0x412259ac48bef7e3 */ + 1.63450868623590236530e+06, /* 0x4138f0ccafad27f6 */ + 4.44305526025387924165e+06, /* 0x4150f2ebd0a7ffe3 */ + 1.20774763767876271158e+07, /* 0x416709348c0ea4ed */ + 3.28299845686652474105e+07, /* 0x417f4f22091940bb */ + 8.92411504815936237574e+07, /* 0x419546d8f9ed26e1 */ + 2.42582597704895108938e+08, /* 0x41aceb088b68e803 */ + 6.59407867241607308388e+08, /* 0x41c3a6e1fd9eecfd */ + 1.79245642306579566002e+09, /* 0x41dab5adb9c435ff */ + 4.87240172312445068359e+09, /* 0x41f226af33b1fdc0 */ + 1.32445610649217357635e+10, /* 0x4208ab7fb5475fb7 */ + 3.60024496686929321289e+10, /* 0x4220c3d3920962c8 */ + 9.78648047144193725586e+10, /* 0x4236c932696a6b5c */ + 2.66024120300899291992e+11, /* 0x424ef822f7f6731c */ + 7.23128532145737548828e+11, /* 0x42650bba3796379a */ + 1.96566714857202099609e+12, /* 0x427c9aae4631c056 */ + 5.34323729076223046875e+12, /* 0x429370470aec28ec */ + 1.45244248326237109375e+13, /* 0x42aa6b765d8cdf6c */ + 3.94814800913403437500e+13, /* 0x42c1f43fcc4b662c */ + 1.07321789892958031250e+14, /* 0x42d866f34a725782 */ + 2.91730871263727437500e+14, /* 0x42f0953e2f3a1ef7 */ + 7.93006726156715250000e+14, /* 0x430689e221bc8d5a */ + 2.15561577355759750000e+15 }; /* 0x431ea215a1d20d76 */ + + static const double cosh_lead[37] = { + 1.00000000000000000000e+00, /* 0x3ff0000000000000 */ + 1.54308063481524371241e+00, /* 0x3ff8b07551d9f550 */ + 3.76219569108363138810e+00, /* 0x400e18fa0df2d9bc */ + 1.00676619957777653269e+01, /* 0x402422a497d6185e */ + 2.73082328360164865444e+01, /* 0x403b4ee858de3e80 */ + 7.42099485247878334349e+01, /* 0x40528d6fcbeff3a9 */ + 2.01715636122455890700e+02, /* 0x406936e67db9b919 */ + 5.48317035155212010977e+02, /* 0x4081228949ba3a8b */ + 1.49047916125217807348e+03, /* 0x409749eaa93f4e76 */ + 4.05154202549259389343e+03, /* 0x40afa715845d8894 */ + 1.10132329201033226127e+04, /* 0x40c5829dd053712d */ + 2.99370708659497577173e+04, /* 0x40dd3c4489115627 */ + 8.13773957125740562333e+04, /* 0x40f3de1654d6b543 */ + 2.21206696005590405548e+05, /* 0x410b00b5916b6105 */ + 6.01302142082804115489e+05, /* 0x412259ac48bf13ca */ + 1.63450868623620807193e+06, /* 0x4138f0ccafad2d17 */ + 4.44305526025399193168e+06, /* 0x4150f2ebd0a8005c */ + 1.20774763767876680940e+07, /* 0x416709348c0ea503 */ + 3.28299845686652623117e+07, /* 0x417f4f22091940bf */ + 8.92411504815936237574e+07, /* 0x419546d8f9ed26e1 */ + 2.42582597704895138741e+08, /* 0x41aceb088b68e804 */ + 6.59407867241607308388e+08, /* 0x41c3a6e1fd9eecfd */ + 1.79245642306579566002e+09, /* 0x41dab5adb9c435ff */ + 4.87240172312445068359e+09, /* 0x41f226af33b1fdc0 */ + 1.32445610649217357635e+10, /* 0x4208ab7fb5475fb7 */ + 3.60024496686929321289e+10, /* 0x4220c3d3920962c8 */ + 9.78648047144193725586e+10, /* 0x4236c932696a6b5c */ + 2.66024120300899291992e+11, /* 0x424ef822f7f6731c */ + 7.23128532145737548828e+11, /* 0x42650bba3796379a */ + 1.96566714857202099609e+12, /* 0x427c9aae4631c056 */ + 5.34323729076223046875e+12, /* 0x429370470aec28ec */ + 1.45244248326237109375e+13, /* 0x42aa6b765d8cdf6c */ + 3.94814800913403437500e+13, /* 0x42c1f43fcc4b662c */ + 1.07321789892958031250e+14, /* 0x42d866f34a725782 */ + 2.91730871263727437500e+14, /* 0x42f0953e2f3a1ef7 */ + 7.93006726156715250000e+14, /* 0x430689e221bc8d5a */ + 2.15561577355759750000e+15 }; /* 0x431ea215a1d20d76 */ + + unsigned long long aux, xneg; + unsigned int ux; + double y, z, z1, z2; + int m; + + /* Special cases */ + + GET_BITS_SP32(fx, ux); + aux = ux & ~SIGNBIT_SP32; + + if (aux < 0x38800000) /* |x| small enough that sinh(x) = x */ + { + if (aux == 0x00000000) + { + /* x is +/-zero. Return the same zero. */ + return fx; + } + else + { +#ifdef WINDOWS + return fx; +#else + return __amd_handle_errorf("sinhf", __amd_sinh, ux, _UNDERFLOW, AMD_F_INEXACT | AMD_F_UNDERFLOW, ERANGE, fx, 0.0, 1); +#endif + } + } + else if (aux == 0x7f800000) /* |x| is NaN or Inf */ + { + return fx; + } + else if (aux > 0x7f800000) + { +#ifdef WINDOWS + return __amd_handle_errorf("sinhf", __amd_sinh, ux | QNANBITPATT_SP32, _DOMAIN, AMD_F_NONE, EDOM, fx, 0.0, 1); +#else + return fx + fx; +#endif + } + + xneg = (aux != ux); + + y = fx; + if (xneg) y = -fx; + + if (y >= max_sinh_arg) + { + /* Return infinity with overflow flag. */ + if (xneg) + return __amd_handle_errorf("sinh", __amd_sinh, NINFBITPATT_SP32, _OVERFLOW, AMD_F_OVERFLOW, ERANGE, fx, 0.0, 1); + else + return __amd_handle_errorf("sinh", __amd_sinh, PINFBITPATT_SP32, _OVERFLOW, AMD_F_OVERFLOW, ERANGE, fx, 0.0, 1); + } + else if (y >= small_threshold) + { + /* In this range y is large enough so that + the negative exponential is negligible, + so sinh(y) is approximated by sign(x)*exp(y)/2. The + code below is an inlined version of that from + exp() with two changes (it operates on + y instead of x, and the division by 2 is + done by reducing m by 1). */ + + splitexp(y, 1.0, thirtytwo_by_log2, log2_by_32_lead, + log2_by_32_tail, &m, &z1, &z2); + m -= 1; + /* scaleDouble_1 is always safe because the argument x was + float, rather than double */ + z = scaleDouble_1((z1 + z2), m); + } + else + { + /* In this range we find the integer part y0 of y + and the increment dy = y - y0. We then compute + + z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy) + + where sinh(y0) and cosh(y0) are tabulated above. */ + + int ind; + double dy, dy2, sdy, cdy; + + ind = (int)y; + dy = y - ind; + + dy2 = dy * dy; + + sdy = dy + dy * dy2 * (0.166666666666666667013899e0 + + (0.833333333333329931873097e-2 + + (0.198412698413242405162014e-3 + + (0.275573191913636406057211e-5 + + (0.250521176994133472333666e-7 + + (0.160576793121939886190847e-9 + + 0.7746188980094184251527126e-12 * dy2) * dy2) * dy2) * dy2) * dy2) * dy2); + + cdy = 1 + dy2 * (0.500000000000000005911074e0 + + (0.416666666666660876512776e-1 + + (0.138888888889814854814536e-2 + + (0.248015872460622433115785e-4 + + (0.275573350756016588011357e-6 + + (0.208744349831471353536305e-8 + + 0.1163921388172173692062032e-10 * dy2) * dy2) * dy2) * dy2) * dy2) * dy2); + + z = sinh_lead[ind] * cdy + cosh_lead[ind] * sdy; + } + + if (xneg) z = -z; + return (float)z; +} diff --git a/src/native/clrmath/src/ref/tanh.cpp b/src/native/clrmath/src/ref/tanh.cpp new file mode 100644 index 00000000000000..5ba9a066a2806e --- /dev/null +++ b/src/native/clrmath/src/ref/tanh.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "clrmath.h" +#include "libm/libm_util.h" +#include "libm/libm_inlines.h" +#include "libm/libm_special.h" + +double FN_PROTOTYPE_REF(tanh)(double x) +{ + /* + The definition of tanh(x) is sinh(x)/cosh(x), which is also equivalent + to the following three formulae: + 1. (exp(x) - exp(-x))/(exp(x) + exp(-x)) + 2. (1 - (2/(exp(2*x) + 1 ))) + 3. (exp(2*x) - 1)/(exp(2*x) + 1) + but computationally, some formulae are better on some ranges. + */ + static const double + thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */ + log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */ + log2_by_32_tail = 5.68948749532545630390e-11, /* 0x3dcf473de6af278e */ + large_threshold = 20.0; /* 0x4034000000000000 */ + + unsigned long long ux, aux, xneg; + double y, z, p, z1, z2; + int m; + + /* Special cases */ + + GET_BITS_DP64(x, ux); + aux = ux & ~SIGNBIT_DP64; + if (aux < 0x3e30000000000000) /* |x| small enough that tanh(x) = x */ + { + if (aux == 0x0000000000000000) + { + /* x is +/-zero. Return the same zero. */ + return x; + } + else + { +#ifdef WINDOWS + return x; +#else + return __amd_handle_error("tanh", __amd_tanh, ux, _UNDERFLOW, AMD_F_INEXACT | AMD_F_UNDERFLOW, ERANGE, x, 0.0, 1); +#endif + } + } + else if (aux > 0x7ff0000000000000) /* |x| is NaN */ + { +#ifdef WINDOWS + return __amd_handle_error("tanh", __amd_tanh, ux | QNANBITPATT_DP64, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); +#else + return x + x; +#endif + } + + xneg = (aux != ux); + + y = x; + if (xneg) y = -x; + + if (y > large_threshold) + { + /* If x is large then exp(-x) is negligible and + formula 1 reduces to plus or minus 1.0 */ + z = 1.0; + } + else if (y <= 1.0) + { + double y2; + y2 = y * y; + if (y < 0.9) + { + /* Use a [3,3] Remez approximation on [0,0.9]. */ + z = y + y * y2 * + (-0.274030424656179760118928e0 + + (-0.176016349003044679402273e-1 + + (-0.200047621071909498730453e-3 - + 0.142077926378834722618091e-7 * y2) * y2) * y2) / + (0.822091273968539282568011e0 + + (0.381641414288328849317962e0 + + (0.201562166026937652780575e-1 + + 0.2091140262529164482568557e-3 * y2) * y2) * y2); + } + else + { + /* Use a [3,3] Remez approximation on [0.9,1]. */ + z = y + y * y2 * + (-0.227793870659088295252442e0 + + (-0.146173047288731678404066e-1 + + (-0.165597043903549960486816e-3 - + 0.115475878996143396378318e-7 * y2) * y2) * y2) / + (0.683381611977295894959554e0 + + (0.317204558977294374244770e0 + + (0.167358775461896562588695e-1 + + 0.173076050126225961768710e-3 * y2) * y2) * y2); + } + } + else + { + /* Compute p = exp(2*y) + 1. The code is basically inlined + from exp_amd. */ + + splitexp(2 * y, 1.0, thirtytwo_by_log2, log2_by_32_lead, + log2_by_32_tail, &m, &z1, &z2); + p = scaleDouble_2(z1 + z2, m) + 1.0; + + /* Now reconstruct tanh from p. */ + z = (1.0 - 2.0 / p); + } + + if (xneg) z = -z; + return z; +}