153 lines
4.8 KiB
C
153 lines
4.8 KiB
C
#ifndef INCLUDED_C_FLOAT_H
|
|
#define INCLUDED_C_FLOAT_H
|
|
|
|
#ifndef INCLUDED_C_TYPES_H
|
|
#include <c_Types.h>
|
|
#endif /*INCLUDED_C_TYPES_H*/
|
|
|
|
#ifndef INCLUDED_MATH_H
|
|
#define INCLUDED_MATH_H
|
|
#include <math.h>
|
|
#endif /*INCLUDED_MATH_H*/
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
/* */
|
|
|
|
|
|
/* Complete IEEE 754 Standard Width Type Definition Constraints [1] */
|
|
typedef float c_float_t;
|
|
typedef double c_double_t;
|
|
|
|
/* ================================================================================================================== */
|
|
/* 32-bit Single Precision IEEE 754 Bitfields Layout [1] */
|
|
|
|
typedef struct {
|
|
uint32_t sign : 1; /* Bit 31: Sign [1] */
|
|
uint32_t exponent : 8; /* Bits 30-23: Biased Exponent [1] */
|
|
uint32_t mantissa : 23; /* Bits 22-0: Fractional Significand [1] */
|
|
} c_IEEE754_Float_Layout_t;
|
|
|
|
typedef union {
|
|
c_float_t value;
|
|
uint32_t bits;
|
|
c_IEEE754_Float_Layout_t layout;
|
|
} c_Float_Cast_t;
|
|
|
|
/* ================================================================================================================== */
|
|
/* 64-bit Double Precision IEEE 754 Bitfields Layout [1] */
|
|
|
|
typedef struct {
|
|
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
|
uint64_t sign : 1; /* Bit 63 [1] */
|
|
uint64_t exponent : 11; /* Bits 62-52 [1] */
|
|
uint64_t mantissa : 52; /* Bits 51-0 [1] */
|
|
#else
|
|
/* Little Endian Bitfield Ordering Layout Configuration */
|
|
uint64_t mantissa : 52; /* Bits 0-51 [1] */
|
|
uint64_t exponent : 11; /* Bits 52-62 [1] */
|
|
uint64_t sign : 1; /* Bit 63 [1] */
|
|
#endif
|
|
} c_IEEE754_Double_Layout_t;
|
|
|
|
typedef union {
|
|
c_double_t value;
|
|
uint64_t bits;
|
|
c_IEEE754_Double_Layout_t layout;
|
|
} c_Double_Cast_t;
|
|
|
|
/* ================================================================================================================== */
|
|
/* Core Inline Bit-Level Inspection Queries */
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
uint32_t c_Float_ToBits(c_float_t f) {
|
|
c_Float_Cast_t cast;
|
|
cast.value = f;
|
|
return cast.bits;
|
|
}
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
c_float_t c_Float_FromBits(uint32_t bits) {
|
|
c_Float_Cast_t cast;
|
|
cast.bits = bits;
|
|
return cast.value;
|
|
}
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
uint64_t c_Double_ToBits(c_double_t d) {
|
|
c_Double_Cast_t cast;
|
|
cast.value = d;
|
|
return cast.bits;
|
|
}
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
c_double_t c_Double_FromBits(uint64_t bits) {
|
|
c_Double_Cast_t cast;
|
|
cast.bits = bits;
|
|
return cast.value;
|
|
}
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
bool c_Float_IsNaN(c_float_t f) {
|
|
c_Float_Cast_t cast;
|
|
cast.value = f;
|
|
/* IEEE 754 rule: Exponent is all 1s, Mantissa is non-zero [1] */
|
|
return (cast.layout.exponent == 0xFF) && (cast.layout.mantissa != 0);
|
|
}
|
|
|
|
C_STATIC_FORCE_INLINE
|
|
bool c_Double_IsNaN(c_double_t d) {
|
|
c_Double_Cast_t cast;
|
|
cast.value = d;
|
|
/* IEEE 754 rule: Exponent is all 1s (0x7FF), Mantissa is non-zero [1] */
|
|
return (cast.layout.exponent == 0x7FF) && (cast.layout.mantissa != 0);
|
|
}
|
|
|
|
/* ================================================================================================================== */
|
|
/* Generic Callback Comparators (Perfect for Heaps & Sort Engines) */
|
|
|
|
/**
|
|
* @brief Standard generic min-heap comparator for single-precision c_float_t elements.
|
|
* @return < 0 if a < b, 0 if a == b, > 0 if a > b
|
|
*/
|
|
C_STATIC_FORCE_INLINE int c_Compare_FloatMin(const void* a, const void* b, void* args) {
|
|
c_float_t val_a = *(const c_float_t*)a;
|
|
c_float_t val_b = *(const c_float_t*)b;
|
|
(void)args;
|
|
return (val_a > val_b) - (val_a < val_b); /* Highly optimized branchless pattern */
|
|
}
|
|
|
|
/**
|
|
* @brief Standard generic min-heap comparator for double-precision c_double_t elements.
|
|
* @return < 0 if a < b, 0 if a == b, > 0 if a > b
|
|
*/
|
|
C_STATIC_FORCE_INLINE int c_Compare_DoubleMin(const void* a, const void* b, void* args) {
|
|
c_double_t val_a = *(const c_double_t*)a;
|
|
c_double_t val_b = *(const c_double_t*)b;
|
|
(void)args;
|
|
return (val_a > val_b) - (val_a < val_b);
|
|
}
|
|
|
|
/* ================================================================================================================== */
|
|
/* Epsilon Tolerant Mathematical Assertions */
|
|
|
|
/**
|
|
* @brief Checks if two single-precision floats are practically equal under an epsilon boundary.
|
|
*/
|
|
C_STATIC_FORCE_INLINE bool c_Float_AlmostEquals(c_float_t a, c_float_t b, c_float_t epsilon) {
|
|
/* If exactly equal (or both are positive/negative infinity), shortcut out */
|
|
if (a == b) return true;
|
|
return fabs(a - b) <= epsilon;
|
|
}
|
|
|
|
/**
|
|
* @brief Checks if two double-precision floats are practically equal under an epsilon boundary.
|
|
*/
|
|
C_STATIC_FORCE_INLINE bool c_Double_AlmostEquals(c_double_t a, c_double_t b, c_double_t epsilon) {
|
|
if (a == b) return true;
|
|
return fabs(a - b) <= epsilon;
|
|
}
|
|
|
|
#endif /*INCLUDED_C_FLOAT_H*/
|