BITAND( ) example
The following program displays Windows version information extracted from the return value of the Windows API function GetVersion( ), which returns a 32-bit integer. The major version number is in the low byte of the low word, and the minor version number is in the high byte of the low word. For example, if the version is 4.10, the major version number is 4 and the minor version number is 10.
As is common practice, macro-functions are created with the #define preprocessor directive to simplify common bit manipulations. There are functions to extract the high word and low word of 32-bit value, and the high byte and low byte of a 16-bit value. The HIBYTE( ) macro-function has some defensive programming in case the parameter is larger than 16 bits. The functions BITAND( ) and BITZRSHIFT( ) are used to extract the values.
#define HIWORD(n) (bitzrshift((n),16))
#define LOWORD(n) (bitand((n),0xFFFF))
#define HIBYTE(n) (bitand(bitzrshift((n),8),0xFF))
#define LOBYTE(n) (bitand((n),0xFF))
if type( "GetVersion" ) # "FP"
extern clong GetVersion( ) kernel32
endif
local v, vMajor, vMinor, vBuild, isNT
v = GetVersion( )
vMajor = LOBYTE( LOWORD( v ))
vMinor = HIBYTE( LOWORD( v ))
isNT = not bitset( v, 31 ) // High bit clear if NT
vBuild = iif( isNT, HIWORD( v ), 0 ) // Ignores Win32s
? iif( isNT, "Windows NT", "Windows 9x" ), ;
"version " + ltrim( str( vMajor )) + "." + str( vMinor, 2, 0, "0" )
if isNT
?? " build", ltrim( str( vBuild ))
endif
To get the low word of a 32-bit integer, a bit mask is created with ones in all 16 low bits. The hexadecimal value of this number is FFFF, as shown in the LOWORD( ) macro-function. Similarly, to get the low byte of a 16-bit integer, the bit mask has ones in the low 8 bits: FF. All the other bits are set to zero when the bitwise AND is performed.
The major version number uses both LOBYTE( ) and LOWORD( ). While this is redundant—LOBYTE( ) alone would work—it’s left in to make the code more symmetical and self-documenting.