| @@ -60,6 +60,7 @@ test/benchsuite | |||||
| test/quad | test/quad | ||||
| test/sandbox | test/sandbox | ||||
| test/math/pi | test/math/pi | ||||
| test/math/poly | |||||
| test/math/remez | test/math/remez | ||||
| tools/make-font | tools/make-font | ||||
| # Our data | # Our data | ||||
| @@ -3,19 +3,25 @@ AM_CPPFLAGS = -I$(top_srcdir)/src | |||||
| all-local: $(noinst_PROGRAMS) | all-local: $(noinst_PROGRAMS) | ||||
| test x$(MAKE_FSELF) = xno || make_fself pi$(EXEEXT) pi.self | test x$(MAKE_FSELF) = xno || make_fself pi$(EXEEXT) pi.self | ||||
| test x$(MAKE_FSELF) = xno || make_fself poly$(EXEEXT) pi.self | |||||
| test x$(MAKE_FSELF) = xno || make_fself remez$(EXEEXT) remez.self | test x$(MAKE_FSELF) = xno || make_fself remez$(EXEEXT) remez.self | ||||
| CLEANFILES = $(noinst_PROGRAMS:%$(EXEEXT)=%.self) \ | CLEANFILES = $(noinst_PROGRAMS:%$(EXEEXT)=%.self) \ | ||||
| $(noinst_PROGRAMS:%$(EXEEXT)=%.elf) \ | $(noinst_PROGRAMS:%$(EXEEXT)=%.elf) \ | ||||
| $(noinst_PROGRAMS:%$(EXEEXT)=%.exe) | $(noinst_PROGRAMS:%$(EXEEXT)=%.exe) | ||||
| noinst_PROGRAMS = pi remez | |||||
| noinst_PROGRAMS = pi poly remez | |||||
| pi_SOURCES = pi.cpp | pi_SOURCES = pi.cpp | ||||
| pi_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ | pi_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ | ||||
| pi_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ | pi_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ | ||||
| pi_DEPENDENCIES = $(top_builddir)/src/liblol.a | pi_DEPENDENCIES = $(top_builddir)/src/liblol.a | ||||
| poly_SOURCES = poly.cpp | |||||
| poly_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ | |||||
| poly_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ | |||||
| poly_DEPENDENCIES = $(top_builddir)/src/liblol.a | |||||
| remez_SOURCES = remez.cpp remez-matrix.h remez-solver.h | remez_SOURCES = remez.cpp remez-matrix.h remez-solver.h | ||||
| remez_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ | remez_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ | ||||
| remez_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ | remez_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ | ||||
| @@ -0,0 +1,99 @@ | |||||
| // | |||||
| // Lol Engine - Sample math program: chek trigonometric functions | |||||
| // | |||||
| // Copyright: (c) 2005-2011 Sam Hocevar <sam@hocevar.net> | |||||
| // This program is free software; you can redistribute it and/or | |||||
| // modify it under the terms of the Do What The Fuck You Want To | |||||
| // Public License, Version 2, as published by Sam Hocevar. See | |||||
| // http://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||||
| // | |||||
| #if defined HAVE_CONFIG_H | |||||
| # include "config.h" | |||||
| #endif | |||||
| #include <cstdio> | |||||
| #include "core.h" | |||||
| using namespace lol; | |||||
| using namespace std; | |||||
| static float adjust(float f, int i) | |||||
| { | |||||
| union { float f; uint32_t x; } u = { f }; | |||||
| u.x += i; | |||||
| return u.f; | |||||
| } | |||||
| static void inspect(float f) | |||||
| { | |||||
| union { float f; uint32_t x; } u = { f }; | |||||
| printf("%08x %g -- ", u.x, u.f); | |||||
| int i = (u.x & 0x7fffffu) | 0x800000u; | |||||
| int j = 23 - ((u.x >> 23) & 0xff) + ((1 << 7) - 1); | |||||
| if (u.f <= 0) | |||||
| i = -i; | |||||
| printf("%i / 2^%i = %g\n", i, j, (float)i / (1LLu << j)); | |||||
| } | |||||
| static float const a0 = adjust(1.0, 0); | |||||
| static float const a1 = adjust(-0.1666666666372165, 0); | |||||
| static float const a2 = adjust(0.008333332748323419, 0); | |||||
| static float const a3 = adjust(-0.0001984108245332497, 0); | |||||
| static float const a4 = adjust(2.753619853326498e-06, 0); | |||||
| static float const a5 = adjust(-2.407483949485896e-08, 0); | |||||
| static float floatsin(float f) | |||||
| { | |||||
| //return lol_sin(f); | |||||
| //#define float double | |||||
| //static float const k = (float)real::R_2_PI; | |||||
| //f *= k; | |||||
| float f2 = f * f; | |||||
| float f4 = f2 * f2; | |||||
| //return f * (a0 + f4 * (a2 + f4 * a4) + f2 * (a1 + f4 * (a3 + f4 * a5))); | |||||
| //return f * (a0 + f2 * (a1 + f2 * (a2 + f2 * (a3 + f2 * (a4 + f2 * a5))))); | |||||
| return f * (a0 + a1 * f2 + a2 * f2 * f2 + a3 * f2 * f2 * f2 + a4 * f2 * f2 * f2 * f2 + a5 * f2 * f2 * f2 * f2 * f2); | |||||
| #undef float | |||||
| } | |||||
| int main(void) | |||||
| { | |||||
| int error[5] = { 0 }; | |||||
| inspect(a0); | |||||
| inspect(a1); | |||||
| inspect(a2); | |||||
| inspect(a3); | |||||
| inspect(a4); | |||||
| inspect(a5); | |||||
| for (float f = (float)real::R_PI_2; f > 1e-30; f = adjust(f, -1)) | |||||
| { | |||||
| union { float f; uint32_t x; } s1 = { sinf(f) }; | |||||
| union { float f; uint32_t x; } s2 = { floatsin(f) }; | |||||
| int e = abs((int)(s1.x - s2.x)); | |||||
| switch (e) | |||||
| { | |||||
| case 0: | |||||
| case 1: | |||||
| case 2: | |||||
| case 3: | |||||
| error[e]++; | |||||
| break; | |||||
| default: | |||||
| if (fabs((double)s1.f - (double)s2.f) > 1e-10 * fabs(s1.f)) | |||||
| printf("%16.14g: %16.14g %16.14g %08x %08x\n", f, s1.f, s2.f, s1.x, s2.x); | |||||
| error[4]++; | |||||
| break; | |||||
| } | |||||
| } | |||||
| printf("exact: %i off by 1: %i by 2: %i by 3: %i error: %i\n", | |||||
| error[0], error[1], error[2], error[3], error[4]); | |||||
| return EXIT_SUCCESS; | |||||
| } | |||||
| @@ -26,10 +26,14 @@ using namespace std; | |||||
| /* The function we want to approximate */ | /* The function we want to approximate */ | ||||
| static real myfun(real const &x) | static real myfun(real const &x) | ||||
| { | { | ||||
| static real const a0 = real::R_1; | |||||
| static real const a1 = real(-11184811) >> 26; | |||||
| static real const b1 = real(-1) / real(6); | |||||
| static real const b2 = real(1) / real(120); | |||||
| real y = sqrt(x); | real y = sqrt(x); | ||||
| if (!y) | if (!y) | ||||
| return real::R_PI_2; | |||||
| return sin(real::R_PI_2 * y) / y; | |||||
| return b2; | |||||
| return ((sin(y) / y - a0) / x - a1) / x; | |||||
| } | } | ||||
| static real myerr(real const &x) | static real myerr(real const &x) | ||||
| @@ -39,8 +43,9 @@ static real myerr(real const &x) | |||||
| int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
| { | { | ||||
| RemezSolver<4> solver; | |||||
| solver.Run(0, 1, myfun, myfun, 15); | |||||
| RemezSolver<3> solver; | |||||
| //solver.Run(0, 1, myfun, myfun, 15); | |||||
| solver.Run(0, real::R_PI * real::R_PI >> 2, myfun, myfun, 15); | |||||
| //solver.Run(-1, 1, myfun, myfun, 15); | //solver.Run(-1, 1, myfun, myfun, 15); | ||||
| //solver.Run(0, real::R_PI * real::R_PI >> 4, myfun, myfun, 15); | //solver.Run(0, real::R_PI * real::R_PI >> 4, myfun, myfun, 15); | ||||