src/core/bitmath_func.cpp
author skidd13
Mon, 03 Dec 2007 09:19:19 +0000
changeset 8005 2318a0547719
parent 8000 2ba28bc428f1
child 8055 49cf1521d591
permissions -rw-r--r--
(svn r11564) -Codechange: Increase the usage of the for_each_bit macro and rename it fitting to the naming style
/* $Id$ */

/** @file bitmath_func.cpp */

#include "../stdafx.h"
#include "bitmath_func.hpp"

const uint8 _ffb_64[64] = {
 0,  0,  1,  0,  2,  0,  1,  0,
 3,  0,  1,  0,  2,  0,  1,  0,
 4,  0,  1,  0,  2,  0,  1,  0,
 3,  0,  1,  0,  2,  0,  1,  0,
 5,  0,  1,  0,  2,  0,  1,  0,
 3,  0,  1,  0,  2,  0,  1,  0,
 4,  0,  1,  0,  2,  0,  1,  0,
 3,  0,  1,  0,  2,  0,  1,  0,
};

/**
 * Search the first set bit in a 32 bit variable.
 *
 * This algorithm is a static implementation of a log
 * conguence search algorithm. It checks the first half
 * if there is a bit set search there further. And this
 * way further. If no bit is set return 0.
 *
 * @param x The value to search
 * @return The position of the first bit set
 */
uint8 FindFirstBit(uint32 x)
{
	if (x == 0) return 0;
	/* The macro FIND_FIRST_BIT is better to use when your x is
	  not more than 128. */

	uint8 pos = 0;

	if ((x & 0x0000ffff) == 0) { x >>= 16; pos += 16; }
	if ((x & 0x000000ff) == 0) { x >>= 8;  pos += 8;  }
	if ((x & 0x0000000f) == 0) { x >>= 4;  pos += 4;  }
	if ((x & 0x00000003) == 0) { x >>= 2;  pos += 2;  }
	if ((x & 0x00000001) == 0) { pos += 1; }

	return pos;
}

/**
 * Search the last set bit in a 32 bit variable.
 *
 * This algorithm is a static implementation of a log
 * conguence search algorithm. It checks the second half
 * if there is a bit set search there further. And this
 * way further. If no bit is set return 0.
 *
 * @param x The value to search
 * @return The position of the last bit set
 */
uint8 FindLastBit(uint32 x)
{
	if (x == 0) return 0;

	uint8 pos = 0;

	if ((x & 0xffff0000) != 0) { x >>= 16; pos += 16; }
	if ((x & 0x0000ff00) != 0) { x >>= 8;  pos += 8;  }
	if ((x & 0x000000f0) != 0) { x >>= 4;  pos += 4;  }
	if ((x & 0x0000000c) != 0) { x >>= 2;  pos += 2;  }
	if ((x & 0x00000002) != 0) { pos += 1; }

	return pos;
}