1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _LINUX_HELPER_MACROS_H_ 3 #define _LINUX_HELPER_MACROS_H_ 4 5 #include <linux/math.h> 6 7 #define __find_closest(x, a, as, op) \ 8 ({ \ 9 typeof(as) __fc_i, __fc_as = (as) - 1; \ 10 typeof(x) __fc_x = (x); \ 11 typeof(*a) const *__fc_a = (a); \ 12 for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ 13 if (__fc_x op DIV_ROUND_CLOSEST(__fc_a[__fc_i] + \ 14 __fc_a[__fc_i + 1], 2)) \ 15 break; \ 16 } \ 17 (__fc_i); \ 18 }) 19 20 /** 21 * find_closest - locate the closest element in a sorted array 22 * @x: The reference value. 23 * @a: The array in which to look for the closest element. Must be sorted 24 * in ascending order. 25 * @as: Size of 'a'. 26 * 27 * Returns the index of the element closest to 'x'. 28 */ 29 #define find_closest(x, a, as) __find_closest(x, a, as, <=) 30 31 /** 32 * find_closest_descending - locate the closest element in a sorted array 33 * @x: The reference value. 34 * @a: The array in which to look for the closest element. Must be sorted 35 * in descending order. 36 * @as: Size of 'a'. 37 * 38 * Similar to find_closest() but 'a' is expected to be sorted in descending 39 * order. 40 */ 41 #define find_closest_descending(x, a, as) __find_closest(x, a, as, >=) 42 43 #endif 44