#ifndef INCLUDED_C_FLOAT_H #define INCLUDED_C_FLOAT_H #ifndef INCLUDED_FLOAT_H #define INCLUDED_FLOAT_H #include #endif /*INCLUDED_FLOAT_H*/ #ifndef INCLUDED_STDINT_H #define INCLUDED_STDINT_H #include #endif /*INCLUDED_STDINT_H*/ #ifndef INCLUDED_MATH_H #define INCLUDED_MATH_H #include #endif /*INCLUDED_MATH_H*/ #ifndef INCLUDED_C_COMPILER_H #include #endif /*INCLUDED_C_COMPILER_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ typedef union { float f; uint32_t u; struct { uint32_t sign: 1; uint32_t exponent: 8; uint32_t mantissa: 23; }IEEE754; }c_Float_t; typedef union { double d; uint64_t u; struct { uint64_t sign: 1; uint64_t exponent: 11; uint64_t mantissa: 52; }; }c_Double_t; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ C_STATIC_FORCE_INLINE int c_float_is_eq(const float a, const float b) { return fabsf(a - b) < FLT_EPSILON; } C_STATIC_FORCE_INLINE int c_float_is_gt(const float a, const float b) { return (a - b) > FLT_EPSILON; } C_STATIC_FORCE_INLINE int c_float_is_ge(const float a, const float b) { return (a - b) >= -FLT_EPSILON; } C_STATIC_FORCE_INLINE int c_float_cmp_safe(const float fa, const float fb) { int nan_a = isnan(fa); int nan_b = isnan(fb); if (C_UNLIKELY(nan_a || nan_b)) { if (nan_a && nan_b) return 0; if (nan_a) return 1; return -1; } if (fa < fb) return -1; if (fa > fb) return 1; return 0; } /* ------------------------------------------------------------------------------------------------------------------ */ /* double */ C_STATIC_FORCE_INLINE int c_double_is_eq(const double a, const double b) { return fabs(a - b) < DBL_EPSILON; } C_STATIC_FORCE_INLINE int c_double_is_gt(const double a, const double b) { return (a - b) > DBL_EPSILON; } C_STATIC_FORCE_INLINE int c_double_is_ge(const double a, const double b) { return (a - b) >= -DBL_EPSILON; } C_STATIC_FORCE_INLINE int c_double_cmp_safe(const double da, const double db) { int nan_a = isnan(da); int nan_b = isnan(db); /* --- 1. 处理 NaN 的极端分支 --- */ /* 采用 C_UNLIKELY 优化,因为大部分待排数据中 NaN 是极少数,提示 CPU 预读正常分支 */ if (C_UNLIKELY(nan_a || nan_b)) { if (nan_a && nan_b) return 0; /* 两个都是 NaN,视为相等 */ if (nan_a) return 1; /* a 是 NaN,b 是正常数,视为 a > b(NaN排到最后) */ return -1; /* a 是正常数,b 是 NaN,视为 a < b */ } /* --- 2. 正常数值的三向比较分支 --- */ if (da < db) return -1; if (da > db) return 1; return 0; } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ C_STATIC_FORCE_INLINE int c_float_ptr_cmp_safe(const void* a, const void* b) { float fa = *(const float*)a; float fb = *(const float*)b; int nan_a = isnan(fa); int nan_b = isnan(fb); if (C_UNLIKELY(nan_a || nan_b)) { if (nan_a && nan_b) return 0; if (nan_a) return 1; return -1; } if (fa < fb) return -1; if (fa > fb) return 1; return 0; } C_STATIC_FORCE_INLINE int c_double_ptr_cmp_safe(const void* a, const void* b) { double da = *(const double*)a; double db = *(const double*)b; int nan_a = isnan(da); int nan_b = isnan(db); /* --- 1. 处理 NaN 的极端分支 --- */ /* 采用 C_UNLIKELY 优化,因为大部分待排数据中 NaN 是极少数,提示 CPU 预读正常分支 */ if (C_UNLIKELY(nan_a || nan_b)) { if (nan_a && nan_b) return 0; /* 两个都是 NaN,视为相等 */ if (nan_a) return 1; /* a 是 NaN,b 是正常数,视为 a > b(NaN排到最后) */ return -1; /* a 是正常数,b 是 NaN,视为 a < b */ } /* --- 2. 正常数值的三向比较分支 --- */ if (da < db) return -1; if (da > db) return 1; return 0; } #endif /*INCLUDED_C_FLOAT_H*/