libc: More bad (and a couple good) math functions

This commit is contained in:
K. Lange 2021-12-06 18:47:55 +09:00
parent ee363c877d
commit 2f59fa9336
4 changed files with 86 additions and 0 deletions

24
apps/test-fpclassify.c Normal file
View 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;
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}