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 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
|
||||
|
@ -49,3 +49,28 @@ double expm1(double x) {
|
||||
BAD;
|
||||
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);
|
||||
}
|
||||
|
||||
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