From: Pali Rohár > Sent: 22 July 2021 22:58 > > On Monday 19 July 2021 15:47:07 Andy Shevchenko wrote: > > On Sat, Jul 17, 2021 at 3:39 PM Pali Rohár <pali@xxxxxxxxxx> wrote: > > > > > > Provide DIV_U64_ROUND_CLOSEST helper which uses div_u64 to perform > > > division rounded to the closest integer using unsigned 64bit > > > dividend and unsigned 32bit divisor. > > > > ... > > > > > +/* > > > + * DIV_U64_ROUND_CLOSEST - unsigned 64bit divide with 32bit divisor rounded to nearest integer > > > > > + * @dividend: unsigned 64bit dividend > > > > Here you insist users to provide a u64 (or compatible) type. > > > > > + * @divisor: unsigned 32bit divisor > > > + * > > > + * Divide unsigned 64bit dividend by unsigned 32bit divisor > > > + * and round to closest integer. > > > + * > > > + * Return: dividend / divisor rounded to nearest integer > > > + */ > > > +#define DIV_U64_ROUND_CLOSEST(dividend, divisor) \ > > > > > + ({ u32 _tmp = (divisor); div_u64((u64)(dividend) + _tmp / 2, _tmp); }) > > > > Here is the casting to u64. Why? (Yes, I have read v1 discussion and I > > just want to continue it here). > > See also Willy's response: https://lore.kernel.org/lkml/20210625155008.GB16901@xxxxxx/ > > Macro does not enforce type as opposite to function. > > There is no compile time check for correct type and neither compile time > warning if smaller typed value is passed. > > And e.g. passing constant with explicit ULL suffix or casting external > constant to 64bit type is impractical. What is wrong with: ({ u32 _tmp = (divisor); div_u64((dividend) + (u64)0 + _tmp / 2, _tmp); }) Or: ({ u32 _tmp = (divisor); div_u64((dividend) + (u64)(_tmp / 2), _tmp); }) Both will ensure a 32bit 'dividend' is promoted to 64 bits before the '+'. Both will fail if 'dividend' isn't an integer type. On 32bit systems the compiler will also know when the high bits van be ignored. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)