| 1 | // Licensed to the .NET Foundation under one or more agreements. | 
| 2 | // The .NET Foundation licenses this file to you under the MIT license. | 
| 3 | // See the LICENSE file in the project root for more information. | 
| 4 |  | 
| 5 | /*===================================================================== | 
| 6 | ** | 
| 7 | ** Source:  test1.c | 
| 8 | ** | 
| 9 | ** Purpose: Tests log with a normal set of values. | 
| 10 | ** | 
| 11 | **===================================================================*/ | 
| 12 |  | 
| 13 | #include <palsuite.h> | 
| 14 |  | 
| 15 | // binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this  | 
| 16 | // is slightly too accurate when writing tests meant to run against libm implementations | 
| 17 | // for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. | 
| 18 | // | 
| 19 | // The tests themselves will take PAL_EPSILON and adjust it according to the expected result | 
| 20 | // so that the delta used for comparison will compare the most significant digits and ignore | 
| 21 | // any digits that are outside the double precision range (15-17 digits). | 
| 22 |  | 
| 23 | // For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use | 
| 24 | // PAL_EPSILON for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx | 
| 25 | // will use PAL_EPSILON / 10 and and expected result in the format of x.xxxxxxxxxxxxxxxx will | 
| 26 | // use PAL_EPSILON * 10. | 
| 27 | #define PAL_EPSILON 8.8817841970012523e-16 | 
| 28 |  | 
| 29 | #define PAL_NAN     sqrt(-1.0) | 
| 30 | #define PAL_POSINF -log(0.0) | 
| 31 | #define PAL_NEGINF  log(0.0) | 
| 32 |  | 
| 33 | /** | 
| 34 |  * Helper test structure | 
| 35 |  */ | 
| 36 | struct test | 
| 37 | { | 
| 38 |     double value;     /* value to test the function with */ | 
| 39 |     double expected;  /* expected result */ | 
| 40 |     double variance;  /* maximum delta between the expected and actual result */ | 
| 41 | }; | 
| 42 |  | 
| 43 | /** | 
| 44 |  * validate | 
| 45 |  * | 
| 46 |  * test validation function | 
| 47 |  */ | 
| 48 | void __cdecl validate(double value, double expected, double variance) | 
| 49 | { | 
| 50 |     double result = log(value); | 
| 51 |  | 
| 52 |     /* | 
| 53 |      * The test is valid when the difference between result | 
| 54 |      * and expected is less than or equal to variance | 
| 55 |      */ | 
| 56 |     double delta = fabs(result - expected); | 
| 57 |  | 
| 58 |     if (delta > variance) | 
| 59 |     { | 
| 60 |         Fail("log(%g) returned %20.17g when it should have returned %20.17g" , | 
| 61 |              value, result, expected); | 
| 62 |     } | 
| 63 | } | 
| 64 |  | 
| 65 | /** | 
| 66 |  * validate | 
| 67 |  * | 
| 68 |  * test validation function for values returning NaN | 
| 69 |  */ | 
| 70 | void __cdecl validate_isnan(double value) | 
| 71 | { | 
| 72 |     double result = log(value); | 
| 73 |  | 
| 74 |     if (!_isnan(result)) | 
| 75 |     { | 
| 76 |         Fail("log(%g) returned %20.17g when it should have returned %20.17g" , | 
| 77 |              value, result, PAL_NAN); | 
| 78 |     } | 
| 79 | } | 
| 80 |  | 
| 81 | /** | 
| 82 |  * main | 
| 83 |  *  | 
| 84 |  * executable entry point | 
| 85 |  */ | 
| 86 | int __cdecl main(int argc, char **argv) | 
| 87 | { | 
| 88 |     struct test tests[] =  | 
| 89 |     { | 
| 90 |         /* value                       expected               variance */ | 
| 91 |         {  0,                          PAL_NEGINF,            0 }, | 
| 92 |         {  0.043213918263772250,      -3.1415926535897932,    PAL_EPSILON * 10 },   // expected: -(pi) | 
| 93 |         {  0.065988035845312537,      -2.7182818284590452,    PAL_EPSILON * 10 },   // expected: -(e) | 
| 94 |         {  0.1,                       -2.3025850929940457,    PAL_EPSILON * 10 },   // expected: -(ln(10)) | 
| 95 |         {  0.20787957635076191,       -1.5707963267948966,    PAL_EPSILON * 10 },   // expected: -(pi / 2) | 
| 96 |         {  0.23629008834452270,       -1.4426950408889634,    PAL_EPSILON * 10 },   // expected: -(log2(e)) | 
| 97 |         {  0.24311673443421421,       -1.4142135623730950,    PAL_EPSILON * 10 },   // expected: -(sqrt(2)) | 
| 98 |         {  0.32355726390307110,       -1.1283791670955126,    PAL_EPSILON * 10 },   // expected: -(2 / sqrt(pi)) | 
| 99 |         {  0.36787944117144232,       -1,                     PAL_EPSILON * 10 },   // expected: -(1) | 
| 100 |         {  0.45593812776599624,       -0.78539816339744831,   PAL_EPSILON },        // expected: -(pi / 4) | 
| 101 |         {  0.49306869139523979,       -0.70710678118654752,   PAL_EPSILON },        // expected: -(1 / sqrt(2)) | 
| 102 |         {  0.5,                       -0.69314718055994531,   PAL_EPSILON },        // expected: -(ln(2)) | 
| 103 |         {  0.52907780826773535,       -0.63661977236758134,   PAL_EPSILON },        // expected: -(2 / pi) | 
| 104 |         {  0.64772148514180065,       -0.43429448190325183,   PAL_EPSILON },        // expected: -(log10(e)) | 
| 105 |         {  0.72737734929521647,       -0.31830988618379067,   PAL_EPSILON },        // expected: -(1 / pi) | 
| 106 |         {  1,                          0,                     PAL_EPSILON }, | 
| 107 |         {  1.3748022274393586,         0.31830988618379067,   PAL_EPSILON },        // expected:  1 / pi | 
| 108 |         {  1.5438734439711811,         0.43429448190325183,   PAL_EPSILON },        // expected:  log10(e) | 
| 109 |         {  1.8900811645722220,         0.63661977236758134,   PAL_EPSILON },        // expected:  2 / pi | 
| 110 |         {  2,                          0.69314718055994531,   PAL_EPSILON },        // expected:  ln(2) | 
| 111 |         {  2.0281149816474725,         0.70710678118654752,   PAL_EPSILON },        // expected:  1 / sqrt(2) | 
| 112 |         {  2.1932800507380155,         0.78539816339744831,   PAL_EPSILON },        // expected:  pi / 4 | 
| 113 |         {  2.7182818284590452,         1,                     PAL_EPSILON * 10 },   //                               value: e | 
| 114 |         {  3.0906430223107976,         1.1283791670955126,    PAL_EPSILON * 10 },   // expected:  2 / sqrt(pi) | 
| 115 |         {  4.1132503787829275,         1.4142135623730950,    PAL_EPSILON * 10 },   // expected:  sqrt(2) | 
| 116 |         {  4.2320861065570819,         1.4426950408889634,    PAL_EPSILON * 10 },   // expected:  log2(e) | 
| 117 |         {  4.8104773809653517,         1.5707963267948966,    PAL_EPSILON * 10 },   // expected:  pi / 2 | 
| 118 |         {  10,                         2.3025850929940457,    PAL_EPSILON * 10 },   // expected:  ln(10) | 
| 119 |         {  15.154262241479264,         2.7182818284590452,    PAL_EPSILON * 10 },   // expected:  e | 
| 120 |         {  23.140692632779269,         3.1415926535897932,    PAL_EPSILON * 10 },   // expected:  pi | 
| 121 |         {  PAL_POSINF,                 PAL_POSINF,            0 }, | 
| 122 |     }; | 
| 123 |  | 
| 124 |  | 
| 125 |     if (PAL_Initialize(argc, argv) != 0) | 
| 126 |     { | 
| 127 |         return FAIL; | 
| 128 |     } | 
| 129 |  | 
| 130 |     for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++) | 
| 131 |     { | 
| 132 |         validate(tests[i].value, tests[i].expected, tests[i].variance); | 
| 133 |     } | 
| 134 |      | 
| 135 |     validate_isnan(PAL_NEGINF); | 
| 136 |     validate_isnan(PAL_NAN); | 
| 137 |  | 
| 138 |     PAL_Terminate(); | 
| 139 |     return PASS; | 
| 140 | } | 
| 141 |  |