Some rough floating point macros!

This commit is contained in:
Kat R. 2022-05-28 11:15:26 -05:00
parent 2ada975628
commit ef5fd0562f
4 changed files with 173 additions and 3 deletions

91
math/__fpclassify.c Normal file
View file

@ -0,0 +1,91 @@
#include <math.h>
int __fpclassifyd(double x) {
union fp {
double d;
long i;
} f;
f.d = x;
if((f.i & 0x7fffffffffffffff) == 0) {
return FP_ZERO;
}
if((f.i & 0x7ff0000000000000) == 0 && (f.i & 0xfffffffffffff != 0)) {
return FP_SUBNORMAL;
}
if((f.i & 0x7ff0000000000000) == 0x7ff0000000000000) {
if((f.i & 0xfffffffffffff) == 0) {
return FP_INFINITE;
}
else {
return FP_NAN;
}
}
return FP_NORMAL;
}
int __fpclassifyf(float x) {
union fp {
float f;
int i;
} f;
f.f = x;
if((f.i & 0x7fffffff) == 0) {
return FP_ZERO;
}
if((f.i & 0x7f800000) == 0 && (f.i & 0x7fffff != 0)) {
return FP_SUBNORMAL;
}
if((f.i & 0x7f800000) == 0x7f800000) {
if((f.i & 0x7fffff) == 0) {
return FP_INFINITE;
}
else {
return FP_NAN;
}
}
return FP_NORMAL;
}
/*
This is based off IEEE 754 binary128 (A.K.A quad-precision) FP numbers.
Apparently, C tends to actually use 80-bit extended precision, which would
mean this doesn't actually work. We'll worry about that later, though.
-Kat
*/
int __fpclassifyl(long double x) {
union fp {
long double d;
long long i;
} f;
f.d = x;
if((f.i & 0x7fffffffffffffffffffffffffffffff) == 0) {
return FP_ZERO;
}
if((f.i & 0x7fff0000000000000000000000000000) == 0 && (f.i & 0xffffffffffffffffffffffffffff != 0)) {
return FP_SUBNORMAL;
}
if((f.i & 0x7fff0000000000000000000000000000) == 0x7fff0000000000000000000000000000) {
if((f.i & 0xffffffffffffffffffffffffffff) == 0) {
return FP_INFINITE;
}
else {
return FP_NAN;
}
}
return FP_NORMAL;
}

34
math/__signbit.c Normal file
View file

@ -0,0 +1,34 @@
#include <math.h>
int __signbitd(double x) {
union fp {
double d;
long i;
} f;
f.d = x;
return f.i & 0x8000000000000000;
}
int __signbitf(float x) {
union fp {
float f;
int i;
} f;
f.f = x;
return f.i & 0x80000000;
}
int __signbitl(long double x) {
union fp {
long double d;
long long i;
} f;
f.d = x;
return f.i & 0x80000000000000000000000000000000;
}