Integer Numbers C/C++ Macros
This document is part of a collection of macros. For introductory remarks, see the first part (General Purpose Macros).
For a review of macrosyntax rules and related tips and tricks, see Writing Macros.
For the typedefs DWORD, WORD, BYTE and CHAR click here.

CATEGORY 
MACRO 
SIMPLE TESTS 
mIsOdd,
mIsEven
mIsNotMultiple,
mIsMultiple,
mIsModEqu
mIsNot2ToN,
mIs2ToN,
mIsPowerOf2 
CONVERSIONS 
mToggleEndian
mInt2Gray,
mGray2Int

EVEN  ODD PARITY 
mLeEven,
mGeEven,
mLtEven,
mGtEven
mLeOdd,
mGeOdd,
mLtOdd,
mGtOdd
mBitsCount

MODULO CALCULUS 
mModIndex
mModLe,
mModLt,
mModGe,
mModGt

ARITHMETICS 
mSetLe2ToN,
mSetLt2ToN,
mSetGe2ToN,
mSetGt2ToN

Simple tests Code: 
#define mIsOdd(n) ((n)&1)
#define mIsEven(n) (!IsOdd(n))
#define mIsNotMultiple(m,d) ((m)%(d))
#define mIsMultiple(m,d) (!mIsNotMultiple(m,d))
#define mIsModEqu(m,n,d) ((m)%(d)==(n)%(d))
#define mIsNot2ToN(n) ((n)&((n)1))
#define mIs2ToN(n) (!mIsNot2ToN(n))
#define mIsPowerOf2(n) ((n)&& mIs2ToN(n))

 Arguments:
 n, m, d are expressions of an integer type (or ones that can be cast to an integer type).
Additional limitations (where they exist) are listed separately for each case.
 The return value is either true (1) or false (0).
 mIsOdd(n)
 tests whether n is an odd integer value.
 mIsEven(n)
 tests whether n is an even integer value divisible by 2.
 mIsMultiple(m,d), mIsNotMultiple(m,d)
 tests whether m is or is not a multiple of d or, equivalently, whether d is or is not a divisor of m.
The arguments m, d must be either both signed or both unsigned integers. The width of d may be smaller than that of m; it should not be larger, though even that would in many cases work.
 mIsModEqu(m,n,d)
 tests whether the integer values m, n are equal modulo d.
The arguments must be either all signed or all unsigned integers.
 mIsNot2ToN(n), mIs2ToN(n), mIsPowerOf2(n)
 tests whether an unsigned integer (or a signed one, but nonnegative) n is a power of 2.
These very efficient expressions exploit the fact that (n)&((n)1) differs from (n) by the removal of the leastsignificant nonzero binary bit. For example, when (n) = bx01011000 then ((n)1) = bx01010111 and (n)&((n)1) = bx01010000.
When n is a power of 2, it has only one binary bit set and (n)&((n)1) evaluates to zero, while for all other positive numbers the result is nonzero. However, zero evaluates also to 0 because it gets interpreted as 2^W, where W is the width (8, 16, 32,... bits) of the argument. Hence, if 0 is not to be included among the powers of 2, a separate test needs to be done, such as in mIsPowerOf2(n).

Conversions Code: 
#define mSwapBytes(lpData,b1,b2) \
{BYTE b;mSwap(((BYTE*)(lpData))[b1],((BYTE*)(lpData))[b2],b);}
#define mToggleEndian(lpn) \
{DWORD i, B=sizeof(*(lpn))1; for (i=0;i+i<=B;i++) {mSwapBytes(lpn,i,Bi);}}
#define mInt2Gray(n) ((n)^((n)>>1))
#define mGray2Int(g,lvn) {DWORD s=1; (lvn)=(g); while (true) \
{(lvn)^=(lvn)>>s; if (((lvn)>>s)>>s) s+=s; else break;}}

 Arguments:
 lpn is a pointer to an integer of any type (signedunsigned) and width.
n, g are unsigned integer expressions of any width
lvn is a leftvalue integer expressions of any width
 The macro mSwapBytes(lpData,b1,b2) is an auxiliary used just to improve readability of mToggleEndian.
 Though it might be of a more general use, here it is intended locally, not to be called directly by Users.
