Branch data Line data Source code
1 : : // Copyright 2019-2024 David Robillard <d@drobilla.net> 2 : : // SPDX-License-Identifier: ISC 3 : : 4 : : #ifndef EXESS_TEST_DOUBLE_TEST_UTILS_H 5 : : #define EXESS_TEST_DOUBLE_TEST_UTILS_H 6 : : 7 : : #include "../src/ieee_float.h" 8 : : #include "../src/warnings.h" 9 : : 10 : : #include <assert.h> 11 : : #include <math.h> 12 : : #include <stdbool.h> 13 : : #include <stdint.h> 14 : : 15 : : /// Return a somewhat evenly distributed double from a random integer 16 : : static inline double 17 : 8192 : random_double(const uint64_t state) 18 : : { 19 : 8192 : return ldexp((double)(state & 0xFFFF0000U), (int)(state % 1024U) - 512); 20 : : } 21 : : 22 : : /// Return the distance between two doubles in ULPs 23 : : static uint64_t 24 : 24250 : double_ulp_distance(const double a, const double b) 25 : : { 26 : : EXESS_DISABLE_CONVERSION_WARNINGS 27 [ - + ]: 24250 : assert(!isnan(a)); 28 [ - + ]: 24250 : assert(!isnan(b)); 29 : : EXESS_RESTORE_WARNINGS 30 : : 31 [ - + ]: 24250 : assert(a >= 0.0); 32 [ - + ]: 24250 : assert(b >= 0.0); 33 : : 34 : 24250 : const uint64_t ia = double_to_rep(a); 35 : 24250 : const uint64_t ib = double_to_rep(b); 36 : : 37 [ + - ]: 24250 : return ia >= ib ? ia - ib : ib - ia; 38 : : } 39 : : 40 : : static bool 41 : 24257 : double_matches(const double a, const double b) 42 : : { 43 : : EXESS_DISABLE_CONVERSION_WARNINGS 44 : 24257 : const bool a_is_nan = isnan(a); 45 : 24257 : const bool a_is_negative = signbit(a); 46 : 24257 : const bool b_is_nan = isnan(b); 47 : 24257 : const bool b_is_negative = signbit(b); 48 : : EXESS_RESTORE_WARNINGS 49 : : 50 [ + + - + : 72757 : return (a_is_nan && b_is_nan) || + + ] 51 [ + - + - : 48500 : (!a_is_nan && !b_is_nan && a_is_negative == b_is_negative && + - + - + - ] 52 : 14 : (a_is_negative ? double_ulp_distance(-a, -b) == 0 53 : 24236 : : double_ulp_distance(a, b) == 0)); 54 : : } 55 : : 56 : : #endif // EXESS_TEST_DOUBLE_TEST_UTILS_H