/*
* =====================================================================================
*
* 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;
}