/*
 * =====================================================================================
 *
 *       Filename:  Maths.h
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  19/06/2009 09:58:05
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  John Ryland (jryland), jryland@xiaofrog.com
 *        Company:  InvertedLogic
 *      Copyright:  Copyright 2009 InvertedLogic. All rights reserved.
 *
 * =====================================================================================
 */

#include <stdio.h>
#include <limits.h>
#include "Debug.h"


#define bitsof(type)		((sizeof(type) * CHAR_BIT)
#define INTEGER_BITS		(sizeof(int) * CHAR_BIT)
#define INTEGER_MSB			(INTEGER_BITS - 1)


#define ARCH_X86			1
#define ARCH_ARM			0
#define ARCH_PPC			0
#define ARCH_SH3			0



unsigned int integerAbs(int number)
{   
    const int mask = number >> sizeof(int) * CHAR_BIT - 1;
    return (unsigned int)((number + mask) ^ mask);
    //return (unsigned int)((number ^ mask) - mask);
}


// if number < 0 then returns -1 else 0
inline int integerSign0(int number)
{
	int sign;
	// Both methods of calculating the sign of the number are portable, however efficency is different on different architectures
#ifdef ARCH_X86
	sign = -(int)((unsigned int)((int)number >> INTEGER_MSB));
#else
	sign = -(number < 0);  // if number < 0 then -1, else 0.
#endif
	return sign;
}


// if number < 0 then returns -1 else +1
inline int integerSign1(int number)
{
	int sign;
	sign = +1 | (number >> (sizeof(int) * CHAR_BIT - 1));
	return sign;
}


inline unsigned int integerMSB(unsigned int number)
{
	/*
	 // Improved Idea, but not quite working yet, should reduce operation by one cycle
	 unsigned int msb = 0;
	 const int mask[5] = { 0xFFFF0000, 0xFF00FF00, 0xF0F0F0F0, 0xCCCCCCCC, 0xAAAAAAAA };
	 for (int i = 0; i < 5; i++)
		msb += (number & mask[i]) ? (16>>i) : 0;
	 return msb;
	*/	
	// Original code for above but slightly less efficient
	unsigned int msb = 0;
	const int mask[5] = { 65536, 256, 16, 4, 2 };
	for (int i = 0; i < 5; i++)
		msb += (number >= (mask[i] << msb)) ? (16 >> i) : 0;
	return msb;
}

