20260829 Redesign
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
#ifndef INCLUDED_C_FLOAT_H
|
||||
#define INCLUDED_C_FLOAT_H
|
||||
|
||||
#ifndef INCLUDED_FLOAT_H
|
||||
#define INCLUDED_FLOAT_H
|
||||
#include <float.h>
|
||||
#endif /*INCLUDED_FLOAT_H*/
|
||||
|
||||
#ifndef INCLUDED_STDINT_H
|
||||
#define INCLUDED_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif /*INCLUDED_STDINT_H*/
|
||||
|
||||
#ifndef INCLUDED_MATH_H
|
||||
#define INCLUDED_MATH_H
|
||||
#include <math.h>
|
||||
#endif /*INCLUDED_MATH_H*/
|
||||
|
||||
#ifndef INCLUDED_C_COMPILER_H
|
||||
#include <c_Compiler.h>
|
||||
#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*/
|
||||
Reference in New Issue
Block a user