math_test.ha (9160B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 @test fn eqwithin() void = { 5 assert(eqwithin(1f64, 2f64, 2f64)); 6 assert(eqwithin(1.0f32, 2.0f32, 2.0f32)); 7 assert(!eqwithin(1.0005f32, 1.0004f32, 0.00001f32)); 8 assert(isclose(1f64, 1.0000000000000000000000000001f64)); 9 assert(isclose(1.0f32, 1.0000000000000000000000000001f32)); 10 assert(!isclose(1.0005f32, 1.0004f32)); 11 }; 12 13 @test fn logf64() void = { 14 for (let idx = 0z; idx < len(TEST_INPUTS); idx += 1) { 15 assert(isclose( 16 logf64(absf64(TEST_INPUTS[idx])), 17 TEST_LOG[idx])); 18 }; 19 assert(logf64(E) == 1f64); 20 assert(logf64(54.598150033144239078110261202860878402790f64) == 4f64); 21 assert(isnan(logf64(-1f64))); 22 assert(logf64(INF) == INF); 23 assert(logf64(0f64) == -INF); 24 assert(isnan(logf64(NAN))); 25 }; 26 27 @test fn log10f64() void = { 28 for (let idx = 0z; idx < len(TEST_INPUTS); idx += 1) { 29 assert(isclose( 30 log10f64(absf64(TEST_INPUTS[idx])), 31 TEST_LOG10[idx])); 32 }; 33 }; 34 35 @test fn log2f64() void = { 36 for (let idx = 0z; idx < len(TEST_INPUTS); idx += 1) { 37 assert(isclose( 38 log2f64(absf64(TEST_INPUTS[idx])), 39 TEST_LOG2[idx])); 40 }; 41 }; 42 43 @test fn log1p() void = { 44 for (let idx = 0z; idx < 10; idx += 1) { 45 assert(isclose( 46 log1pf64(TEST_INPUTS[idx] / 100f64), 47 TEST_LOG1P[idx])); 48 }; 49 assert(isnan(log1pf64(-INF))); 50 assert(isnan(log1pf64(-PI))); 51 assert(log1pf64(-1f64) == -INF); 52 assert(log1pf64(-0f64) == -0f64); 53 assert(log1pf64(0f64) == 0f64); 54 assert(log1pf64(INF) == INF); 55 assert(isnan(log1pf64(NAN))); 56 }; 57 58 @test fn expf64() void = { 59 for (let idx = 0z; idx < len(TEST_INPUTS); idx += 1) { 60 assert(isclose(expf64(TEST_INPUTS[idx]), TEST_EXP[idx])); 61 }; 62 assert(expf64(1f64) == E); 63 assert(isnan(expf64(NAN))); 64 assert(isinf(expf64(INF))); 65 assert(expf64(-INF) == 0f64); 66 assert(isinf(expf64(99999f64))); 67 assert(expf64(-99999f64) == 0f64); 68 assert(expf64(0.5e-20) == 1f64); 69 }; 70 71 @test fn exp2f64() void = { 72 for (let idx = 0z; idx < len(TEST_INPUTS); idx += 1) { 73 assert(isclose(exp2f64(TEST_INPUTS[idx]), TEST_EXP2[idx])); 74 }; 75 assert(exp2f64(0f64) == 1f64); 76 assert(exp2f64(3f64) == 8f64); 77 assert(exp2f64(-2f64) == 0.25f64); 78 assert(!isinf(exp2f64(256f64))); 79 assert(isinf(exp2f64(99999f64))); 80 assert(exp2f64(-99999f64) == 0f64); 81 assert(isnan(exp2f64(NAN))); 82 assert(isinf(exp2f64(INF))); 83 assert(exp2f64(-INF) == 0f64); 84 }; 85 86 @test fn sqrt() void = { 87 for (let idx = 0z; idx < len(TEST_INPUTS); idx += 1) { 88 assert(isclose( 89 sqrtf64(absf64(TEST_INPUTS[idx])), 90 TEST_SQRT[idx])); 91 }; 92 assert(sqrtf64(2f64) == SQRT_2); 93 assert(sqrtf64(4f64) == 2f64); 94 assert(sqrtf64(16f64) == 4f64); 95 assert(sqrtf64(65536f64) == 256f64); 96 assert(sqrtf64(powf64(123f64, 2f64)) == 123f64); 97 assert(sqrtf64(0f64) == 0f64); 98 assert(isnan(sqrtf64(NAN))); 99 assert(sqrtf64(INF) == INF); 100 assert(isnan(sqrtf64(-2f64))); 101 }; 102 103 @test fn powf64() void = { 104 for (let idx = 0z; idx < len(TEST_INPUTS); idx += 1) { 105 assert(eqwithin( 106 powf64(10f64, TEST_INPUTS[idx]), 107 TEST_POW[idx], 108 1e-8f64)); 109 }; 110 // Positive integer 111 assert(powf64(2f64, 2f64) == 4f64); 112 assert(powf64(3f64, 3f64) == 27f64); 113 // Very large positive integer 114 assert(!isinf(powf64(2f64, 1020f64))); 115 assert(isinf(powf64(2f64, 1050f64))); 116 // Very very large positive integer 117 assert(isinf(powf64(2f64, F64_MAX_NORMAL))); 118 assert(powf64(0.5f64, F64_MAX_NORMAL) == 0f64); 119 // Negative integer 120 assert(powf64(2f64, -1f64) == 0.5f64); 121 assert(powf64(2f64, -2f64) == 0.25f64); 122 // Very small negative integer 123 assert(powf64(2f64, -1020f64) > 0f64); 124 assert(powf64(2f64, -1080f64) == 0f64); 125 // Very very small negative integer 126 assert(powf64(2f64, -F64_MAX_NORMAL) == 0f64); 127 assert(isinf(powf64(0.5f64, -F64_MAX_NORMAL))); 128 // Positive fractional powers 129 assert(eqwithin(powf64(2f64, 1.5f64), 130 2.8284271247461900976033774f64, 131 1e-10f64)); 132 assert(eqwithin(powf64(2f64, 5.5f64), 133 45.254833995939041561654039f64, 134 1e-10f64)); 135 // Negative fractional powers 136 assert(eqwithin(powf64(2f64, -1.5f64), 137 0.3535533905932737622004221f64, 138 1e-10f64)); 139 assert(eqwithin(powf64(2f64, -5.5f64), 140 0.0220970869120796101375263f64, 141 1e-10f64)); 142 143 // Special cases 144 // pow(x, ±0) = 1 for any x 145 assert(powf64(123f64, 0f64) == 1f64); 146 // pow(1, y) = 1 for any y 147 assert(powf64(1f64, 123f64) == 1f64); 148 // pow(x, 1) = x for any x 149 assert(powf64(123f64, 1f64) == 123f64); 150 // pow(NaN, y) = NaN 151 assert(isnan(powf64(NAN, 123f64))); 152 // pow(x, NaN) = NaN 153 assert(isnan(powf64(123f64, NAN))); 154 // pow(±0, y) = ±Inf for y an odd integer < 0 155 assert(powf64(0f64, -3f64) == INF); 156 assert(powf64(-0f64, -3f64) == -INF); 157 // pow(±0, -Inf) = +Inf 158 assert(powf64(0f64, -INF) == INF); 159 assert(powf64(-0f64, -INF) == INF); 160 // pow(±0, +Inf) = +0 161 assert(powf64(0f64, INF) == 0f64); 162 assert(powf64(-0f64, INF) == 0f64); 163 // pow(±0, y) = +Inf for finite y < 0 and not an odd integer 164 assert(powf64(0f64, -2f64) == INF); 165 assert(powf64(0f64, -2f64) == INF); 166 //pow(±0, y) = ±0 for y an odd integer > 0 167 assert(powf64(0f64, 123f64) == 0f64); 168 const neg_zero = powf64(-0f64, 123f64); 169 assert(neg_zero == 0f64); 170 assert(isnegative(neg_zero)); 171 // pow(±0, y) = +0 for finite y > 0 and not an odd integer 172 assert(powf64(0f64, 8f64) == 0f64); 173 // pow(-1, ±Inf) = 1 174 assert(powf64(-1f64, INF) == 1f64); 175 assert(powf64(-1f64, -INF) == 1f64); 176 // pow(x, +Inf) = +Inf for |x| > 1 177 assert(powf64(123f64, INF) == INF); 178 // pow(x, -Inf) = +0 for |x| > 1 179 assert(powf64(123f64, -INF) == 0f64); 180 // pow(x, +Inf) = +0 for |x| < 1 181 assert(powf64(0.5f64, INF) == 0f64); 182 assert(powf64(-0.5f64, INF) == 0f64); 183 // pow(x, -Inf) = +Inf for |x| < 1 184 assert(powf64(0.5f64, -INF) == INF); 185 assert(powf64(-0.5f64, -INF) == INF); 186 // pow(+Inf, y) = +Inf for y > 0 187 assert(powf64(INF, 123f64) == INF); 188 // pow(+Inf, y) = +0 for y < 0 189 assert(powf64(INF, -1f64) == 0f64); 190 // pow(-Inf, y) = pow(-0, -y) 191 assert(powf64(-INF, 123f64) == powf64(-0f64, -123f64)); 192 // pow(x, y) = NaN for finite x < 0 and finite non-integer y 193 assert(isnan(powf64(-2f64, 1.23f64))); 194 // sqrt 195 assert(powf64(4f64, 0.5f64) == sqrtf64(4f64)); 196 assert(powf64(4f64, 0.5f64) == 2f64); 197 assert(powf64(4f64, -0.5f64) == (1f64 / sqrtf64(4f64))); 198 assert(powf64(4f64, -0.5f64) == (1f64 / 2f64)); 199 }; 200 201 @test fn floor() void = { 202 for (let idx = 0z; idx < 10; idx += 1) { 203 assert(isclose( 204 floorf64(TEST_INPUTS[idx]), 205 TEST_FLOOR[idx])); 206 }; 207 assert(floorf64(-INF) == -INF); 208 assert(floorf64(-0f64) == -0f64); 209 assert(floorf64(0f64) == 0f64); 210 assert(floorf64(INF) == INF); 211 assert(isnan(floorf64(NAN))); 212 }; 213 214 @test fn ceil() void = { 215 for (let idx = 0z; idx < 10; idx += 1) { 216 assert(isclose( 217 ceilf64(TEST_INPUTS[idx]), 218 TEST_CEIL[idx])); 219 }; 220 assert(ceilf64(-INF) == -INF); 221 assert(ceilf64(-F64_MAX_NORMAL) == -F64_MAX_NORMAL); 222 assert(ceilf64(-0f64) == -0f64); 223 assert(ceilf64(0f64) == 0f64); 224 assert(ceilf64(F64_MAX_NORMAL) == F64_MAX_NORMAL); 225 assert(ceilf64(INF) == INF); 226 assert(isnan(ceilf64(NAN))); 227 }; 228 229 @test fn trunc() void = { 230 for (let idx = 0z; idx < 10; idx += 1) { 231 assert(isclose( 232 truncf64(TEST_INPUTS[idx]), 233 TEST_TRUNC[idx])); 234 }; 235 assert(truncf64(-INF) == -INF); 236 assert(truncf64(-F64_MAX_NORMAL) == -F64_MAX_NORMAL); 237 assert(truncf64(-0f64) == -0f64); 238 assert(truncf64(0f64) == 0f64); 239 assert(truncf64(F64_MAX_NORMAL) == F64_MAX_NORMAL); 240 assert(truncf64(INF) == INF); 241 assert(isnan(truncf64(NAN))); 242 }; 243 244 @test fn round() void = { 245 for (let idx = 0z; idx < 10; idx += 1) { 246 assert(isclose( 247 roundf64(TEST_INPUTS[idx]), 248 TEST_ROUND[idx])); 249 }; 250 assert(roundf64(-INF) == -INF); 251 assert(roundf64(-F64_MAX_NORMAL) == -F64_MAX_NORMAL); 252 assert(roundf64(-0f64) == -0f64); 253 assert(roundf64(0f64) == 0f64); 254 assert(roundf64(F64_MAX_NORMAL) == F64_MAX_NORMAL); 255 assert(roundf64(INF) == INF); 256 assert(isnan(roundf64(NAN))); 257 }; 258 259 @test fn modf64() void = { 260 for (let idx = 0z; idx < 10; idx += 1) { 261 assert(isclose( 262 modf64(10f64, TEST_INPUTS[idx]), 263 TEST_MODF[idx])); 264 }; 265 266 assert(isnan(modf64(-INF, -INF))); 267 assert(isnan(modf64(-INF, -PI))); 268 assert(isnan(modf64(-INF, 0f64))); 269 assert(isnan(modf64(-INF, PI))); 270 assert(isnan(modf64(-INF, INF))); 271 assert(isnan(modf64(-INF, NAN))); 272 assert(modf64(-PI, -INF) == -PI); 273 assert(isnan(modf64(-PI, 0f64))); 274 assert(modf64(-PI, INF) == -PI); 275 assert(isnan(modf64(-PI, NAN))); 276 assert(modf64(-0f64, -INF) == -0f64); 277 assert(isnan(modf64(-0f64, 0f64))); 278 assert(modf64(-0f64, INF) == -0f64); 279 assert(isnan(modf64(-0f64, NAN))); 280 assert(modf64(0f64, -INF) == 0f64); 281 assert(isnan(modf64(0f64, 0f64))); 282 assert(modf64(0f64, INF) == 0f64); 283 assert(isnan(modf64(0f64, NAN))); 284 assert(modf64(PI, -INF) == PI); 285 assert(isnan(modf64(PI, 0f64))); 286 assert(modf64(PI, INF) == PI); 287 assert(isnan(modf64(PI, NAN))); 288 assert(isnan(modf64(INF, -INF))); 289 assert(isnan(modf64(INF, -PI))); 290 assert(isnan(modf64(INF, 0f64))); 291 assert(isnan(modf64(INF, PI))); 292 assert(isnan(modf64(INF, INF))); 293 assert(isnan(modf64(INF, NAN))); 294 assert(isnan(modf64(NAN, -INF))); 295 assert(isnan(modf64(NAN, -PI))); 296 assert(isnan(modf64(NAN, 0f64))); 297 assert(isnan(modf64(NAN, PI))); 298 assert(isnan(modf64(NAN, INF))); 299 assert(isnan(modf64(NAN, NAN))); 300 assert(modf64(5.9790119248836734e+200, 1.1258465975523544) == 301 0.6447968302508578); 302 };