mirror of https://github.com/flysand7/ciabatta.git
math generic exp function
This commit is contained in:
parent
9df9a57b67
commit
cca63462fc
2
bake.cmd
2
bake.cmd
|
@ -51,5 +51,5 @@ del build\*.obj
|
||||||
|
|
||||||
:skip_crt_compilation
|
:skip_crt_compilation
|
||||||
echo Compiling test..
|
echo Compiling test..
|
||||||
clang -fno-builtin test\test_wctype.c ciabatta.lib -std=c11 -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS%
|
clang -fno-builtin test\test_math.c ciabatta.lib -std=c11 -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS%
|
||||||
::cl test\test_math.c /Iinc -D_CRT_SECURE_NO_WARNINGS /Z7 /link ciabatta.lib kernel32.lib user32.lib shell32.lib -nostdlib -nodefaultlibs
|
::cl test\test_math.c /Iinc -D_CRT_SECURE_NO_WARNINGS /Z7 /link ciabatta.lib kernel32.lib user32.lib shell32.lib -nostdlib -nodefaultlibs
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <float.h>
|
|
||||||
#include <fenv.h>
|
|
||||||
|
|
||||||
#define rln2 1.4426950408889634073599246810018921374266459541529859341354494069
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <fenv.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define ln2 0.69314718055994530941723212145817
|
||||||
|
|
||||||
|
#define ftype float
|
||||||
|
#define suffix(name) name ## f
|
||||||
|
#include "generic.h"
|
||||||
|
#undef ftype
|
||||||
|
#undef suffix
|
||||||
|
|
||||||
|
#define ftype double
|
||||||
|
#define suffix(name) name
|
||||||
|
#include "generic.h"
|
||||||
|
#undef ftype
|
||||||
|
#undef suffix
|
||||||
|
|
||||||
|
#define ftype long double
|
||||||
|
#define suffix(name) name ## l
|
||||||
|
#include "generic.h"
|
||||||
|
#undef ftype
|
||||||
|
#undef suffix
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
ftype suffix(exp)(ftype x) {
|
||||||
|
if(isnan(x)) return NAN;
|
||||||
|
if(x > 0 && isinf(x)) return +INFINITY;
|
||||||
|
if(x < 0 && isinf(x)) return +0.0;
|
||||||
|
if(x == 0) return 1.0;
|
||||||
|
if(x > 709.8) {
|
||||||
|
#if math_errhandling & MATH_ERREXCEPT
|
||||||
|
feraiseexcept(FE_OVERFLOW);
|
||||||
|
#endif
|
||||||
|
#if math_errhandling & MATH_ERRNO
|
||||||
|
errno = ERANGE;
|
||||||
|
#endif
|
||||||
|
return +INFINITY;
|
||||||
|
}
|
||||||
|
if(x < -708.4) {
|
||||||
|
#if math_errhandling & MATH_ERREXCEPT
|
||||||
|
feraiseexcept(FE_OVERFLOW);
|
||||||
|
#endif
|
||||||
|
#if math_errhandling & MATH_ERRNO
|
||||||
|
errno = ERANGE;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ftype e = 1.0;
|
||||||
|
ftype xp = 1.0;
|
||||||
|
ftype f = 1;
|
||||||
|
for(uint64_t i = 1; i != 10; ++i) {
|
||||||
|
f *= i;
|
||||||
|
xp *= x;
|
||||||
|
e += xp / f;
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
ftype suffix(exp2)(ftype x) {
|
||||||
|
return suffix(exp)(x * ln2);
|
||||||
|
}
|
||||||
|
|
||||||
|
ftype suffix(expm1)(ftype x) {
|
||||||
|
return suffix(exp)(x) - 1.0;
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
// This stuff is kinda related to what's going on in this file, so I left it
|
// This stuff is kinda related to what's going on in this file, so I left it
|
||||||
// in a rather ugly manner here.
|
// in a rather ugly manner here.
|
||||||
|
|
|
@ -20,7 +20,7 @@ typedef double double_t;
|
||||||
#define MATH_ERRNO 1
|
#define MATH_ERRNO 1
|
||||||
#define MATH_ERREXCEPT 2
|
#define MATH_ERREXCEPT 2
|
||||||
|
|
||||||
#define math_errhandling MATH_ERRNO
|
#define math_errhandling MATH_ERRNO | MATH_ERREXCEPT
|
||||||
|
|
||||||
// Classification
|
// Classification
|
||||||
#define FP_INFINITE 0
|
#define FP_INFINITE 0
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <fenv.h>
|
#include <fenv.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
const char *show_classification(double x) {
|
const char *show_classification(double x) {
|
||||||
switch(fpclassify(x)) {
|
switch(fpclassify(x)) {
|
||||||
|
@ -103,5 +104,18 @@ int main() {
|
||||||
printf("lround(LONG_MAX+1.5) = %ld\n", lround(LONG_MAX+1.5));
|
printf("lround(LONG_MAX+1.5) = %ld\n", lround(LONG_MAX+1.5));
|
||||||
if(fetestexcept(FE_INVALID)) printf(" FE_INVALID was raised\n");
|
if(fetestexcept(FE_INVALID)) printf(" FE_INVALID was raised\n");
|
||||||
|
|
||||||
|
printf("\n\n=== exp === \n");
|
||||||
|
printf("exp(1) = %f\n", exp(1));
|
||||||
|
printf("FV of $100, continuously compounded at 3%% for 1 year = %f\n",
|
||||||
|
100*exp(0.03));
|
||||||
|
// special values
|
||||||
|
printf("exp(-0) = %f\n", exp(-0.0));
|
||||||
|
printf("exp(-Inf) = %f\n", exp(-INFINITY));
|
||||||
|
//error handling
|
||||||
|
errno = 0; feclearexcept(FE_ALL_EXCEPT);
|
||||||
|
printf("exp(710) = %f\n", exp(710));
|
||||||
|
if(errno == ERANGE) printf(" errno == ERANGE\n");
|
||||||
|
if(fetestexcept(FE_OVERFLOW)) printf(" FE_OVERFLOW raised\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue