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.