Message ID | 20231215152440.34537-1-lucas.segarra.fernandez@intel.com |
---|---|
State | New |
Headers | show |
Series | [1/5] math.h: Add avg_array() | expand |
On Fri, Dec 15, 2023 at 04:24:40PM +0100, Lucas Segarra Fernandez wrote: > Add macro to compute average of values within an array. > > This patch is based on earlier work done by Wojciech Ziemba. > > Signed-off-by: Lucas Segarra Fernandez <lucas.segarra.fernandez@intel.com> > Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com> > Reviewed-by: Damian Muszynski <damian.muszynski@intel.com> > --- > include/linux/math.h | 33 +++++++++++++++++++++++++++++++++ > 1 file changed, 33 insertions(+) I think adding this to a common header when there are no other users is a bit premature. Please keep it in a local header file until a new user appears. Thanks,
diff --git a/include/linux/math.h b/include/linux/math.h index dd4152711de7..012416c92e89 100644 --- a/include/linux/math.h +++ b/include/linux/math.h @@ -205,4 +205,37 @@ static inline u32 int_sqrt64(u64 x) } #endif +/** + * avg_array() - Return average of values within an array. + * @array: Array of values. + * @len: Number of elements. + * + * This algorithm computes average of an array without running into overflow. + * + * Return: average of values. + */ +#define avg_array(array, len) ( \ +{ \ + typeof(&(array)[0]) _array = (array); \ + __unqual_scalar_typeof(_array[0]) _x = 0; \ + __unqual_scalar_typeof(_array[0]) _y = 0; \ + __unqual_scalar_typeof(_array[0]) _a, _b; \ + typeof(len) _len = (len); \ + size_t _i; \ + \ + for (_i = 0; _i < _len; _i++) { \ + _a = _array[_i]; \ + _b = do_div(_a, _len); \ + _x += _a; \ + if (_y >= _len - _b) { \ + _x++; \ + _y -= _len - _b; \ + } else { \ + _y += _b; \ + } \ + } \ + do_div(_y, _len); \ + (_x + _y); \ +}) + #endif /* _LINUX_MATH_H */