Added uint log2 and deprecate GTX_unsigned_int

This commit is contained in:
Christophe Riccio 2011-10-11 15:31:16 +01:00
parent e3da53946e
commit 09ee14ad4c
8 changed files with 235 additions and 81 deletions

View File

@ -42,6 +42,7 @@ namespace detail
detail::type<genFIType>::is_float ||
detail::type<genFIType>::is_int, "'abs' only accept floating-point and integer inputs");
return x >= genFIType(0) ? x : -x;
// TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff;
}
};

View File

@ -124,7 +124,6 @@
#include "./gtx/transform.hpp"
#include "./gtx/transform2.hpp"
#include "./gtx/ulp.hpp"
#include "./gtx/unsigned_int.hpp"
#include "./gtx/vec1.hpp"
#include "./gtx/vector_access.hpp"
#include "./gtx/vector_angle.hpp"

View File

@ -58,6 +58,10 @@ namespace glm
//! From GLM_GTX_integer extension.
int sqrt(int x);
//! Returns the log2 of x.
//! From GLM_GTX_integer extension.
unsigned int log2(unsigned int x);
//! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
//! From GLM_GTX_integer extension.
int mod(int x, int y);
@ -67,6 +71,22 @@ namespace glm
template <typename genType>
genType factorial(genType const & x);
//! 32bit signed integer.
//! From GLM_GTX_unsigned_int extension.
typedef signed int sint;
//! Returns x raised to the y power.
//! From GLM_GTX_unsigned_int extension.
uint pow(uint x, uint y);
//! Returns the positive square root of x.
//! From GLM_GTX_unsigned_int extension.
uint sqrt(uint x);
//! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
//! From GLM_GTX_unsigned_int extension.
uint mod(uint x, uint y);
/// @}
}//namespace glm

View File

@ -37,6 +37,52 @@ GLM_FUNC_QUALIFIER int sqrt(int x)
return CurrentAnswer;
}
// Henry Gordon Dietz: http://aggregate.org/MAGIC/
namespace detail
{
GLM_FUNC_QUALIFIER unsigned int ones32(unsigned int x)
{
/* 32-bit recursive reduction using SWAR...
but first step is mapping 2-bit values
into sum of 2 1-bit values in sneaky way
*/
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return(x & 0x0000003f);
}
}//namespace detail
/*
// Henry Gordon Dietz: http://aggregate.org/MAGIC/
GLM_FUNC_QUALIFIER unsigned int log2(unsigned int x)
{
register int y = (x & (x - 1));
y |= -y;
y >>= (WORDBITS - 1);
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return detail::ones32(x) - 1 - y;
}
*/
// Henry Gordon Dietz: http://aggregate.org/MAGIC/
unsigned int log2(unsigned int x)
{
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return(detail::ones32(x) - 1);
}
// mod
GLM_FUNC_QUALIFIER int mod(int x, int y)
{
@ -84,4 +130,33 @@ GLM_FUNC_QUALIFIER detail::tvec4<valType> factorial(
factorial(x.w));
}
GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
{
uint result = x;
for(uint i = 1; i < y; ++i)
result *= x;
return result;
}
GLM_FUNC_QUALIFIER uint sqrt(uint x)
{
if(x <= 1) return x;
uint NextTrial = x >> 1;
uint CurrentAnswer;
do
{
CurrentAnswer = NextTrial;
NextTrial = (NextTrial + x / NextTrial) >> 1;
} while(NextTrial < CurrentAnswer);
return CurrentAnswer;
}
GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
{
return x - y * (x / y);
}
}//namespace glm

View File

@ -19,58 +19,8 @@
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref gtx_unsigned_int
/// @file glm/gtx/unsigned_int.hpp
/// @date 2005-12-24 / 2011-06-07
/// @author Christophe Riccio
///
/// @see core (dependence)
/// @see gtx_integer (dependence)
///
/// @defgroup gtx_unsigned_int GLM_GTX_unsigned_int: Unsigned int
/// @ingroup gtx
///
/// @brief Add support for unsigned integer for core functions
///
/// <glm/gtx/unsigned_int.hpp> need to be included to use these functionalities.
///////////////////////////////////////////////////////////////////////////////////
#ifndef GLM_GTX_unsigned_int
#define GLM_GTX_unsigned_int GLM_VERSION
// Dependency:
#include "../glm.hpp"
#include "../gtx/integer.hpp"
#if(defined(GLM_MESSAGES) && !defined(glm_ext))
# pragma message("GLM: GLM_GTX_unsigned_int extension included")
#if(defined(GLM_MESSAGES))
# pragma message("GLM: GLM_GTX_unsigned_int extension is deprecated, include GLM_GTX_integer instead")
#endif
namespace glm
{
/// @addtogroup gtx_unsigned_int
/// @{
//! 32bit signed integer.
//! From GLM_GTX_unsigned_int extension.
typedef signed int sint;
//! Returns x raised to the y power.
//! From GLM_GTX_unsigned_int extension.
uint pow(uint x, uint y);
//! Returns the positive square root of x.
//! From GLM_GTX_unsigned_int extension.
uint sqrt(uint x);
//! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
//! From GLM_GTX_unsigned_int extension.
uint mod(uint x, uint y);
/// @}
}//namespace glm
#include "unsigned_int.inl"
#endif//GLM_GTX_unsigned_int

