fast increase number to be mod 16 in C
what is the best way to to get the closest, non-smaller number that is divisible by 16?
the method I came up with doesn't look very elegant or fast
int non_smaller_int_divisible_by_16(int x)
{
return x + ((16 - (x % 16)) % 16);
}
the expected results are
result | X values
-------|----------
16 | 1,2,..., 16
32 | 17开发者_如何学运维, 18, ... 32
48 | 33, 34, ..., 48
etc
int non_smaller_int_divisible_by_16(int x)
{
return (x + 15) & ~15;
}
Since 16 is a power of two, you can use binary masking - add 15 so we get the next highest multiple, and mask with the bitwise inverse of 15, to clear the bottom bits.
Edit:
It's not clear what you want to happen with negative numbers - both your and my code will round to more-positive values (ie negative numbers will get smaller). If negative values don't make sense in your program, it'd be better to use an unsigned type.
Finally, you might be interested to look at Bit Twiddling Hacks, which is a great collection of some really clever (if often extremely obscure) tricks along these lines.
@therefromhere's solution is more elegant and faster, but if you need to do this with a number that isn't a power of 2 then you can use this approach.
int non_smaller_int_divisible_by_n(int x, int n)
{
return n*((x+n-1)/n);
}
following @nemo's comment, there's a nifty way to solve this that works for all mod bases, is very readable, and should be fast
unsigned int non_smaller_int_divisible_by_16(unsigned int x)
{
return x + ((-x) % 16);
}
the generic version is therefore
unsigned int non_smaller_int_divisible_by_base(unsigned int x, unsigned int base)
{
return x + ((-x) % base);
}
int non_smaller_int_divisible_by_16(int x) {
return (x & 15) ? (x | 15) + 1 : x;
}
精彩评论