libc: Add some missing bit-twiddly libm functions
This commit is contained in:
parent
136cfe2b2e
commit
ed40dc436e
@ -69,4 +69,9 @@ extern int fpclassify(double x);
|
|||||||
#define isnan(x) (fpclassify(x) == FP_NAN)
|
#define isnan(x) (fpclassify(x) == FP_NAN)
|
||||||
#define isinf(x) (fpclassify(x) == FP_INFINITE)
|
#define isinf(x) (fpclassify(x) == FP_INFINITE)
|
||||||
|
|
||||||
|
extern float ceilf(float x);
|
||||||
|
extern double round(double x);
|
||||||
|
extern float roundf(float x);
|
||||||
|
extern long lroundf(float x);
|
||||||
|
|
||||||
_End_C_Header
|
_End_C_Header
|
||||||
|
@ -484,3 +484,59 @@ int fpclassify(double x) {
|
|||||||
}
|
}
|
||||||
return FP_NORMAL;
|
return FP_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double ceil(double x) {
|
||||||
|
union {
|
||||||
|
double asFloat;
|
||||||
|
uint64_t asInt;
|
||||||
|
} bits = {x};
|
||||||
|
int64_t exponent = ((bits.asInt >> 52) & 0x7FF) - 0x3ff;
|
||||||
|
uint64_t mantissa = (bits.asInt & 0xFffffFFFFffffULL);
|
||||||
|
if (exponent >= 52 || x == 0) return x;
|
||||||
|
if (exponent <= -1) return (bits.asInt >> 63) ? -0.0 : 1.0;
|
||||||
|
uint64_t mask = (0xfffffFFFFffffULL >> exponent);
|
||||||
|
if (!(mask & mantissa)) return x;
|
||||||
|
if (!(bits.asInt >> 63)) {
|
||||||
|
bits.asInt += mask;
|
||||||
|
}
|
||||||
|
bits.asInt &= ~mask;
|
||||||
|
return bits.asFloat;
|
||||||
|
}
|
||||||
|
|
||||||
|
double round(double x) {
|
||||||
|
union {
|
||||||
|
double asFloat;
|
||||||
|
uint64_t asInt;
|
||||||
|
} bits = {x};
|
||||||
|
int64_t exponent = ((bits.asInt >> 52) & 0x7FF) - 0x3ff;
|
||||||
|
uint64_t mantissa = (bits.asInt & 0xFffffFFFFffffULL);
|
||||||
|
if (exponent >= 52 || x == 0) return x;
|
||||||
|
if (exponent < -1) return (bits.asInt >> 63) ? -0.0 : 0.0;
|
||||||
|
if (exponent == -1) return x >= 0.5 ? 1.0 : (x <= -0.5 ? -1.0 : ((bits.asInt >> 63) ? -0.0 : 0.0));
|
||||||
|
|
||||||
|
uint64_t mask = 0xfffffFFFFffffULL >> exponent;
|
||||||
|
uint64_t a = mantissa & mask;
|
||||||
|
uint64_t b = mantissa & (mask >> 1);
|
||||||
|
|
||||||
|
if (a & ~b) {
|
||||||
|
bits.asInt += mask;
|
||||||
|
bits.asInt &= ~mask;
|
||||||
|
return bits.asFloat;
|
||||||
|
}
|
||||||
|
|
||||||
|
bits.asInt &= ~mask;
|
||||||
|
return bits.asFloat;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ceilf(float x) {
|
||||||
|
return ceil(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
float roundf(float x) {
|
||||||
|
return round(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
long lroundf(float x) {
|
||||||
|
return round(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user