@@ -38,6 +38,79 @@ BFDEV_BEGIN_DECLS
3838 (x) & ~bfdev_round_mask(x, y) \
3939)
4040
41+ #define bfdev_abs_expr (var , type , other ) __builtin_choose_expr( \
42+ __builtin_types_compatible_p(typeof(var), signed type) || \
43+ __builtin_types_compatible_p(typeof(var), unsigned type), \
44+ ({ \
45+ signed type __var; \
46+ __var = (signed type)(var); \
47+ __var < 0 ? - __var : __var; \
48+ }), other \
49+ )
50+
51+ /**
52+ * bfdev_abs - return absolute value of an argument.
53+ *
54+ * If it is unsigned type, it is converted to signed type first.
55+ * char is treated as if it was signed but the macro's
56+ * return type is preserved as char.
57+ */
58+ #define bfdev_abs (var ) \
59+ bfdev_abs_expr(var, long long, \
60+ bfdev_abs_expr(var, long, \
61+ bfdev_abs_expr(var, int, \
62+ bfdev_abs_expr(var, short, \
63+ bfdev_abs_expr(var, char, \
64+ __builtin_choose_expr( \
65+ __builtin_types_compatible_p( \
66+ typeof(var), char), \
67+ (char) ({ \
68+ signed char __var; \
69+ __var = (signed char)(var); \
70+ __var < 0 ? - __var : __var; \
71+ }), \
72+ ((void)0) \
73+ ) \
74+ )))) \
75+ )
76+
77+ /**
78+ * bfdev_abs_diff - return absolute value of the difference between the args.
79+ * @var1: the first argument.
80+ * @var2: the second argument.
81+ */
82+ #define bfdev_abs_diff (var1 , var2 ) ({ \
83+ typeof(var1) __var1, __var2; \
84+ \
85+ __var1 = (typeof(var1))(var1); \
86+ __var2 = (typeof(var1))(var2); \
87+ \
88+ __var1 > __var2 \
89+ ? (__var1 - __var2) \
90+ : (__var2 - __var1); \
91+ })
92+
93+ /**
94+ * BFDEV_MULT_FRAC
95+ *
96+ * Calculate "value * numer / denom"
97+ * without unnecessary overflow or loss of precision.
98+ */
99+ #define BFDEV_MULT_FRAC (value , numer , denom ) ({ \
100+ typeof(value) __value, __numer, __denom; \
101+ typeof(value) __quot, __rem; \
102+ \
103+ __value = (typeof(value))(value); \
104+ __numer = (typeof(value))(numer); \
105+ __denom = (typeof(value))(denom); \
106+ \
107+ __quot = (__value) / (__denom); \
108+ __rem = (__value) % (__denom); \
109+ \
110+ (__quot * (__numer)) + \
111+ ((__rem * (__numer)) / (__denom)); \
112+ })
113+
41114/**
42115 * BFDEV_DIV_ROUND_UP - round up division.
43116 * @n: divisor number.
0 commit comments