Make fbits inline, and add PopCount

Floating point bitwise functions are now inline, also implemented a 'PopCount' function, which replicates the '__popcnt' instruction, but does not require the CPU to feature the instruction. This was mainly added as the SDK launcher doesn't check the CPU for SSSe3/popcnt, as it doesn't involve any instruction sets past SSE2.
This commit is contained in:
Kawe Mazidjatari 2023-07-13 00:06:56 +02:00
parent 9e899084e9
commit 0de507713b
4 changed files with 72 additions and 55 deletions

View File

@ -43,7 +43,7 @@ add_sources( SOURCE_GROUP "Vector"
add_sources( SOURCE_GROUP "Math"
"almostequal.cpp"
"fbits.cpp"
"bits.h"
"fbits.h"
"math_pfns.h"
"mathlib.h"

24
r5dev/mathlib/bits.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef MATHLIB_BITS_H
#define MATHLIB_BITS_H
//=============================================================================//
//
// Purpose: bitwise utilities.
//
//=============================================================================//
//-----------------------------------------------------------------------------
// '__popcnt' instruction reimplementation (allows for usage without requiring
// a processor to feature the popcnt instruction, only use for tools that have
// to run on processors that do NOT support popcnt!).
//-----------------------------------------------------------------------------
inline unsigned int PopCount(unsigned long long x)
{
unsigned int count = 0;
while (x) {
x &= x - 1; // Clears the least significant bit set to 1.
count++;
}
return count;
}
#endif // MATHLIB_BITS_H

View File

@ -1,45 +0,0 @@
//=============================================================================//
//
// Purpose: look for NANs, infinities, and underflows.
//
//=============================================================================//
#include "mathlib/fbits.h"
//-----------------------------------------------------------------------------
// This follows the ANSI/IEEE 754-1985 standard
//-----------------------------------------------------------------------------
unsigned long& FloatBits(float& f)
{
return *reinterpret_cast<unsigned long*>(&f);
}
unsigned long const& FloatBits(float const& f)
{
return *reinterpret_cast<unsigned long const*>(&f);
}
float BitsToFloat(unsigned long i)
{
return *reinterpret_cast<float*>(&i);
}
bool IsFinite(float f)
{
return ((FloatBits(f) & 0x7F800000) != 0x7F800000);
}
unsigned long FloatAbsBits(float f)
{
return FloatBits(f) & 0x7FFFFFFF;
}
float FloatMakePositive(float f)
{
return fabsf(f); // was since 2002: BitsToFloat( FloatBits(f) & 0x7FFFFFFF ); fixed in 2010
}
float FloatNegate(float f)
{
return -f; //BitsToFloat( FloatBits(f) ^ 0x80000000 );
}

View File

@ -1,14 +1,52 @@
#pragma once
#ifndef MATHLIB_FBITS_H
#define MATHLIB_FBITS_H
//=============================================================================//
//
// Purpose: look for NANs, infinities, and underflows.
//
//=============================================================================//
unsigned long& FloatBits(float& f);
unsigned long const& FloatBits(float const& f);
float BitsToFloat(unsigned long i);
bool IsFinite(float f);
unsigned long FloatAbsBits(float f);
float FloatMakePositive(float f);
float FloatNegate(float f);
//-----------------------------------------------------------------------------
// This follows the ANSI/IEEE 754-1985 standard
//-----------------------------------------------------------------------------
inline unsigned long& FloatBits(float& f)
{
return *reinterpret_cast<unsigned long*>(&f);
}
#define FLOAT32_NAN_BITS (std::uint32_t)0x7FC00000 // NaN!
inline unsigned long const& FloatBits(float const& f)
{
return *reinterpret_cast<unsigned long const*>(&f);
}
inline float BitsToFloat(unsigned long i)
{
return *reinterpret_cast<float*>(&i);
}
inline bool IsFinite(float f)
{
return ((FloatBits(f) & 0x7F800000) != 0x7F800000);
}
inline unsigned long FloatAbsBits(float f)
{
return FloatBits(f) & 0x7FFFFFFF;
}
inline float FloatMakePositive(float f)
{
return fabsf(f); // was since 2002: BitsToFloat( FloatBits(f) & 0x7FFFFFFF ); fixed in 2010
}
inline float FloatNegate(float f)
{
return -f; //BitsToFloat( FloatBits(f) ^ 0x80000000 );
}
#define FLOAT32_NAN_BITS (unsigned int)0x7FC00000 // NaN!
#define FLOAT32_NAN BitsToFloat( FLOAT32_NAN_BITS )
#define VEC_T_NAN FLOAT32_NAN
#endif // MATHLIB_FBITS_H