This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  Some More "Power Of 2" Utility Functions
  Submitted by



For OpenGL texturing, I was in need of some "customized" (read: not really mathematically correct but convenient) "Power Of 2" utility functions, which I'd like to present here. For example, I wanted the functions to return 0 for an input of 0, although it is 20 = 1 != 0, while taking care of the BSR instruction's property of being undefined for an input of 0. Both GNU and MSVC versions are available. These functions are part of my light-weight C++ wrapper for OpenGL called GALE which will be available at my homepage in some time.

//--BEGIN--pot.h--

inline bool isPowerOf2(unsigned x) {
    if (x<1) return false;
    return (x&(x-1))==0;
}

#ifdef __GNUC__ unsigned ceilPowerOf2(unsigned x); #else unsigned __fastcall ceilPowerOf2(unsigned x); #endif

#ifdef __GNUC__ unsigned floorPowerOf2(unsigned x); #else unsigned __fastcall floorPowerOf2(unsigned x); #endif

//--END--pot.h--


//--BEGIN--pot.c--

// Returns the least power of 2 greater than or equal to "x".
// Note that for x=0 and for x>2147483648 this returns 0!
#ifdef __GNUC__
unsigned ceilPowerOf2(unsigned x) {
    unsigned eax;
    __asm__(
        "xor eax,eax\n"
        "dec ecx\n"
        "bsr ecx,ecx\n"
        "cmovz ecx,eax\n"
        "setnz al\n"
        "inc eax\n"
        "shl eax,cl\n"
        : "=a" (eax)
        : "c" (x)
    );
    return eax;
}
#else
__declspec(naked) unsigned __fastcall ceilPowerOf2(unsigned x) {
    __asm {
        xor eax,eax
        dec ecx
        bsr ecx,ecx
        cmovz ecx,eax
        setnz al
        inc eax
        shl eax,cl
        ret
    }
}
#endif

// Returns the greatest power of 2 less than or equal to "x". // Note that for x=0 this returns 0! #ifdef __GNUC__ unsigned floorPowerOf2(unsigned x) { unsigned eax; __asm__( "xor eax,eax\n" "bsr ecx,ecx\n" "setnz al\n" "shl eax,cl\n" : "=a" (eax) : "c" (x) ); return eax; } #else __declspec(naked) unsigned __fastcall floorPowerOf2(unsigned x) { __asm { xor eax,eax bsr ecx,ecx setnz al shl eax,cl ret } } #endif

//--END--pot.c--

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

 

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.