It swaps the byte with index b1 of the generic structure pointed to by lpData with its byte with index b2.
Naturally, b1 and b2 must be nonnegative integer expressions.
 mToggleEndian(lpn)
 toggles the integer pointed to by lpn (of any type and width) between the littleendian (least significant byte first) and the bigendian (most significant byte first) encoding. In this context, the term toggle means that a littleendian number is replaced by its bigendian version and viceversa (the operation is an inverse of itself). This requires a bytereversal of the Bbytes structure such that the last byte becomes the first one and so on. The conversion is done inplace, i.e., the result replaces the input.
 mInt2Gray(n)
 converts an unsigned integer n to the corresponding binary Gray code. This is a simple expression macro.
 mGray2Int(g,lvn)
 converts a Gray code g to the corresponding unsigned integer and sets the result into lvn.
This is an optimized compositestatement macro using an auxiliary variable.

Even/Odd Parity Code: 
#define mLeEven(n) ((n)&1?(n)1:(n);)
#define mGeEven(n) ((n)&1?(n)+1:(n);)
#define mLtEven(n) ((n)&1?(n)1:(n)2;)
#define mGtEven(n) ((n)&1?(n)+1:(n)+2;)
#define mLeOdd(n) ((n)&1?(n):(n)1;)
#define mGeOdd(n) ((n)&1?(n):(n)+1;)
#define mLtOdd(n) ((n)&1?(n)2:(n)1;)
#define mGtOdd(n) ((n)&1?(n)+2:(n)+1;)
#define mBitsCount(nn,lvc) {DWORD temp=(nn); (lvc)=0; while(temp){(lvc)++;temp&=temp1;}}

 Arguments:
 n is an integer expression (signed or unsigned).
nn is an unsigned integer expression
lvc is a nonnegative integer leftvalue
 Parity has a dual meaning: either even/odd integer value, or even/odd number of binary bits set in a nonnegative integer
Macros pertinent to both cases are covered in this category.

mLeEven(n), mGeEven(n), mLtEven(n),mGtEven(n)
 returns the nearest even value which is respectively ≤, ≥, < or > n.

mLeOdd(lvn), mGeOdd(lvn), mLtOdd(lvn), mGtOdd(lvn)
 returns the nearest odd value which is respectively ≤, ≥, < or > n.

mBitsCount(nn,lvc),
 expression macro setting in the counter lvc the number of binary bits which are set in nn.

Modulo Calculus Code: 
#define mModIndex(n,d) ((n)%(d))
#define mModLe(n,d) ((n)((n)%(d)))
#define mModGe(n,d) ((n)%(d)?(n)+(d)((n)%(d)):(n))
#define mModLt(n,d) ((n)%(d)?(n)((n)%(d)):(n)(d))
#define mModGt(n,d) ((n)+(d)((n)%(d)))

Arguments:
n is an integer expression (or one that can be cast to an integer type).
d is a positive expression of an integer type (or one that can be cast to an integer type).

mModIndex(n,d)
 returns n % d, which is the index of n in modulod calculus.

mModLe(n,d), mModGe(n,d), mModLt(n,d),mModGt(n,d)
 returns the nearest modulod boundary which is ≤, ≥, < or > n.

Arithmetics Code: 
#define mSetLe2ToN(lvn) {while (mIsNot2ToN(lvn)) (lvn)&=(lvn)1;}
#define mSetGe2ToN(lvn) {if (mIsNot2ToN(lvn)) {mSetLe2ToN(lvn);(lvn)<<=1;}}
#define mSetLt2ToN(lvn) {if (mIsNot2ToN(lvn)) mSetLe2ToN(lvn); else (lvn)>>=1;}
#define mSetGt2ToN(lvn) {mSetLe2ToN(lvn);(lvn)<<=1;}

Arguments:
lvn is an unsigned, positive integer leftvalue.

mSetLe2ToN(lvn), mSetGe2ToN(lvn), mSetLt2ToN(lvn), mSetGt2ToN(lvn),
 replaces lvn with the nearest power of 2 which is ≤, ≥, < or > lvn

