Adding single-precision math functions. (#5492)
authorTanner Gooding <tannergooding@users.noreply.github.com>
Tue, 18 Oct 2016 09:56:53 +0000 (02:56 -0700)
committerJan Vorlicek <janvorli@microsoft.com>
Tue, 18 Oct 2016 09:56:53 +0000 (11:56 +0200)
* Adding single-precision math functions to floatsingle
* Adding single-precision math functions to the PAL layer.
* Adding single-precision math tests to the PAL layer.
* Adding single-precision math functions to mscorlib.
* Adding single-precision math function support to the vm.
* Updating floatsingle.cpp to define a _isnanf macro for Windows ARM.

91 files changed:
src/classlibnative/float/floatsingle.cpp
src/classlibnative/inc/floatsingle.h
src/mscorlib/model.xml
src/mscorlib/mscorlib.shared.sources.props
src/mscorlib/ref/mscorlib.cs
src/mscorlib/src/System/BitConverter.cs
src/mscorlib/src/System/MathF.cs [new file with mode: 0644]
src/mscorlib/src/System/Single.cs
src/pal/inc/pal.h
src/pal/src/cruntime/math.cpp
src/pal/src/include/pal/palinternal.h
src/pal/tests/palsuite/c_runtime/CMakeLists.txt
src/pal/tests/palsuite/c_runtime/_finitef/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/_finitef/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/_finitef/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/_finitef/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/_isnanf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/_isnanf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/_isnanf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/_isnanf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/acosf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/acosf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/acosf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/acosf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/asinf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/asinf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/asinf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/asinf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/atan2f/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/atan2f/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/atan2f/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/atan2f/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/atanf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/atanf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/atanf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/atanf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/ceilf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/ceilf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/ceilf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/ceilf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/cosf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/cosf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/cosf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/cosf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/coshf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/coshf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/coshf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/coshf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/expf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/expf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/expf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/expf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/floorf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/floorf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/floorf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/floorf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/log10f/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/log10f/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/log10f/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/log10f/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/logf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/logf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/logf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/logf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/powf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/powf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/powf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/powf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sinf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sinf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sinf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sinf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sinhf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sinhf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sinhf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sinhf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sqrtf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sqrtf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sqrtf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/sqrtf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/tanf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/tanf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/tanf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/tanf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/tanhf/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/tanhf/test1/CMakeLists.txt [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/tanhf/test1/test1.c [new file with mode: 0644]
src/pal/tests/palsuite/c_runtime/tanhf/test1/testinfo.dat [new file with mode: 0644]
src/pal/tests/palsuite/paltestlist.txt
src/pal/tests/palsuite/palverify.dat
src/vm/ecalllist.h

index dd1bb43..daf8999 100644 (file)
 
 #define IS_FLT_INFINITY(x)         (((*((INT32*)((void*)&x))) & 0x7FFFFFFF) == 0x7F800000)
 
+// Windows x86 and Windows ARM don't define _isnanf() but they do define a generic macro isnan()
+#if (defined(_TARGET_X86_) || defined(_TARGET_ARM_)) && !defined(FEATURE_PAL) && !defined(_isnanf)
+#define _isnanf      isnan
+#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
@@ -39,6 +44,218 @@ FCIMPL1(float, COMSingle::Abs, float x)
     return (float)fabsf(x);
 FCIMPLEND
 
+/*=====================================Acos=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Acos, float x)
+    FCALL_CONTRACT;
+
+    return (float)acosf(x);
+FCIMPLEND
+
+/*=====================================Asin=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Asin, float x)
+    FCALL_CONTRACT;
+
+    return (float)asinf(x);
+FCIMPLEND
+
+/*=====================================Atan=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Atan, float x)
+    FCALL_CONTRACT;
+
+    return (float)atanf(x);
+FCIMPLEND
+
+/*=====================================Atan2====================================
+**
+==============================================================================*/
+FCIMPL2(float, COMSingle::Atan2, float y, float x)
+    FCALL_CONTRACT;
+
+    // atan2f(+/-INFINITY, +/-INFINITY) produces +/-0.785398163f (x is +INFINITY) and
+    // +/-2.35619449f (x is -INFINITY) instead of the expected value of NaN. We handle
+    // that case here ourselves.
+    if (IS_FLT_INFINITY(y) && IS_FLT_INFINITY(x)) {
+        return (float)(y / x);
+    }
+
+    return (float)atan2f(y, x);
+FCIMPLEND
+
+/*====================================Ceil======================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Ceil, float x)
+    FCALL_CONTRACT;
+
+    return (float)ceilf(x);
+FCIMPLEND
+
+/*=====================================Cos======================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Cos, float x)
+    FCALL_CONTRACT;
+
+    return (float)cosf(x);
+FCIMPLEND
+
+/*=====================================Cosh=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Cosh, float x)
+    FCALL_CONTRACT;
+
+    return (float)coshf(x);
+FCIMPLEND
+
+/*=====================================Exp======================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Exp, float x)
+    FCALL_CONTRACT;
+
+    return (float)expf(x);
+FCIMPLEND
+
+/*====================================Floor=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Floor, float x)
+    FCALL_CONTRACT;
+
+    return (float)floorf(x);
+FCIMPLEND
+
+/*=====================================Log======================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Log, float x)
+    FCALL_CONTRACT;
+
+    return (float)logf(x);
+FCIMPLEND
+
+/*====================================Log10=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Log10, float x)
+    FCALL_CONTRACT;
+
+    return (float)log10f(x);
+FCIMPLEND
+
+/*=====================================ModF=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::ModF, float* iptr)
+    FCALL_CONTRACT;
+
+    return (float)modff(*iptr, iptr);
+FCIMPLEND
+
+/*=====================================Pow======================================
+**
+==============================================================================*/
+FCIMPL2(float, COMSingle::Pow, float x, float y)
+    FCALL_CONTRACT;
+
+    // The CRT version of pow preserves the NaN payload of x over the NaN payload of y.
+
+    if(_isnanf(y)) {
+        return y; // IEEE 754-2008: NaN payload must be preserved
+    }
+
+    if(_isnanf(x)) {
+        return x; // IEEE 754-2008: NaN payload must be preserved
+    }
+
+    // The CRT version of powf does not return NaN for powf(-1.0f, +/-INFINITY) and
+    // instead returns +1.0f.
+
+    if(IS_FLT_INFINITY(y) && (x == -1.0f)) {
+        INT32 result = CLR_NAN_32;
+        return (*((float*)((INT32*)&result)));
+    }
+
+    return (float)powf(x, y);
+FCIMPLEND
+
+/*====================================Round=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Round, float x)
+    FCALL_CONTRACT;
+
+    // If the number has no fractional part do nothing
+    // This shortcut is necessary to workaround precision loss in borderline cases on some platforms
+    if (x == (float)((INT32)x)) {
+        return x;
+    }
+
+    // We had a number that was equally close to 2 integers.
+    // We need to return the even one.
+
+    float tempVal = (x + 0.5f);
+    float flrTempVal = floorf(tempVal);
+
+    if ((flrTempVal == tempVal) && (fmodf(tempVal, 2.0f) != 0)) {
+        flrTempVal -= 1.0f;
+    }
+
+    return _copysignf(flrTempVal, x);
+FCIMPLEND
+
+/*=====================================Sin======================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Sin, float x)
+    FCALL_CONTRACT;
+
+    return (float)sinf(x);
+FCIMPLEND
+
+/*=====================================Sinh=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Sinh, float x)
+    FCALL_CONTRACT;
+
+    return (float)sinhf(x);
+FCIMPLEND
+
+/*=====================================Sqrt=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Sqrt, float x)
+    FCALL_CONTRACT;
+
+    return (float)sqrtf(x);
+FCIMPLEND
+
+/*=====================================Tan======================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Tan, float x)
+    FCALL_CONTRACT;
+
+    return (float)tanf(x);
+FCIMPLEND
+
+/*=====================================Tanh=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Tanh, float x)
+    FCALL_CONTRACT;
+
+    return (float)tanhf(x);
+FCIMPLEND
+
 #ifdef _MSC_VER
 #pragma float_control(precise, on )
 #endif
index 6d123ec..f8a1dda 100644 (file)
 class COMSingle {
 public:
     FCDECL1(static float, Abs, float x);
+    FCDECL1(static float, Acos, float x);
+    FCDECL1(static float, Asin, float x);
+    FCDECL1(static float, Atan, float x);
+    FCDECL2(static float, Atan2, float y, float x);
+    FCDECL1(static float, Ceil, float x);
+    FCDECL1(static float, Cos, float x);
+    FCDECL1(static float, Cosh, float x);
+    FCDECL1(static float, Exp, float x);
+    FCDECL1(static float, Floor, float x);
+    FCDECL1(static float, Log, float x);
+    FCDECL1(static float, Log10, float x);
+    FCDECL1(static float, ModF, float* iptr);
+    FCDECL2(static float, Pow, float x, float y);
+    FCDECL1(static float, Round, float x);
+    FCDECL1(static float, Sin, float x);
+    FCDECL1(static float, Sinh, float x);
+    FCDECL1(static float, Sqrt, float x);
+    FCDECL1(static float, Tan, float x);
+    FCDECL1(static float, Tanh, float x);
 };
 
 #endif // _FLOATSINGLE_H_
index 0f18f46..70b2597 100644 (file)
     </Type>
     <Type Name="System.BitConverter">
       <Member Name="DoubleToInt64Bits(System.Double)" />
+      <Member Name="Int32BitsToSingle(System.Int32)" />
       <Member Name="Int64BitsToDouble(System.Int64)" />
       <Member MemberType="Field" Name="IsLittleEndian" />
       <Member Name="GetBytes(System.Boolean)" />
       <Member Name="GetBytes(System.UInt32)" />
       <Member Name="GetBytes(System.UInt64)" />
       <Member Name="GetBytes(System.UInt16)" />
+      <Member Name="SingleToInt32Bits(System.Single)" />
       <Member Name="ToBoolean(System.Byte[],System.Int32)" />
       <Member Name="ToChar(System.Byte[],System.Int32)" />
       <Member Name="ToDouble(System.Byte[],System.Int32)" />
       <Member Name="Truncate(System.Decimal)"  />
       <Member Name="Truncate(System.Double)"  />
     </Type>
+    <Type Name="System.MathF">
+      <Member MemberType="Field" Name="E" />
+      <Member MemberType="Field" Name="PI" />
+      <Member Name="Abs(System.Single)" />
+      <Member Name="Acos(System.Single)" />
+      <Member Name="Asin(System.Single)" />
+      <Member Name="Atan(System.Single)" />
+      <Member Name="Atan2(System.Single,System.Single)" />
+      <Member Name="Ceiling(System.Single)"/>
+      <Member Name="Cos(System.Single)" />
+      <Member Name="Cosh(System.Single)" />
+      <Member Name="Exp(System.Single)" />
+      <Member Name="Floor(System.Single)" />
+      <Member Name="IEEERemainder(System.Single,System.Single)" />
+      <Member Name="Log(System.Single)" />
+      <Member Name="Log(System.Single,System.Single)" />
+      <Member Name="Log10(System.Single)" />
+      <Member Name="Max(System.Single,System.Single)" />
+      <Member Name="Min(System.Single,System.Single)" />
+      <Member Name="Pow(System.Single,System.Single)" />
+      <Member Name="Round(System.Single)" />
+      <Member Name="Round(System.Single,System.Int32)" />
+      <Member Name="Round(System.Single,System.Int32,System.MidpointRounding)"  />
+      <Member Name="Round(System.Single,System.MidpointRounding)"  />
+      <Member Name="Sign(System.Single)" />
+      <Member Name="Sin(System.Single)" />
+      <Member Name="Sinh(System.Single)" />
+      <Member Name="Sqrt(System.Single)" />
+      <Member Name="Tan(System.Single)" />
+      <Member Name="Tanh(System.Single)" />
+      <Member Name="Truncate(System.Single)"  />
+    </Type>
     <Type Name="System.MemberAccessException">
       <Member Name="#ctor" />
       <Member Name="#ctor(System.String)" />
index 459c18b..63c4e3f 100644 (file)
     <SystemSources Include="$(BclSourcesRoot)\System\_LocalDataStoreMgr.cs" />
     <SystemSources Include="$(BclSourcesRoot)\System\MarshalByRefObject.cs" />
     <SystemSources Include="$(BclSourcesRoot)\System\Math.cs" />
+    <SystemSources Include="$(BclSourcesRoot)\System\MathF.cs" />
     <SystemSources Include="$(BclSourcesRoot)\System\mda.cs" />
     <SystemSources Include="$(BclSourcesRoot)\System\MethodAccessException.cs" />
     <SystemSources Include="$(BclSourcesRoot)\System\MidpointRounding.cs" />
index 1e59ef7..4160762 100644 (file)
@@ -603,7 +603,11 @@ namespace System
         [System.CLSCompliantAttribute(false)]
         public static byte[] GetBytes(ulong value) { throw null; }
         [System.Security.SecuritySafeCriticalAttribute]
+        public static float Int32BitsToSingle(int value) { throw null; }
+        [System.Security.SecuritySafeCriticalAttribute]
         public static double Int64BitsToDouble(long value) { throw null; }
+        [System.Security.SecuritySafeCriticalAttribute]
+        public static int SingleToInt32Bits(float value) { throw null; }
         public static bool ToBoolean(byte[] value, int startIndex) { throw null; }
         public static char ToChar(byte[] value, int startIndex) { throw null; }
         [System.Security.SecuritySafeCriticalAttribute]
@@ -2622,6 +2626,59 @@ namespace System
         public static decimal Truncate(decimal d) { throw null; }
         public static double Truncate(double d) { throw null; }
     }
+    public static partial class MathF
+    {
+        public const float E =  2.71828183f;
+        public const float PI = 3.14159265f;
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Abs(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Acos(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Asin(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Atan(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Atan2(float y, float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Ceiling(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Cos(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Cosh(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Exp(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Floor(float x) { return default(float); }
+        public static float IEEERemainder(float x, float y) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Log(float x) { return default(float); }
+        public static float Log(float x, float y) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Log10(float x) { return default(float); }        
+        public static float Max(float x, float y) { return default(float); }
+        public static float Min(float x, float y) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Pow(float x, float y) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Round(float x) { return default(float); }
+        public static float Round(float x, int digits) { return default(float); }
+        public static float Round(float x, int digits, System.MidpointRounding mode) { return default(float); }
+        public static float Round(float x, System.MidpointRounding mode) { return default(float); }
+        public static int Sign(float x) { return default(int); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Sin(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Sinh(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
+        [System.Security.SecuritySafeCriticalAttribute]
+        public static float Sqrt(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Tan(float x) { return default(float); }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
+        public static float Tanh(float x) { return default(float); }
+        public static float Truncate(float x) { return default(float); }
+    }
     [System.Runtime.InteropServices.ComVisibleAttribute(true)]
     public partial class MemberAccessException : System.SystemException
     {
index 5ecb130..8be545c 100644 (file)
@@ -446,6 +446,16 @@ namespace System {
         [SecuritySafeCritical]
         public static unsafe double Int64BitsToDouble(long value) {
             return *((double*)&value);
-        }                    
+        }
+
+        [SecuritySafeCritical]
+        public static unsafe int SingleToInt32Bits(float value) {
+            return *((int*)&value);
+        }
+
+        [SecuritySafeCritical]
+        public static unsafe float Int32BitsToSingle(int value) {
+            return *((float*)&value);
+        }
     }
 }
diff --git a/src/mscorlib/src/System/MathF.cs b/src/mscorlib/src/System/MathF.cs
new file mode 100644 (file)
index 0000000..bca5559
--- /dev/null
@@ -0,0 +1,292 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================
+**
+** Purpose: Some single-precision floating-point math operations
+**
+===========================================================*/
+namespace System {
+
+    //This class contains only static members and doesn't require serialization.
+    using System;
+    using System.Runtime;
+    using System.Runtime.CompilerServices;
+    using System.Runtime.ConstrainedExecution;
+    using System.Runtime.Versioning;
+    using System.Diagnostics.Contracts;
+
+    public static class MathF
+    {
+        private static float singleRoundLimit = 1e8f;
+
+        private const int maxRoundingDigits = 6;
+
+        // This table is required for the Round function which can specify the number of digits to round to
+        private static float[] roundPower10Single = new float[] {
+            1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 1e6f
+        };
+
+        public const float PI = 3.14159265f;
+
+        public const float E = 2.71828183f;
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Abs(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Acos(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Asin(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Atan(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Atan2(float y, float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Ceiling(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Cos(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Cosh(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Exp(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Floor(float x);
+
+        public static float IEEERemainder(float x, float y)
+        {
+            if (float.IsNaN(x))
+            {
+                return x; // IEEE 754-2008: NaN payload must be preserved
+            }
+
+            if (float.IsNaN(y))
+            {
+                return y; // IEEE 754-2008: NaN payload must be preserved
+            }
+
+            var regularMod = x % y;
+
+            if (float.IsNaN(regularMod))
+            {
+              return float.NaN;
+            }
+
+            if ((regularMod == 0) && float.IsNegative(x))
+            {
+                return float.NegativeZero;
+            }
+
+            var alternativeResult = (regularMod - (Abs(y) * Sign(x)));
+
+            if (Abs(alternativeResult) == Abs(regularMod))
+            {
+                var divisionResult = x / y;
+                var roundedResult = Round(divisionResult);
+
+                if (Abs(roundedResult) > Abs(divisionResult))
+                {
+                    return alternativeResult;
+                }
+                else
+                {
+                    return regularMod;
+                }
+            }
+
+            if (Math.Abs(alternativeResult) < Math.Abs(regularMod))
+            {
+                return alternativeResult;
+            }
+            else
+            {
+                return regularMod;
+            }
+        }
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Log(float x);
+
+        public static float Log(float x, float y)
+        {
+            if (float.IsNaN(x))
+            {
+                return x; // IEEE 754-2008: NaN payload must be preserved
+            }
+
+            if (float.IsNaN(y))
+            {
+                return y; // IEEE 754-2008: NaN payload must be preserved
+            }
+
+            if (y == 1)
+            {
+                return float.NaN;
+            }
+
+            if ((x != 1) && ((y == 0) || float.IsPositiveInfinity(y)))
+            {
+                return float.NaN;
+            }
+
+            return Log(x) / Log(y);
+        }
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Log10(float x);
+
+        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+        public static float Max(float x, float y) => ((x > y) || float.IsNaN(x)) ? x : y;
+
+        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+        public static float Min(float x, float y) => ((x < y) || float.IsNaN(x)) ? x : y;
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Pow(float x, float y);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Round(float x);
+
+        public static float Round(float x, int digits)
+        {
+            if ((digits < 0) || (digits > maxRoundingDigits))
+            {
+               throw new ArgumentOutOfRangeException(nameof(digits), Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
+            }
+            Contract.EndContractBlock();
+
+            return InternalRound(x, digits, MidpointRounding.ToEven);
+        }
+
+        public static float Round(float x, int digits, MidpointRounding mode)
+        {
+            if ((digits < 0) || (digits > maxRoundingDigits))
+            {
+                throw new ArgumentOutOfRangeException(nameof(digits), Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
+            }
+            
+            if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero)
+            {
+                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumx", mode, nameof(MidpointRounding)), nameof(mode));
+            }
+            Contract.EndContractBlock();
+
+            return InternalRound(x, digits, mode);
+        }
+
+        public static float Round(float x, MidpointRounding mode)
+        {
+            if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero)
+            {
+                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumx", mode, nameof(MidpointRounding)), nameof(mode));
+            }
+            Contract.EndContractBlock();
+            
+            return InternalRound(x, 0, mode);
+        }
+
+        public static int Sign(float x)
+        {
+            if (x < 0)
+            {
+                return -1;
+            }
+            else if (x > 0)
+            {
+                return 1;
+            }
+            else if (x == 0)
+            {
+                return 0;
+            }
+
+            throw new ArithmeticException(Environment.GetResourceString("Arithmetic_NaN"));
+        }
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Sin(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Sinh(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Sqrt(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Tan(float x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        public static extern float Tanh(float x);
+
+        public static float Truncate(float x) => InternalTruncate(x);
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        private static unsafe float InternalRound(float x, int digits, MidpointRounding mode)
+        {
+            if (Abs(x) < singleRoundLimit)
+            {
+                var power10 = roundPower10Single[digits];
+                
+                x *= power10;
+                
+                if (mode == MidpointRounding.AwayFromZero)
+                {
+                    var fraction = SplitFractionSingle(&x);
+                    
+                    if (Abs(fraction) >= 0.5f)
+                    {
+                        x += Sign(fraction);
+                    }
+                }
+                else
+                {
+                    x = Round(x);
+                }
+
+                x /= power10;
+            }
+
+            return x;
+        }
+
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        private unsafe static float InternalTruncate(float x)
+        {
+            SplitFractionSingle(&x);
+            return x;
+        }
+
+        [System.Security.SecurityCritical]  // auto-generated
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        private static unsafe extern float SplitFractionSingle(float* x);
+    }
+}
index 6a77f08..a2d3b13 100644 (file)
@@ -37,6 +37,8 @@ namespace System {
         public const float NegativeInfinity = (float)-1.0 / (float)0.0;
         public const float NaN = (float)0.0 / (float)0.0;
 
+        internal static float NegativeZero = BitConverter.Int32BitsToSingle(unchecked((int)0x80000000));
+        
         [Pure]
         [System.Security.SecuritySafeCritical]  // auto-generated
         [System.Runtime.Versioning.NonVersionable]
@@ -65,6 +67,12 @@ namespace System {
         public unsafe static bool IsNaN(float f) {
             return (*(int*)(&f) & 0x7FFFFFFF) > 0x7F800000;
         }
+        
+        [Pure]
+        [System.Security.SecuritySafeCritical]  // auto-generated
+        internal unsafe static bool IsNegative(float f) {
+            return (*(uint*)(&f) & 0x80000000) == 0x80000000;
+        }
 
         // Compares this object to another object, returning an integer that
         // indicates the relationship.
index 792e24e..e698a26 100644 (file)
@@ -5791,6 +5791,13 @@ CoCreateGuid(OUT GUID * pguid);
 #define log           PAL_log
 #define log10         PAL_log10
 #define pow           PAL_pow
+#define acosf         PAL_acosf
+#define asinf         PAL_asinf
+#define atan2f        PAL_atan2f
+#define expf          PAL_expf
+#define logf          PAL_logf
+#define log10f        PAL_log10f
+#define powf          PAL_powf
 #define malloc        PAL_malloc
 #define free          PAL_free
 #define mkstemp       PAL_mkstemp
@@ -6040,9 +6047,29 @@ PALIMPORT double __cdecl sqrt(double);
 PALIMPORT double __cdecl tan(double);
 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 asinf(float);
+PALIMPORT float __cdecl atanf(float);
+PALIMPORT float __cdecl atan2f(float, float);
+PALIMPORT float __cdecl ceilf(float);
+PALIMPORT float __cdecl cosf(float);
+PALIMPORT float __cdecl coshf(float);
+PALIMPORT float __cdecl expf(float);
 PALIMPORT float __cdecl fabsf(float);
+PALIMPORT float __cdecl floorf(float);
 PALIMPORT float __cdecl fmodf(float, float); 
+PALIMPORT float __cdecl logf(float);
+PALIMPORT float __cdecl log10f(float);
 PALIMPORT float __cdecl modff(float, float*);
+PALIMPORT float __cdecl powf(float, float);
+PALIMPORT float __cdecl sinf(float);
+PALIMPORT float __cdecl sinhf(float);
+PALIMPORT float __cdecl sqrtf(float);
+PALIMPORT float __cdecl tanf(float);
+PALIMPORT float __cdecl tanhf(float);
 
 #ifndef PAL_STDCPP_COMPAT
 
index 7075fd6..08f4192 100644 (file)
@@ -35,6 +35,12 @@ Abstract:
 
 #define IS_DBL_NEGZERO(x)         (((*((INT64*)((void*)&x))) & I64(0xFFFFFFFFFFFFFFFF)) == I64(0x8000000000000000))
 
+#define PAL_NAN_FLT     sqrtf(-1.0f)
+#define PAL_POSINF_FLT -logf(0.0f)
+#define PAL_NEGINF_FLT  logf(0.0f)
+
+#define IS_FLT_NEGZERO(x)         (((*((INT32*)((void*)&x))) & 0xFFFFFFFF) == 0x80000000)
+
 SET_DEFAULT_DEBUG_CHANNEL(CRT);
 
 /*++
@@ -422,3 +428,364 @@ PALIMPORT double __cdecl PAL_pow(double x, double y)
     PERF_EXIT(pow);
     return ret;
 }
+
+/*++
+Function:
+  _finitef
+
+Determines whether given single-precision floating point value is finite.
+
+Return Value
+
+_finitef returns a nonzero value (TRUE) if its argument x is not
+infinite, that is, if -INF < x < +INF. It returns 0 (FALSE) if the
+argument is infinite or a NaN.
+
+Parameter
+
+x  Single-precision floating-point value
+
+--*/
+int __cdecl _finitef(float x)
+{
+    int ret;
+    PERF_ENTRY(_finitef);
+    ENTRY("_finitef (x=%f)\n", x);
+
+#if defined(_IA64_) && defined (_HPUX_)
+    ret = !isnan(x) && (x != PAL_POSINF_FLT) && (x != PAL_NEGINF_FLT);
+#else
+    ret = isfinite(x);
+#endif
+
+    LOGEXIT("_finitef returns int %d\n", ret);
+    PERF_EXIT(_finitef);
+    return ret;
+}
+
+/*++
+Function:
+  _isnanf
+
+See MSDN doc
+--*/
+int __cdecl _isnanf(float x)
+{
+    int ret;
+    PERF_ENTRY(_isnanf);
+    ENTRY("_isnanf (x=%f)\n", x);
+
+    ret = isnan(x);
+
+    LOGEXIT("_isnanf returns int %d\n", ret);
+    PERF_EXIT(_isnanf);
+    return ret;
+}
+
+/*++
+Function:
+  _copysignf
+
+See MSDN doc
+--*/
+float __cdecl _copysignf(float x, float y)
+{
+    float ret;
+    PERF_ENTRY(_copysignf);
+    ENTRY("_copysignf (x=%f, y=%f)\n", x, y);
+
+    ret = copysign(x, y);
+
+    LOGEXIT("_copysignf returns float %f\n", ret);
+    PERF_EXIT(_copysignf);
+    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:
+    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
+
+See MSDN.
+--*/
+PALIMPORT float __cdecl PAL_log10f(float x)
+{
+    float ret;
+    PERF_ENTRY(log10f);
+    ENTRY("log10f (x=%f)\n", x);
+
+#if !HAVE_COMPATIBLE_LOG10
+    errno = 0;
+#endif  // !HAVE_COMPATIBLE_LOG10
+
+    ret = log10f(x);
+    
+#if !HAVE_COMPATIBLE_LOG10
+    if ((errno == EDOM) && (x < 0))
+    {
+        ret = PAL_NAN_FLT;    // NaN
+    }
+#endif  // !HAVE_COMPATIBLE_LOG10
+
+    LOGEXIT("log10f returns float %f\n", ret);
+    PERF_EXIT(log10f);
+    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 = PAL_NAN_FLT;    // NaN
+        }
+        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 = PAL_NAN_FLT;    // NaN
+        }
+        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
+
+    if ((y == 0.0f) && isnan(x))
+    {
+        // Windows returns NaN for powf(NaN, 0), but POSIX specifies
+        // a return value of 1 for that case.  We need to return
+        // the same result as Windows.
+        ret = PAL_NAN_FLT;
+    }
+    else
+    {
+        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;
+}
index 88d47bb..fa51ecc 100644 (file)
@@ -216,9 +216,18 @@ function_name() to call the system's implementation
 #define sqrt DUMMY_sqrt
 #define tan DUMMY_tan
 #define tanh DUMMY_tanh
+#define ceilf DUMMY_ceilf
+#define cosf DUMMY_cosf
+#define coshf DUMMY_coshf
 #define fabsf DUMMY_fabsf
+#define floorf DUMMY_floorf
 #define fmodf DUMMY_fmodf
 #define modff DUMMY_modff
+#define sinf DUMMY_sinf
+#define sinhf DUMMY_sinhf
+#define sqrtf DUMMY_sqrtf
+#define tanf DUMMY_tanf
+#define tanhf DUMMY_tanhf
 
 /* RAND_MAX needed to be renamed to avoid duplicate definition when including 
    stdlib.h header files. PAL_RAND_MAX should have the same value as RAND_MAX 
@@ -457,9 +466,26 @@ function_name() to call the system's implementation
 #undef sqrt
 #undef tan
 #undef tanh
+#undef acosf
+#undef asinf
+#undef atanf
+#undef atan2f
+#undef ceilf
+#undef cosf
+#undef coshf
+#undef expf
 #undef fabsf
+#undef floorf
 #undef fmodf
+#undef logf
+#undef log10f
 #undef modff
+#undef powf
+#undef sinf
+#undef sinhf
+#undef sqrtf
+#undef tanf
+#undef tanhf
 #undef rand
 #undef srand
 #undef errno
index 533454c..a3a1eb4 100644 (file)
@@ -2,16 +2,23 @@ cmake_minimum_required(VERSION 2.8.12.2)
 
 add_subdirectory(abs)
 add_subdirectory(acos)
+add_subdirectory(acosf)
 add_subdirectory(asin)
+add_subdirectory(asinf)
 add_subdirectory(atan)
 add_subdirectory(atan2)
+add_subdirectory(atan2f)
+add_subdirectory(atanf)
 add_subdirectory(atof)
 add_subdirectory(atoi)
 add_subdirectory(atol)
 add_subdirectory(bsearch)
 add_subdirectory(ceil)
+add_subdirectory(ceilf)
 add_subdirectory(cos)
+add_subdirectory(cosf)
 add_subdirectory(cosh)
+add_subdirectory(coshf)
 
 # TODO: make this test compile
 # add_subdirectory(ctime)
@@ -19,6 +26,7 @@ add_subdirectory(cosh)
 add_subdirectory(errno)
 add_subdirectory(exit)
 add_subdirectory(exp)
+add_subdirectory(expf)
 add_subdirectory(fabs)
 add_subdirectory(fabsf)
 add_subdirectory(fclose)
@@ -27,6 +35,7 @@ add_subdirectory(ferror)
 add_subdirectory(fflush)
 add_subdirectory(fgets)
 add_subdirectory(floor)
+add_subdirectory(floorf)
 add_subdirectory(fmod)
 add_subdirectory(fmodf)
 add_subdirectory(fopen)
@@ -57,6 +66,8 @@ add_subdirectory(llabs)
 add_subdirectory(localtime)
 add_subdirectory(log)
 add_subdirectory(log10)
+add_subdirectory(log10f)
+add_subdirectory(logf)
 add_subdirectory(malloc)
 add_subdirectory(memchr)
 add_subdirectory(memcmp)
@@ -66,14 +77,18 @@ add_subdirectory(memset)
 add_subdirectory(modf)
 add_subdirectory(modff)
 add_subdirectory(pow)
+add_subdirectory(powf)
 add_subdirectory(printf)
 add_subdirectory(qsort)
 add_subdirectory(rand_srand)
 add_subdirectory(realloc)
 add_subdirectory(sin)
+add_subdirectory(sinf)
 add_subdirectory(sinh)
+add_subdirectory(sinhf)
 add_subdirectory(sprintf)
 add_subdirectory(sqrt)
+add_subdirectory(sqrtf)
 add_subdirectory(sscanf)
 add_subdirectory(strcat)
 add_subdirectory(strchr)
@@ -94,7 +109,9 @@ add_subdirectory(strtoul)
 add_subdirectory(swprintf)
 add_subdirectory(swscanf)
 add_subdirectory(tan)
+add_subdirectory(tanf)
 add_subdirectory(tanh)
+add_subdirectory(tanhf)
 add_subdirectory(time)
 add_subdirectory(tolower)
 add_subdirectory(toupper)
@@ -125,6 +142,7 @@ add_subdirectory(_alloca)
 add_subdirectory(_ecvt)
 add_subdirectory(_fdopen)
 add_subdirectory(_finite)
+add_subdirectory(_finitef)
 add_subdirectory(_fullpath)
 
 # TODO: make this test compile
@@ -132,6 +150,7 @@ add_subdirectory(_fullpath)
 
 add_subdirectory(_getw)
 add_subdirectory(_isnan)
+add_subdirectory(_isnanf)
 add_subdirectory(_itow)
 add_subdirectory(_makepath)
 add_subdirectory(_mbsdec)
diff --git a/src/pal/tests/palsuite/c_runtime/_finitef/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_finitef/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/_finitef/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_finitef/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9ef630f
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_finitef_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_finitef_test1 coreclrpal)
+
+target_link_libraries(paltest_finitef_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_finitef/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_finitef/test1/test1.c
new file mode 100644 (file)
index 0000000..f9a1109
--- /dev/null
@@ -0,0 +1,119 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================================
+**
+** Source:  test1.c
+**
+** Purpose: Checks that _finitef correctly classifies all types
+**          of floating point numbers (NaN, -Infinity, Infinity,
+**          finite nonzero, unnormalized, 0, and -0)
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+/*
+The IEEE single precision floating point standard looks like this:
+
+  S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
+  0 1      8 9                    31
+
+S is the sign bit.  The E bits are the exponent, and the 23 F bits are
+the fraction.  These represent a value, V.
+
+If E=255 and F is nonzero, then V=NaN ("Not a number")
+If E=255 and F is zero and S is 1, then V=-Infinity
+If E=255 and F is zero and S is 0, then V=Infinity
+If 0<E<255 then V=(-1)^S * 2^(E-1028) * (1.F) where "1.F" is the binary
+   number created by prefixing F with a leading 1 and a binary point.
+If E=0 and F is nonzero, then V=(-1)^S * 2^(-127) * (0.F) These are
+   "unnormalized" values.
+If E=0 and F is zero and S is 1, then V=-0
+If E=0 and F is zero and S is 0, then V=0
+
+*/
+
+#define TO_FLOAT(x)    (*((float*)((void*)&x)))
+
+int __cdecl main(int argc, char **argv)
+{
+    /*non-finite numbers*/
+    UINT32 lsnan =              0xffffffffu;
+    UINT32 lqnan =              0x7fffffffu;
+    UINT32 lneginf =            0xff800000u;
+    UINT32 lposinf =            0x7f800000u;
+
+    float snan =               TO_FLOAT(lsnan);
+    float qnan =               TO_FLOAT(lqnan);
+    float neginf =             TO_FLOAT(lneginf);
+    float posinf =             TO_FLOAT(lposinf);
+
+    /*finite numbers*/
+    UINT32 lnegunnormalized =   0x807fffffu;
+    UINT32 lposunnormalized =   0x007fffffu;
+    UINT32 lnegzero =           0x80000000u;
+
+    float negunnormalized =    TO_FLOAT(lnegunnormalized);
+    float posunnormalized =    TO_FLOAT(lposunnormalized);
+    float negzero =            TO_FLOAT(lnegzero);
+
+    /*
+     * Initialize the PAL and return FAIL if this fails
+     */
+    if (PAL_Initialize(argc, argv) != 0)
+    {
+        return FAIL;
+    }
+
+    /*non-finite numbers*/
+    if (_finitef(snan) || _finitef(qnan))
+    {
+        Fail("_finitef() found NAN to be finite.\n");
+    }
+
+    if (_finitef(neginf))
+    {
+        Fail("_finitef() found negative infinity to be finite.\n");
+    }
+
+    if (_finitef(posinf))
+    {
+        Fail("_finitef() found infinity to be finite.\n");
+    }
+
+    /*finite numbers*/
+    if (!_finitef(negunnormalized))
+    {
+        Fail("_finitef() found a negative unnormalized value to be infinite.\n");
+    }
+
+    if (!_finitef(posunnormalized))
+    {
+        Fail("_finitef() found an unnormalized value to be infinite.\n");
+    }
+
+    if (!_finitef(negzero))
+    {
+        Fail("_finitef() found negative zero to be infinite.\n");
+    }
+
+    if (!_finitef(+0.0f))
+    {
+        Fail("_finitef() found zero to be infinite.\n");
+    }
+
+    if (!_finitef(-123.456f))
+    {
+        Fail("_finitef() found %f to be infinite.\n", -123.456f);
+    }
+
+    if (!_finitef(+123.456f))
+    {
+        Fail("_finitef() found %f to be infinite.\n", +123.456f);
+    }
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_finitef/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_finitef/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..b076743
--- /dev/null
@@ -0,0 +1,13 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = _finitef
+Name = Positive Test for _finitef
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Checks that _finitef correctly classifies all types of floating point
+= numbers (NaN, -Infinity, Infinity, finite nonzero, unnormalized, 0, and -0).
diff --git a/src/pal/tests/palsuite/c_runtime/_isnanf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_isnanf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/_isnanf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_isnanf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a8d42aa
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_isnanf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_isnanf_test1 coreclrpal)
+
+target_link_libraries(paltest_isnanf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_isnanf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_isnanf/test1/test1.c
new file mode 100644 (file)
index 0000000..9b75a72
--- /dev/null
@@ -0,0 +1,115 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================================
+**
+** Source:  test1.c
+**
+** Purpose: 
+** Test _isnanf with a number of trivial values, to ensure they indicated that
+** they are numbers.  Then try with Positive/Negative Infinite, which should
+** also be numbers.  Finally set the least and most significant bits of 
+** the fraction to positive and negative, at which point it should return
+** the true value. 
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+#define TO_FLOAT(x)    (*((float*)((void*)&x)))
+#define TO_I32(x)      (*((INT32*)((void*)&x)))
+
+/*
+ * NaN: any float with maximum exponent (0x7f8) and non-zero fraction
+ */
+int __cdecl main(int argc, char *argv[])
+{
+    /*
+     * Initialize the PAL and return FAIL if this fails
+     */
+    if (PAL_Initialize(argc, argv) != 0)
+    {
+        return FAIL;
+    }
+
+    /*
+     * Try some trivial values
+     */
+    if (_isnanf(0.0f))
+    {
+        Fail("_isnanf() incorrectly identified %f as NaN!\n", 0.0f);
+    }
+
+    if (_isnanf(1.234567f))
+    {
+        Fail("_isnanf() incorrectly identified %f as NaN!\n", 1.234567f);
+    }
+
+    if (_isnanf(42.0f))
+    {
+        Fail("_isnanf() incorrectly identified %f as NaN!\n", 42.0f);
+    }
+
+    UINT32 lneginf =           0xff800000u;
+    UINT32 lposinf =           0x7f800000u;
+    
+    float neginf =             TO_FLOAT(lneginf);
+    float posinf =             TO_FLOAT(lposinf);
+
+    /*
+     * Try positive and negative infinity
+     */
+    if (_isnanf(neginf))
+    {
+        Fail("_isnanf() incorrectly identified negative infinity as NaN!\n");
+    }
+
+    if (_isnanf(posinf))
+    {
+        Fail("_isnanf() incorrectly identified infinity as NaN!\n");
+    }
+
+    /*
+     * Try setting the least significant bit of the fraction,
+     * positive and negative
+     */
+    UINT32 lsnan =             0xff800001u;
+    float snan =               TO_FLOAT(lsnan);
+    
+    if (!_isnanf(snan))
+    {
+        Fail("_isnanf() failed to identify %I32x as NaN!\n", lsnan);
+    }
+
+    UINT32 lqnan =             0x7f800001u;
+    float qnan =               TO_FLOAT(lqnan);
+    
+    if (!_isnanf(qnan))
+    {
+        Fail("_isnanf() failed to identify %I32x as NaN!\n", lqnan);
+    }
+
+    /*
+     * Try setting the most significant bit of the fraction,
+     * positive and negative
+     */
+    lsnan =                     0xffc00000u;
+    snan =                      TO_FLOAT(lsnan);
+
+    if (!_isnanf(snan))
+    {
+        Fail ("_isnanf() failed to identify %I32x as NaN!\n", lsnan);
+    }
+
+    lqnan =                     0x7fc00000u;
+    qnan =                      TO_FLOAT(lqnan);
+
+    if (!_isnanf(qnan))
+    {
+        Fail ("_isnanf() failed to identify %I32x as NaN!\n", lqnan);
+    }
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_isnanf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_isnanf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..22b0edb
--- /dev/null
@@ -0,0 +1,16 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = _isnanf
+Name = Test #1 for _isnanf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Test _isnanf with a number of trivial values, to ensure they indicated that
+= they are numbers.  Then try with Positive/Negative Infinite, which should
+= also be numbers.  Finally set the least and most significant bits of 
+= the fraction to positive and negative, at which point it should return
+= the true value.
diff --git a/src/pal/tests/palsuite/c_runtime/acosf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/acosf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/acosf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/acosf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2643647
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_acosf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_acosf_test1 coreclrpal)
+
+target_link_libraries(paltest_acosf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/acosf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/acosf/test1/test1.c
new file mode 100644 (file)
index 0000000..3d8668c
--- /dev/null
@@ -0,0 +1,129 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that acosf return the correct values
+** 
+** Dependencies: PAL_Initialize
+**               PAL_Terminate
+**               Fail
+**               fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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++)
+    {
+        validate(tests[i].value, tests[i].expected, tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NEGINF);
+    validate_isnan(PAL_NAN);
+    validate_isnan(PAL_POSINF);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/acosf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/acosf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..41cead3
--- /dev/null
@@ -0,0 +1,14 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = acosf
+Name = Positive Test for acosf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes a series of values to the acosf() function,
+= checking each for the expfected result. Also checks
+= for proper handling of out-of-range values.
diff --git a/src/pal/tests/palsuite/c_runtime/asinf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/asinf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/asinf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/asinf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b167bd8
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_asinf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_asinf_test1 coreclrpal)
+
+target_link_libraries(paltest_asinf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/asinf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/asinf/test1/test1.c
new file mode 100644 (file)
index 0000000..773015e
--- /dev/null
@@ -0,0 +1,145 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that asinf return the correct values
+** 
+** Dependencies: PAL_Initialize
+**               PAL_Terminate
+**               Fail
+**               fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning +INF
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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++)
+    {
+        validate( tests[i].value,  tests[i].expected, tests[i].variance);
+        validate(-tests[i].value, -tests[i].expected, tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NEGINF);
+    validate_isnan(PAL_NAN);
+    validate_isnan(PAL_POSINF);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/asinf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/asinf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..ca2dd42
--- /dev/null
@@ -0,0 +1,14 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = asinf
+Name = Positive Test for asinf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes a series of values to the asinf() function,
+= checking each for the expected result. Also checks
+= for proper handling of out-of-range values.
diff --git a/src/pal/tests/palsuite/c_runtime/atan2f/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atan2f/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/atan2f/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atan2f/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d71a61b
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_atan2f_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_atan2f_test1 coreclrpal)
+
+target_link_libraries(paltest_atan2f_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/atan2f/test1/test1.c b/src/pal/tests/palsuite/c_runtime/atan2f/test1/test1.c
new file mode 100644 (file)
index 0000000..2ee641e
--- /dev/null
@@ -0,0 +1,147 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** 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 <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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;
+        
+        validate( tests[i].y,  tests[i].x,  tests[i].expected,      tests[i].variance);
+        validate(-tests[i].y,  tests[i].x, -tests[i].expected,      tests[i].variance);
+        validate( tests[i].y, -tests[i].x,  pi - tests[i].expected, tests[i].variance);
+        validate(-tests[i].y, -tests[i].x,  tests[i].expected - pi, tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NEGINF, PAL_NAN);
+    validate_isnan(PAL_NAN,    PAL_NEGINF);
+    validate_isnan(PAL_NAN,    PAL_POSINF);
+    validate_isnan(PAL_POSINF, PAL_NAN);
+    
+    validate_isnan(PAL_NAN, -1);
+    validate_isnan(PAL_NAN, -0.0f);
+    validate_isnan(PAL_NAN,  0);
+    validate_isnan(PAL_NAN,  1);
+    
+    validate_isnan(-1,   PAL_NAN);
+    validate_isnan(-0.0f, PAL_NAN);
+    validate_isnan( 0,   PAL_NAN);
+    validate_isnan( 1,   PAL_NAN);
+    
+    validate_isnan(PAL_NAN, PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/atan2f/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/atan2f/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..bd9a9d9
--- /dev/null
@@ -0,0 +1,14 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = atan2f
+Name = Test #1 for atan2f
+Type = DEFAULT
+EXE1 = test1
+Description
+=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.
diff --git a/src/pal/tests/palsuite/c_runtime/atanf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atanf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/atanf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atanf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b71b1cf
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_atanf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_atanf_test1 coreclrpal)
+
+target_link_libraries(paltest_atanf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/atanf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/atanf/test1/test1.c
new file mode 100644 (file)
index 0000000..543a0a8
--- /dev/null
@@ -0,0 +1,127 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that atanf return the correct values
+** 
+** Dependencies: PAL_Initialize
+**               PAL_Terminate
+**               Fail
+**               fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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++)
+    {
+        validate( tests[i].value,  tests[i].expected, tests[i].variance);
+        validate(-tests[i].value, -tests[i].expected, tests[i].variance);
+    }
+
+    validate_isnan(PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/atanf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/atanf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..0d18427
--- /dev/null
@@ -0,0 +1,13 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = atanf
+Name = Positive Test for atanf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes a series of values to the atanf() function,
+= checking each for the expected result.
diff --git a/src/pal/tests/palsuite/c_runtime/ceilf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ceilf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/ceilf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ceilf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..64f14cd
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_ceilf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_ceilf_test1 coreclrpal)
+
+target_link_libraries(paltest_ceilf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/ceilf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/ceilf/test1/test1.c
new file mode 100644 (file)
index 0000000..4939fb7
--- /dev/null
@@ -0,0 +1,131 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================================
+**
+** 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 <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char *argv[])
+{
+    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;
+    }
+    
+    validate( 0,    0, PAL_EPSILON);
+    validate(-0.0f,  0, PAL_EPSILON);
+    
+    validate( 1,    1, PAL_EPSILON * 10);
+    validate(-1.0f, -1, PAL_EPSILON * 10);
+    
+    for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+    {
+        validate( tests[i].value, tests[i].expected,     tests[i].variance);
+        validate(-tests[i].value, 1 - tests[i].expected, tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/ceilf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/ceilf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..095b8b2
--- /dev/null
@@ -0,0 +1,14 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = ceilf
+Name = Test #1 for ceilf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+=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
diff --git a/src/pal/tests/palsuite/c_runtime/cosf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/cosf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/cosf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/cosf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b3a18ea
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_cosf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_cosf_test1 coreclrpal)
+
+target_link_libraries(paltest_cosf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/cosf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/cosf/test1/test1.c
new file mode 100644 (file)
index 0000000..210851a
--- /dev/null
@@ -0,0 +1,130 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that cosf return the correct values
+** 
+** Dependencies: PAL_Initialize
+**               PAL_Terminate
+**               Fail
+**               fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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++)
+    {
+        validate( tests[i].value, tests[i].expected, tests[i].variance);
+        validate(-tests[i].value, tests[i].expected, tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NEGINF);
+    validate_isnan(PAL_NAN);
+    validate_isnan(PAL_POSINF);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/cosf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/cosf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..a0265ad
--- /dev/null
@@ -0,0 +1,13 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = cosf
+Name = Positive Test for cosf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to cosf() a series of angle value, checking that
+= each one return the correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/coshf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/coshf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/coshf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/coshf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..92fcfde
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_coshf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_coshf_test1 coreclrpal)
+
+target_link_libraries(paltest_coshf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/coshf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/coshf/test1/test1.c
new file mode 100644 (file)
index 0000000..e1ab745
--- /dev/null
@@ -0,0 +1,129 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that coshf return the correct values
+** 
+** Dependencies: PAL_Initialize
+**               PAL_Terminate
+**               Fail
+**               fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning PAL_NAN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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++)
+    {
+        validate( tests[i].value, tests[i].expected, tests[i].variance);
+        validate(-tests[i].value, tests[i].expected, tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/coshf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/coshf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..814ed98
--- /dev/null
@@ -0,0 +1,13 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = coshf
+Name = Positive Test for coshf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to coshf() a series of angle value, checking that
+= each one return to correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/expf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/expf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/expf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/expf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fb12b65
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_expf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_expf_test1 coreclrpal)
+
+target_link_libraries(paltest_expf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/expf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/expf/test1/test1.c
new file mode 100644 (file)
index 0000000..32f4e8d
--- /dev/null
@@ -0,0 +1,137 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source:  test1.c
+**
+** Purpose: Tests expf with a normal set of values.
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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++)
+    {
+        validate(tests[i].value, tests[i].expected, tests[i].variance);
+    }
+
+    validate_isnan(PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/expf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/expf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..c359285
--- /dev/null
@@ -0,0 +1,12 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = expf
+Name = Test #1 for expf
+Type = DEFAULT
+EXE1 = test1
+Description
+=Tests expf with a normal set of values.
diff --git a/src/pal/tests/palsuite/c_runtime/floorf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/floorf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/floorf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/floorf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f6e24ad
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_floorf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_floorf_test1 coreclrpal)
+
+target_link_libraries(paltest_floorf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/floorf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/floorf/test1/test1.c
new file mode 100644 (file)
index 0000000..57dca21
--- /dev/null
@@ -0,0 +1,131 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================================
+**
+** 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 <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char *argv[])
+{
+    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;
+    }
+    
+    validate( 0,    0, PAL_EPSILON);
+    validate(-0.0f, 0, PAL_EPSILON);
+    
+    validate( 1,     1, PAL_EPSILON * 10);
+    validate(-1.0f, -1, PAL_EPSILON * 10);
+
+    for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+    {
+        validate( tests[i].value,  tests[i].expected,       tests[i].variance);
+        validate(-tests[i].value, -(tests[i].expected + 1), tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/floorf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/floorf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..0065401
--- /dev/null
@@ -0,0 +1,13 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = floorf
+Name = Positive Test for floorf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to floorf() a series of value, checking that
+= each one return to correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/log10f/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/log10f/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/log10f/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/log10f/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b2c0835
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_log10f_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_log10f_test1 coreclrpal)
+
+target_link_libraries(paltest_log10f_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/log10f/test1/test1.c b/src/pal/tests/palsuite/c_runtime/log10f/test1/test1.c
new file mode 100644 (file)
index 0000000..e7c8c2f
--- /dev/null
@@ -0,0 +1,144 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that log10f returns correct values.
+** 
+** Dependencies: PAL_Initialize
+**               PAL_Terminate
+**               Fail
+**               fabs
+**               _isnanf
+** 
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+    float result = log10f(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("log10f(%g) returned %10.9g when it should have returned %10.9g",
+             value, result, expected);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+    float result = log10f(value);
+
+    if (!_isnanf(result))
+    {
+        Fail("log10f(%g) returned %10.9g when it should have returned %10.9g",
+             value, result, PAL_NAN);
+    }
+}
+
+/**
+ * main
+ * 
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+    struct test tests[] = 
+    {
+        /* value                expected        variance */
+        {  0,                   PAL_NEGINF,     0 },
+        {  0.000721784159f,    -3.14159265f,    PAL_EPSILON * 10 },   // expected: -(pi)
+        {  0.00191301410f,     -2.71828183f,    PAL_EPSILON * 10 },   // expected: -(e)
+        {  0.00498212830f,     -2.30258509f,    PAL_EPSILON * 10 },   // expected: -(ln(10))
+        {  0.0268660410f,      -1.57079633f,    PAL_EPSILON * 10 },   // expected: -(pi / 2)
+        {  0.0360831928f,      -1.44269504f,    PAL_EPSILON * 10 },   // expected: -(logf2(e))
+        {  0.0385288847f,      -1.41421356f,    PAL_EPSILON * 10 },   // expected: -(sqrtf(2))
+        {  0.0744082059f,      -1.12837917f,    PAL_EPSILON * 10 },   // expected: -(2 / sqrtf(pi))
+        {  0.1f,               -1,              PAL_EPSILON * 10 },   // expected: -(1)
+        {  0.163908636f,       -0.785398163f,   PAL_EPSILON },        // expected: -(pi / 4)
+        {  0.196287760f,       -0.707106781f,   PAL_EPSILON },        // expected: -(1 / sqrtf(2))
+        {  0.202699566f,       -0.693147181f,   PAL_EPSILON },        // expected: -(ln(2))
+        {  0.230876765f,       -0.636619772f,   PAL_EPSILON },        // expected: -(2 / pi)
+        {  0.367879441f,       -0.434294482f,   PAL_EPSILON },        // expected: -(log10f(e))
+        {  0.480496373f,       -0.318309886f,   PAL_EPSILON },        // expected: -(1 / pi)
+        {  1,                   0,              PAL_EPSILON },
+        {  2.08118116f,         0.318309886f,   PAL_EPSILON },        // expected:  1 / pi
+        {  2.71828183f,         0.434294482f,   PAL_EPSILON },        // expected:  log10f(e)           value: e
+        {  4.33131503f,         0.636619772f,   PAL_EPSILON },        // expected:  2 / pi
+        {  4.93340967f,         0.693147181f,   PAL_EPSILON },        // expected:  ln(2)
+        {  5.09456117f,         0.707106781f,   PAL_EPSILON },        // expected:  1 / sqrtf(2)
+        {  6.10095980f,         0.785398163f,   PAL_EPSILON },        // expected:  pi / 4
+        {  10,                  1,              PAL_EPSILON * 10 },
+        {  13.4393779f,         1.12837917f,    PAL_EPSILON * 10 },   // expected:  2 / sqrtf(pi)
+        {  25.9545535f,         1.41421356f,    PAL_EPSILON * 10 },   // expected:  sqrtf(2)
+        {  27.7137338f,         1.44269504f,    PAL_EPSILON * 10 },   // expected:  logf2(e)
+        {  37.2217105f,         1.57079633f,    PAL_EPSILON * 10 },   // expected:  pi / 2
+        {  200.717432f,         2.30258509f,    PAL_EPSILON * 10 },   // expected:  ln(10)
+        {  522.735300f,         2.71828183f,    PAL_EPSILON * 10 },   // expected:  e
+        {  1385.45573f,         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++)
+    {
+        validate(tests[i].value, tests[i].expected, tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NEGINF);
+    validate_isnan(PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/log10f/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/log10f/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..175ee3a
--- /dev/null
@@ -0,0 +1,17 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = log10f
+Name = Positive Test for log10f
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes a series of values to the log10f() function,
+= checking each for the expected result. Also checks
+= for proper handling of out-of-range values.
+
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/logf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/logf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/logf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/logf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..550f572
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_logf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_logf_test1 coreclrpal)
+
+target_link_libraries(paltest_logf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/logf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/logf/test1/test1.c
new file mode 100644 (file)
index 0000000..499778e
--- /dev/null
@@ -0,0 +1,139 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source:  test1.c
+**
+** Purpose: Tests logf with a normal set of values.
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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++)
+    {
+        validate(tests[i].value, tests[i].expected, tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NEGINF);
+    validate_isnan(PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/logf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/logf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..aadfee6
--- /dev/null
@@ -0,0 +1,14 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = logf
+Name = Positive Test for logf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes a series of values to the logf() function,
+= checking each for the expected result. Also checks
+= for proper handling of out-of-range values.
diff --git a/src/pal/tests/palsuite/c_runtime/powf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/powf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/powf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/powf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8ea040f
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_powf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_powf_test1 coreclrpal)
+
+target_link_libraries(paltest_powf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/powf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/powf/test1/test1.c
new file mode 100644 (file)
index 0000000..ca738e8
--- /dev/null
@@ -0,0 +1,229 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** 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 <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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)
+        
+        { -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 },
+
+        {  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++)
+    {
+        validate(tests[i].x, tests[i].y, tests[i].expected, tests[i].variance);
+    }
+
+    validate_isnan(-10, -1.57079633f);                                                   //          y: -(pi / 2)
+    validate_isnan(-10, -0.785398163f);                                                  //          y: -(pi / 4)
+    validate_isnan(-10,  0.785398163f);                                                  //          y:   pi / 4
+    validate_isnan(-10,  1.57079633f);                                                   //          y:   pi / 2
+    
+    validate_isnan(-2.71828183f, -1.57079633f);                                          // x: -(e)  y: -(pi / 2)
+    validate_isnan(-2.71828183f, -0.785398163f);                                         // x: -(e)  y: -(pi / 4)
+    validate_isnan(-2.71828183f,  0.785398163f);                                         // x: -(e)  y:   pi / 4
+    validate_isnan(-2.71828183f,  1.57079633f);                                          // x: -(e)  y:   pi / 2
+
+    validate_isnan(-1, PAL_NEGINF);
+    validate_isnan(-1, PAL_POSINF);
+
+    validate_isnan(PAL_NAN, -0.0);
+    validate_isnan(PAL_NAN,  0);
+
+    validate_isnan(PAL_NEGINF, PAL_NAN);
+    validate_isnan(PAL_NAN,    PAL_NEGINF);
+    
+    validate_isnan(PAL_POSINF, PAL_NAN);
+    validate_isnan(PAL_NAN,    PAL_POSINF);
+    
+    validate_isnan(PAL_NAN, PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/powf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/powf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..778c042
--- /dev/null
@@ -0,0 +1,17 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = powf
+Name = Call powf with some std input/output.
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Call the powf function with various num/expfonent pairs
+= that should produce std answers.
+
+
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/sinf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sinf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/sinf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sinf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0651b43
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_sinf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_sinf_test1 coreclrpal)
+
+target_link_libraries(paltest_sinf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sinf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/sinf/test1/test1.c
new file mode 100644 (file)
index 0000000..d5bd248
--- /dev/null
@@ -0,0 +1,130 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that sinf return the correct values
+** 
+** Dependencies: PAL_Initialize
+**               PAL_Terminate
+**               Fail
+**               fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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++)
+    {
+        validate( tests[i].value,  tests[i].expected, tests[i].variance);
+        validate(-tests[i].value, -tests[i].expected, tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NEGINF);
+    validate_isnan(PAL_NAN);
+    validate_isnan(PAL_POSINF);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sinf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sinf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..08ff602
--- /dev/null
@@ -0,0 +1,13 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = sinf
+Name = Positive Test for sinf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to sinf() a series of angle value, checking that
+= each one return to correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/sinhf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sinhf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/sinhf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sinhf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..72cce43
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_sinhf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_sinhf_test1 coreclrpal)
+
+target_link_libraries(paltest_sinhf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sinhf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/sinhf/test1/test1.c
new file mode 100644 (file)
index 0000000..4e706a2
--- /dev/null
@@ -0,0 +1,129 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that sinhf return the correct values
+** 
+** Dependencies: PAL_Initialize
+**               PAL_Terminate
+**               Fail
+**               fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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++)
+    {
+        validate( tests[i].value,  tests[i].expected, tests[i].variance);
+        validate(-tests[i].value, -tests[i].expected, tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sinhf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sinhf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..cfb27f5
--- /dev/null
@@ -0,0 +1,13 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = sinhf
+Name = Positive Test for sinhf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to sinhf() a series of angle value, checking that
+= each one return to correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/sqrtf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sqrtf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f6aa0cb
--- /dev/null
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/c_runtime/sqrtf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sqrtf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..96b6ffa
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_sqrtf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_sqrtf_test1 coreclrpal)
+
+target_link_libraries(paltest_sqrtf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sqrtf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/sqrtf/test1/test1.c
new file mode 100644 (file)
index 0000000..cb1ac9e
--- /dev/null
@@ -0,0 +1,122 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source:  test1.c
+**
+** Purpose:  Call the sqrtf function on a positive value, a positive value
+** with a decimal and on the maxium possible float value.  
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+    float result = sqrtf(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("sqrtf(%g) returned %10.9g when it should have returned %10.9g",
+             value, result, expected);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+    float result = sqrtf(value);
+
+    if (!_isnanf(result))
+    {
+        Fail("sqrtf(%g) returned %10.9g when it should have returned %10.9g",
+             value, result, PAL_NAN);
+    }
+}
+
+int __cdecl main(int argc, char **argv)
+{
+    struct test tests[] = 
+    {
+        /* value            expected         variance */
+        {  0.318309886f,    0.564189584f,    PAL_EPSILON },       // value:  1 / pi
+        {  0.434294482f,    0.659010229f,    PAL_EPSILON },       // value:  log10f(e)
+        {  0.636619772f,    0.797884561f,    PAL_EPSILON },       // value:  2 / pi
+        {  0.693147181f,    0.832554611f,    PAL_EPSILON },       // value:  ln(2)
+        {  0.707106781f,    0.840896415f,    PAL_EPSILON },       // value:  1 / sqrtf(2)
+        {  0.785398163f,    0.886226925f,    PAL_EPSILON },       // value:  pi / 4
+        {  1,               1,               PAL_EPSILON * 10 },
+        {  1.12837917f,     1.06225193f,     PAL_EPSILON * 10 },  // value:  2 / sqrtf(pi)
+        {  1.41421356f,     1.18920712f,     PAL_EPSILON * 10 },  // value:  sqrtf(2)
+        {  1.44269504f,     1.20112241f,     PAL_EPSILON * 10 },  // value:  logf2(e)
+        {  1.57079633f,     1.25331414f,     PAL_EPSILON * 10 },  // value:  pi / 2
+        {  2.30258509f,     1.51742713f,     PAL_EPSILON * 10 },  // value:  ln(10)
+        {  2.71828183f,     1.64872127f,     PAL_EPSILON * 10 },  // value:  e
+        {  3.14159265f,     1.77245385F,     PAL_EPSILON * 10 },  // value:  pi
+    };
+
+    /* PAL initialization */
+    if (PAL_Initialize(argc, argv) != 0)
+    {
+        return FAIL;
+    }
+    
+    validate(-0.0f, -0.0f, PAL_EPSILON);
+    validate( 0.0f,  0.0f, PAL_EPSILON);
+
+    for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+    {
+        validate(tests[i].value, tests[i].expected, tests[i].variance);
+        validate_isnan(-tests[i].value);
+    }
+    
+    validate_isnan(PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sqrtf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sqrtf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..00d8ab2
--- /dev/null
@@ -0,0 +1,17 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = sqrtf
+Name = Call sqrtf on positive values and zero.
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Call the sqrtf function on a positive value, a positive value
+= with a decimal and on the maxium possible float value. 
+
+
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/tanf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/tanf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/tanf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/tanf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cd588ea
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_tanf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_tanf_test1 coreclrpal)
+
+target_link_libraries(paltest_tanf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/tanf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/tanf/test1/test1.c
new file mode 100644 (file)
index 0000000..18d5c4e
--- /dev/null
@@ -0,0 +1,136 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that tanf return the correct values
+** 
+** Dependencies: PAL_Initialize
+**               PAL_Terminate
+**               Fail
+**               fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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++)
+    {
+        validate( tests[i].value,  tests[i].expected, tests[i].variance);
+        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.
+    validate( 1.57079633f, -22877332.0, PAL_EPSILON * 100000000);
+    validate(-1.57079633f,  22877332.0, PAL_EPSILON * 100000000);
+    
+    validate_isnan(PAL_NEGINF);
+    validate_isnan(PAL_NAN);
+    validate_isnan(PAL_POSINF);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/tanf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/tanf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..aa33232
--- /dev/null
@@ -0,0 +1,13 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = tanf
+Name = Positive Test for tanf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to tanf() a series of angle value, checking that
+= each one return to correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/tanhf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/tanhf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e1ef7f
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/tanhf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/tanhf/test1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fd0af2a
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+  test1.c
+)
+
+add_executable(paltest_tanhf_test1
+  ${SOURCES}
+)
+
+add_dependencies(paltest_tanhf_test1 coreclrpal)
+
+target_link_libraries(paltest_tanhf_test1
+  pthread
+  m
+  coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/tanhf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/tanhf/test1/test1.c
new file mode 100644 (file)
index 0000000..904729a
--- /dev/null
@@ -0,0 +1,129 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that tanhf return the correct values
+** 
+** Dependencies: PAL_Initialize
+**               PAL_Terminate
+**               Fail
+**               fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// 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 */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl 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);
+    }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl 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
+ */
+int __cdecl main(int argc, char **argv)
+{
+    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++)
+    {
+        validate( tests[i].value,  tests[i].expected, tests[i].variance);
+        validate(-tests[i].value, -tests[i].expected, tests[i].variance);
+    }
+    
+    validate_isnan(PAL_NAN);
+
+    PAL_Terminate();
+    return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/tanhf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/tanhf/test1/testinfo.dat
new file mode 100644 (file)
index 0000000..6c7594f
--- /dev/null
@@ -0,0 +1,13 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = C Runtime
+Function = tanhf
+Name = Positive Test for tanhf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to tanhf() a series of angle value, checking that
+= each one return to correct value.
index d0a76e9..24d2d91 100644 (file)
@@ -1,20 +1,28 @@
 c_runtime/abs/test1/paltest_abs_test1
 c_runtime/acos/test1/paltest_acos_test1
+c_runtime/acosf/test1/paltest_acosf_test1
 c_runtime/asin/test1/paltest_asin_test1
+c_runtime/asinf/test1/paltest_asinf_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/atof/test1/paltest_atof_test1
 c_runtime/atoi/test1/paltest_atoi_test1
 c_runtime/atol/test1/paltest_atol_test1
 c_runtime/bsearch/test1/paltest_bsearch_test1
 c_runtime/bsearch/test2/paltest_bsearch_test2
 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
@@ -24,6 +32,7 @@ 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/fmod/test1/paltest_fmod_test1
 c_runtime/fmodf/test1/paltest_fmodf_test1
 c_runtime/fopen/test1/paltest_fopen_test1
@@ -94,6 +103,8 @@ c_runtime/llabs/test1/paltest_llabs_test1
 c_runtime/localtime/test1/paltest_localtime_test1
 c_runtime/log/test1/paltest_log_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
@@ -104,6 +115,7 @@ 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
@@ -128,7 +140,9 @@ 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/sinf/test1/paltest_sinf_test1
 c_runtime/sinh/test1/paltest_sinh_test1
+c_runtime/sinhf/test1/paltest_sinhf_test1
 c_runtime/sprintf/test1/paltest_sprintf_test1
 c_runtime/sprintf/test10/paltest_sprintf_test10
 c_runtime/sprintf/test11/paltest_sprintf_test11
@@ -149,6 +163,7 @@ c_runtime/sprintf/test7/paltest_sprintf_test7
 c_runtime/sprintf/test8/paltest_sprintf_test8
 c_runtime/sprintf/test9/paltest_sprintf_test9
 c_runtime/sqrt/test1/paltest_sqrt_test1
+c_runtime/sqrtf/test1/paltest_sqrtf_test1
 c_runtime/sscanf/test1/paltest_sscanf_test1
 c_runtime/sscanf/test10/paltest_sscanf_test10
 c_runtime/sscanf/test11/paltest_sscanf_test11
@@ -218,7 +233,9 @@ 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
@@ -328,8 +345,10 @@ c_runtime/wprintf/test1/paltest_wprintf_test1
 c_runtime/_alloca/test1/paltest_alloca_test1
 c_runtime/_fdopen/test1/paltest_fdopen_test1
 c_runtime/_finite/test1/paltest_finite_test1
+c_runtime/_finitef/test1/paltest_finitef_test1
 c_runtime/_fullpath/test1/paltest_fullpath_test1
 c_runtime/_isnan/test1/paltest_isnan_test1
+c_runtime/_isnanf/test1/paltest_isnanf_test1
 c_runtime/_itow/test1/paltest_itow_test1
 c_runtime/_makepath/test1/paltest_makepath_test1
 c_runtime/_mbsdec/test1/paltest_mbsdec_test1
index 36b48d6..dc30b86 100644 (file)
@@ -7,11 +7,13 @@ c_runtime/_alloca/test1,1
 c_runtime/_ecvt/test1,1
 c_runtime/_fdopen/test1,1
 c_runtime/_finite/test1,1
+c_runtime/_finitef/test1,1
 c_runtime/_fullpath/test1,1
 c_runtime/_gcvt/test1,1
 c_runtime/_gcvt/test2,1
 c_runtime/_getw/test1,1
 c_runtime/_isnan/test1,1
+c_runtime/_isnanf/test1,1
 c_runtime/_itow/test1,1
 c_runtime/_makepath/test1,1
 c_runtime/_mbsdec/test1,1
@@ -123,22 +125,30 @@ c_runtime/_wsplitpath/test1,1
 c_runtime/_wtoi/test1,1
 c_runtime/abs/test1,1
 c_runtime/acos/test1,1
+c_runtime/acosf/test1,1
 c_runtime/asin/test1,1
+c_runtime/asinf/test1,1
 c_runtime/atan/test1,1
 c_runtime/atan2/test1,1
+c_runtime/atan2f/test1,1
+c_runtime/atanf/test1,1
 c_runtime/atof/test1,1
 c_runtime/atoi/test1,1
 c_runtime/atol/test1,1
 c_runtime/bsearch/test1,1
 c_runtime/bsearch/test2,1
 c_runtime/ceil/test1,1
+c_runtime/ceilf/test1,1
 c_runtime/cos/test1,1
+c_runtime/cosf/test1,1
 c_runtime/cosh/test1,1
+c_runtime/coshf/test1,1
 c_runtime/ctime/test1,1
 c_runtime/errno/test1,1
 c_runtime/errno/test2,1
 c_runtime/exit/test1,1
 c_runtime/exp/test1,1
+c_runtime/expf/test1,1
 c_runtime/fabs/test1,1
 c_runtime/fabsf/test1,1
 c_runtime/fclose/test1,1
@@ -151,6 +161,7 @@ c_runtime/fgets/test1,1
 c_runtime/fgets/test2,1
 c_runtime/fgets/test3,1
 c_runtime/floor/test1,1
+c_runtime/floorf/test1,1
 c_runtime/fmod/test1,1
 c_runtime/fmodf/test1,1
 c_runtime/fopen/test1,1
@@ -230,6 +241,8 @@ c_runtime/llabs/test1,1
 c_runtime/localtime/test1,1
 c_runtime/log/test1,1
 c_runtime/log10/test1,1
+c_runtime/log10f/test1,1
+c_runtime/logf/test1,1
 c_runtime/malloc/test1,1
 c_runtime/memchr/test1,1
 c_runtime/memcmp/test1,1
@@ -238,6 +251,7 @@ c_runtime/memmove/test1,1
 c_runtime/memset/test1,1
 c_runtime/modf/test1,1
 c_runtime/pow/test1,1
+c_runtime/powf/test1,1
 c_runtime/printf/test1,1
 c_runtime/printf/test2,1
 c_runtime/printf/test3,1
@@ -262,7 +276,9 @@ c_runtime/qsort/test2,1
 c_runtime/rand_srand/test1,1
 c_runtime/realloc/test1,1
 c_runtime/sin/test1,1
+c_runtime/sinf/test1,1
 c_runtime/sinh/test1,1
+c_runtime/sinhf/test1,1
 c_runtime/sprintf/test1,1
 c_runtime/sprintf/test2,1
 c_runtime/sprintf/test3,1
@@ -283,6 +299,7 @@ c_runtime/sprintf/test17,1
 c_runtime/sprintf/test18,1
 c_runtime/sprintf/test19,1
 c_runtime/sqrt/test1,1
+c_runtime/sqrtf/test1,1
 c_runtime/sscanf/test1,1
 c_runtime/sscanf/test2,1
 c_runtime/sscanf/test3,1
@@ -354,7 +371,9 @@ c_runtime/swscanf/test15,1
 c_runtime/swscanf/test16,1
 c_runtime/swscanf/test17,1
 c_runtime/tan/test1,1
+c_runtime/tanf/test1,1
 c_runtime/tanh/test1,1
+c_runtime/tanhf/test1,1
 c_runtime/time/test1,1
 c_runtime/tolower/test1,1
 c_runtime/toupper/test1,1
index d0c315d..2277b03 100644 (file)
@@ -1251,6 +1251,29 @@ FCFuncStart(gMathFuncs)
     FCIntrinsic("Tanh", COMDouble::Tanh, CORINFO_INTRINSIC_Tanh)
 FCFuncEnd()
 
+FCFuncStart(gMathFFuncs)
+    FCIntrinsic("Abs", COMSingle::Abs, CORINFO_INTRINSIC_Abs)
+    FCIntrinsic("Acos", COMSingle::Acos, CORINFO_INTRINSIC_Acos)
+    FCIntrinsic("Asin", COMSingle::Asin, CORINFO_INTRINSIC_Asin)
+    FCIntrinsic("Atan", COMSingle::Atan, CORINFO_INTRINSIC_Atan)
+    FCIntrinsic("Atan2", COMSingle::Atan2, CORINFO_INTRINSIC_Atan2)
+    FCIntrinsic("Ceiling", COMSingle::Ceil, CORINFO_INTRINSIC_Ceiling)
+    FCIntrinsic("Cos", COMSingle::Cos, CORINFO_INTRINSIC_Cos)
+    FCIntrinsic("Cosh", COMSingle::Cosh, CORINFO_INTRINSIC_Cosh)
+    FCIntrinsic("Exp", COMSingle::Exp, CORINFO_INTRINSIC_Exp)
+    FCIntrinsic("Floor", COMSingle::Floor, CORINFO_INTRINSIC_Floor)
+    FCFuncElement("Log", COMSingle::Log)
+    FCIntrinsic("Log10", COMSingle::Log10, CORINFO_INTRINSIC_Log10)
+    FCIntrinsic("Pow", COMSingle::Pow, CORINFO_INTRINSIC_Pow)
+    FCIntrinsic("Round", COMSingle::Round, CORINFO_INTRINSIC_Round)
+    FCIntrinsic("Sin", COMSingle::Sin, CORINFO_INTRINSIC_Sin)
+    FCIntrinsic("Sinh", COMSingle::Sinh, CORINFO_INTRINSIC_Sinh)
+    FCFuncElement("SplitFractionSingle", COMSingle::ModF)
+    FCIntrinsic("Sqrt", COMSingle::Sqrt, CORINFO_INTRINSIC_Sqrt)
+    FCIntrinsic("Tan", COMSingle::Tan, CORINFO_INTRINSIC_Tan)
+    FCIntrinsic("Tanh", COMSingle::Tanh, CORINFO_INTRINSIC_Tanh)
+FCFuncEnd()
+
 FCFuncStart(gRuntimeThreadFuncs)
     FCFuncElement("get_IsAlive", ThreadNative::IsAlive)
     FCFuncElement("IsBackgroundNative", ThreadNative::IsBackground)
@@ -2252,6 +2275,7 @@ FCClassElement("Marshal", "System.Runtime.InteropServices", gInteropMarshalFuncs
 FCClassElement("MarshalByRefObject", "System", gMarshalByRefFuncs)
 #endif
 FCClassElement("Math", "System", gMathFuncs)
+FCClassElement("MathF", "System", gMathFFuncs)
 #ifdef MDA_SUPPORTED 
 FCClassElement("Mda", "System", gMda)
 #endif