diff options
Diffstat (limited to 'include/linux/math.h')
| -rw-r--r-- | include/linux/math.h | 80 |
1 files changed, 65 insertions, 15 deletions
diff --git a/include/linux/math.h b/include/linux/math.h index 53674a327e39..6dc1d1d32fbc 100644 --- a/include/linux/math.h +++ b/include/linux/math.h @@ -2,6 +2,7 @@ #ifndef _LINUX_MATH_H #define _LINUX_MATH_H +#include <linux/types.h> #include <asm/div64.h> #include <uapi/linux/kernel.h> @@ -33,6 +34,18 @@ */ #define round_down(x, y) ((x) & ~__round_mask(x, y)) +/** + * DIV_ROUND_UP_POW2 - divide and round up + * @n: numerator + * @d: denominator (must be a power of 2) + * + * Divides @n by @d and rounds up to next multiple of @d (which must be a power + * of 2). Avoids integer overflows that may occur with __KERNEL_DIV_ROUND_UP(). + * Performance is roughly equivalent to __KERNEL_DIV_ROUND_UP(). + */ +#define DIV_ROUND_UP_POW2(n, d) \ + ((n) / (d) + !!((n) & ((d) - 1))) + #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP #define DIV_ROUND_DOWN_ULL(ll, d) \ @@ -106,27 +119,45 @@ } \ ) -/* - * Multiplies an integer by a fraction, while avoiding unnecessary - * overflow or loss of precision. - */ -#define mult_frac(x, numer, denom)( \ -{ \ - typeof(x) quot = (x) / (denom); \ - typeof(x) rem = (x) % (denom); \ - (quot * (numer)) + ((rem * (numer)) / (denom)); \ -} \ -) +#define __STRUCT_FRACT(type) \ +struct type##_fract { \ + __##type numerator; \ + __##type denominator; \ +}; +__STRUCT_FRACT(s8) +__STRUCT_FRACT(u8) +__STRUCT_FRACT(s16) +__STRUCT_FRACT(u16) +__STRUCT_FRACT(s32) +__STRUCT_FRACT(u32) +#undef __STRUCT_FRACT + +/* Calculate "x * n / d" without unnecessary overflow or loss of precision. */ +#define mult_frac(x, n, d) \ +({ \ + typeof(x) x_ = (x); \ + typeof(n) n_ = (n); \ + typeof(d) d_ = (d); \ + \ + typeof(x_) q = x_ / d_; \ + typeof(x_) r = x_ % d_; \ + q * n_ + r * n_ / d_; \ +}) #define sector_div(a, b) do_div(a, b) /** * abs - return absolute value of an argument - * @x: the value. If it is unsigned type, it is converted to signed type first. - * char is treated as if it was signed (regardless of whether it really is) - * but the macro's return type is preserved as char. + * @x: the value. + * + * If it is unsigned type, @x is converted to signed type first. + * char is treated as if it was signed (regardless of whether it really is) + * but the macro's return type is preserved as char. * - * Return: an absolute value of x. + * NOTE, for signed type if @x is the minimum, the returned result is undefined + * as there is not enough bits to represent it as a positive number. + * + * Return: an absolute value of @x. */ #define abs(x) __abs_choose_expr(x, long long, \ __abs_choose_expr(x, long, \ @@ -144,6 +175,25 @@ ({ signed type __x = (x); __x < 0 ? -__x : __x; }), other) /** + * abs_diff - return absolute value of the difference between the arguments + * @a: the first argument + * @b: the second argument + * + * @a and @b have to be of the same type. With this restriction we compare + * signed to signed and unsigned to unsigned. The result is the subtraction + * the smaller of the two from the bigger, hence result is always a positive + * value. + * + * Return: an absolute value of the difference between the @a and @b. + */ +#define abs_diff(a, b) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + (void)(&__a == &__b); \ + __a > __b ? (__a - __b) : (__b - __a); \ +}) + +/** * reciprocal_scale - "scale" a value into range [0, ep_ro) * @val: value * @ep_ro: right open interval endpoint |
