libc: More bad (and a couple good) math functions
This commit is contained in:
parent
ee363c877d
commit
2f59fa9336
24
apps/test-fpclassify.c
Normal file
24
apps/test-fpclassify.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
int main(int argc, char * argv[]) {
|
||||||
|
if (argc < 2) return 1;
|
||||||
|
|
||||||
|
union {
|
||||||
|
double asFloat;
|
||||||
|
uint64_t asInt;
|
||||||
|
} bits;
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "inf")) {
|
||||||
|
bits.asFloat = INFINITY;
|
||||||
|
} else if (!strcmp(argv[1], "nan")) {
|
||||||
|
bits.asFloat = NAN;
|
||||||
|
} else {
|
||||||
|
bits.asFloat = strtod(argv[1], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("0x%016zx %d\n", bits.asInt, fpclassify(bits.asFloat));
|
||||||
|
return 0;
|
||||||
|
}
|
@ -46,4 +46,26 @@ extern double modf(double x, double *iptr);
|
|||||||
|
|
||||||
extern double hypot(double x, double y);
|
extern double hypot(double x, double y);
|
||||||
|
|
||||||
|
extern double trunc(double x);
|
||||||
|
extern double acosh(double x);
|
||||||
|
extern double asinh(double x);
|
||||||
|
extern double atanh(double x);
|
||||||
|
extern double erf(double x);
|
||||||
|
extern double erfc(double x);
|
||||||
|
extern double gamma(double x);
|
||||||
|
extern double lgamma(double x);
|
||||||
|
extern double copysign(double x, double y);
|
||||||
|
extern double remainder(double x, double y);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_NORMAL
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int fpclassify(double x);
|
||||||
|
|
||||||
|
#define isfinite(x) ((fpclassify(x) != FP_NAN && fpclassify(x) != FP_INFINITE))
|
||||||
|
#define isnormal(x) (fpclassify(x) == FP_NORMAL)
|
||||||
|
#define isnan(x) (fpclassify(x) == FP_NAN)
|
||||||
|
#define isinf(x) (fpclassify(x) == FP_INFINITE)
|
||||||
|
|
||||||
_End_C_Header
|
_End_C_Header
|
||||||
|
@ -49,3 +49,28 @@ double expm1(double x) {
|
|||||||
BAD;
|
BAD;
|
||||||
return exp(x) - 1.0;
|
return exp(x) - 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double trunc(double x) {
|
||||||
|
BAD;
|
||||||
|
return (double)(long)x;
|
||||||
|
}
|
||||||
|
|
||||||
|
double acosh(double x) { BAD; return 0.0; }
|
||||||
|
double asinh(double x) { BAD; return 0.0; }
|
||||||
|
double atanh(double x) { BAD; return 0.0; }
|
||||||
|
double erf(double x) { BAD; return 0.0; }
|
||||||
|
double erfc(double x) { BAD; return 0.0; }
|
||||||
|
double gamma(double x) { BAD; return 0.0; }
|
||||||
|
double lgamma(double x){ BAD; return 0.0; }
|
||||||
|
double remainder(double x, double y) { BAD; return 0.0; }
|
||||||
|
|
||||||
|
double copysign(double x, double y) {
|
||||||
|
if (y < 0) {
|
||||||
|
if (x < 0) return x;
|
||||||
|
return -x;
|
||||||
|
} else {
|
||||||
|
if (x < 0) return -x;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -469,3 +469,18 @@ double tanh(double x) {
|
|||||||
return (exp(2.0*x) - 1.0) / (exp(2.0*x) + 1.0);
|
return (exp(2.0*x) - 1.0) / (exp(2.0*x) + 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fpclassify(double x) {
|
||||||
|
union {
|
||||||
|
double asFloat;
|
||||||
|
uint64_t asInt;
|
||||||
|
} bits = {x};
|
||||||
|
uint64_t exponent = (bits.asInt >> 52) & 0x7FF;
|
||||||
|
uint64_t mantissa = (bits.asInt & 0xFffffFFFFffffULL);
|
||||||
|
|
||||||
|
if (exponent == 0x7FF) {
|
||||||
|
return mantissa ? FP_NAN : FP_INFINITE;
|
||||||
|
} else if (exponent == 0) {
|
||||||
|
return mantissa ? FP_SUBNORMAL : FP_ZERO;
|
||||||
|
}
|
||||||
|
return FP_NORMAL;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user