View File

@ -9,33 +9,5 @@
namespace glm{
GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
{
uint result = x;
for(uint i = 1; i < y; ++i)
result *= x;
return result;
}
GLM_FUNC_QUALIFIER uint sqrt(uint x)
{
if(x <= 1) return x;
uint NextTrial = x >> 1;
uint CurrentAnswer;
do
{
CurrentAnswer = NextTrial;
NextTrial = (NextTrial + x / NextTrial) >> 1;
} while(NextTrial < CurrentAnswer);
return CurrentAnswer;
}
GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
{
return x - y * (x / y);
}
}//namespace glm

View File

@ -1,4 +1,5 @@
glmCreateTestGTC(gtx_bit)
glmCreateTestGTC(gtx_integer)
glmCreateTestGTC(gtx_noise)
glmCreateTestGTC(gtx_quaternion)
glmCreateTestGTC(gtx_random)

136
test/gtx/gtx_integer.cpp Normal file
View File

@ -0,0 +1,136 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2010-09-16
// Updated : 2010-09-16
// Licence : This source is under MIT licence
// File : test/gtx/bit.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <glm/glm.hpp>
#include <glm/gtx/number_precision.hpp>
#include <glm/gtx/bit.hpp>
#include <iostream>
enum result
{
SUCCESS,
FAIL,
ASSERT,
STATIC_ASSERT
};
namespace extractField
{
template <typename genType, typename sizeType>
struct type
{
genType Value;
sizeType BitFirst;
sizeType BitCount;
genType Return;
result Result;
};
typedef type<glm::uint64, glm::uint> typeU64;
typeU64 const Data64[] =
{
{0xffffffffffffffff, 8, 0, 0x0000000000000000, SUCCESS},
{0x0000000000000000, 0,64, 0x0000000000000000, SUCCESS},
{0xffffffffffffffff, 0,64, 0xffffffffffffffff, SUCCESS},
{0x0f0f0f0f0f0f0f0f, 0,64, 0x0f0f0f0f0f0f0f0f, SUCCESS},
{0x0000000000000000, 8, 0, 0x0000000000000000, SUCCESS},
{0x8000000000000000,63, 1, 0x0000000000000001, SUCCESS},
{0x7fffffffffffffff,63, 1, 0x0000000000000000, SUCCESS},
{0x0000000000000300, 8, 8, 0x0000000000000003, SUCCESS},
{0x000000000000ff00, 8, 8, 0x00000000000000ff, SUCCESS},
{0xfffffffffffffff0, 0, 5, 0x0000000000000010, SUCCESS},
{0x00000000000000ff, 1, 3, 0x0000000000000007, SUCCESS},
{0x00000000000000ff, 0, 3, 0x0000000000000007, SUCCESS},
{0x0000000000000000, 0, 2, 0x0000000000000000, SUCCESS},
{0xffffffffffffffff, 0, 8, 0x00000000000000ff, SUCCESS},
{0xffffffff00000000,32,32, 0x00000000ffffffff, SUCCESS},
{0xfffffffffffffff0, 0, 8, 0x0000000000000000, FAIL},
{0xffffffffffffffff,32,32, 0x0000000000000000, FAIL},
//{0xffffffffffffffff,64, 1, 0x0000000000000000, ASSERT}, // Throw an assert
//{0xffffffffffffffff, 0,65, 0x0000000000000000, ASSERT}, // Throw an assert
//{0xffffffffffffffff,33,32, 0x0000000000000000, ASSERT}, // Throw an assert
};
int test()
{
glm::uint32 count = sizeof(Data64) / sizeof(typeU64);
for(glm::uint32 i = 0; i < count; ++i)
{
glm::uint64 Return = glm::extractField(
Data64[i].Value,
Data64[i].BitFirst,
Data64[i].BitCount);
bool Compare = Data64[i].Return == Return;
if(Data64[i].Result == SUCCESS && Compare)
continue;
else if(Data64[i].Result == FAIL && !Compare)
continue;
std::cout << "glm::extractfield test fail on test " << i << std::endl;
return 1;
}
return 0;
}
}//extractField
namespace bitRevert
{
template <typename genType>
struct type
{
genType Value;
genType Return;
result Result;
};
typedef type<glm::uint64> typeU64;
typeU64 const Data64[] =
{
{0xffffffffffffffff, 0xffffffffffffffff, SUCCESS},
{0x0000000000000000, 0x0000000000000000, SUCCESS},
{0xf000000000000000, 0x000000000000000f, SUCCESS},
};
int test()
{
glm::uint32 count = sizeof(Data64) / sizeof(typeU64);
for(glm::uint32 i = 0; i < count; ++i)
{
glm::uint64 Return = glm::bitRevert(
Data64[i].Value);
bool Compare = Data64[i].Return == Return;
if(Data64[i].Result == SUCCESS && Compare)
continue;
else if(Data64[i].Result == FAIL && !Compare)
continue;
std::cout << "glm::extractfield test fail on test " << i << std::endl;
return 1;
}
return 0;
}
}//bitRevert
int main()
{
int Error = 0;
Error += ::extractField::test();
Error += ::bitRevert::test();
return Error;
}