|
|
|
|
|
by to3m
4296 days ago
|
|
Provided everything is unsigned, this should result in something somewhat similar. I think this form also makes it clearer what's going on. Assume MQ_ALIGNSIZE is a power of two. Then if N is the power, MQ_ALIGNSIZE is 1<<N. Then you can replace divisions by right shifts, and multiplications by left shifts, and turn the expression into (value+(1<<N)-1)>>N<<N. Consider x>>N<<N. The (unsigned - i.e., guaranteed zero-filling) right shift discards the bottom N bits, and then the left shift puts the remaining bits back where they were. The net result is to mask off the bottom N bits of x. Another way of putting that would be x&~((1<<N)-1) - hopefully that is clear. In our example, 1<<N is MQ_ALIGNSIZE. So we have x&~(MQ_ALIGNSIZE-1), or, overall, (x+MQ_ALIGNSIZE-1)&~(MQ_ALIGNSIZE-1). I suppose it's possible a compiler could transform this, or the divide-and-multiply version, into the add-then-and version, given enough things that are compile-time constants. But personally if I knew the alignment would be a power of two - which it pretty much always is - I'd just write the code I want. Life is usually simpler that way. |
|