From: Sam Moore Date: Mon, 21 Apr 2014 08:47:20 +0000 (+0800) Subject: Ability to define Real as long double X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=c9ce50e17952b0feeec68758444a50302a0aafba;p=ipdf%2Fcode.git Ability to define Real as long double `make DEF=-DREAL=2` to compile using long double as Real Also changed calculatepi to include long double. And also, only actually integrate using Real if it is something other than float, double, long double. --- diff --git a/src/main.cpp b/src/main.cpp index d9f2a7f..9b33453 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,12 @@ #include // Because we can. int main(int argc, char ** argv) { - Debug("Compiled with REAL = %d => \"%s\"", REAL, g_real_name[REAL]); + #ifndef __STDC_IEC_559__ + Warn("__STDC_IEC_559__ not defined. IEEE 754 floating point not fully supported.\n"); + #endif + + + Debug("Compiled with REAL = %d => \"%s\" sizeof(Real) == %d bytes", REAL, g_real_name[REAL], sizeof(Real)); Document doc; srand(time(NULL)); diff --git a/src/real.cpp b/src/real.cpp index 74c774b..7c70a92 100644 --- a/src/real.cpp +++ b/src/real.cpp @@ -5,7 +5,8 @@ namespace IPDF // Maps the REAL to a string const char * g_real_name[] = { "single", - "double" + "double", + "long double" }; } diff --git a/src/real.h b/src/real.h index e6e69bc..0068472 100644 --- a/src/real.h +++ b/src/real.h @@ -5,6 +5,7 @@ #define REAL_SINGLE 0 #define REAL_DOUBLE 1 +#define REAL_LONG_DOUBLE 2 #ifndef REAL #error "REAL was not defined!" @@ -20,6 +21,9 @@ namespace IPDF #elif REAL == REAL_DOUBLE typedef double Real; inline double Float(Real r) {return r;} +#elif REAL == REAL_LONG_DOUBLE + typedef long double Real; + inline long double Float(Real r) {return r;} #else #error "Type of Real unspecified." #endif //REAL diff --git a/src/tests/calculatepi.cpp b/src/tests/calculatepi.cpp index 46348ff..0b7692b 100644 --- a/src/tests/calculatepi.cpp +++ b/src/tests/calculatepi.cpp @@ -4,7 +4,7 @@ * Compares results obtained with float, double, and Real. */ #include "main.h" -#include // for PI +#include #include // for performance measurements /** Function to integrate @@ -19,7 +19,7 @@ template T f(const T & x) /** * Integrate f using the simpson rule */ -template T Integrate(T(*f)(const T&), const T & xmin, const T & xmax, uint64_t intervals) +template T Integrate(T(*f)(const T & ), const T & xmin, const T & xmax, uint64_t intervals) { T sum = 0.0; T dx = (xmax - xmin) / T(intervals); @@ -31,33 +31,47 @@ template T Integrate(T(*f)(const T&), const T & xmin, const T & xmax, odd += f(xmin + dx*T(i)); for (i = 2; i < intervals-1; i+=2) even += f(xmin + dx*T(i)); - sum = (f(xmin) + T(4.0)*odd + T(2.0)*even + f(xmin+T(intervals)*dx))*dx / T(3.0); return sum; } -#define MAX_INTERVALS 1e9 - +#define MAX_INTERVALS 1e10 /** * main */ int main(int argc, char ** argv) { - printf("# intervals\terror_float\tclock_float\terror_double\tclock_double\terror_real\tclock_real\n"); - for (uint64_t intervals = 1; intervals < (uint64_t)(MAX_INTERVALS); intervals*=10) + setbuf(stdout, NULL); + setbuf(stderr, NULL); + long double PI = acosl(-1.0L); + printf("# intervals\terror_float\tclock_float\terror_double\tclock_double\terror_long\tclock_long"); + #if REAL > REAL_LONG_DOUBLE + printf("\terror_real\tclock_real\n"); + #else + printf("\n"); + #endif //REAL + for (uint64_t intervals = 1; intervals < (uint64_t)(MAX_INTERVALS); intervals*=5) { clock_t start = clock(); - float error_float = Integrate(f, 0.0, 1.0, intervals) - (float)(M_PI); + float error_float = Integrate(f, 0.0f, 1.0f, intervals) - float(PI); clock_t clock_float = clock() - start; start = clock(); - double error_double = Integrate(f, 0.0, 1.0, intervals) - (double)(M_PI); + double error_double = Integrate(f, 0.0, 1.0, intervals) - double(PI); clock_t clock_double = clock() - start; start = clock(); - Real error_real = Integrate(f, 0.0, 1.0, intervals) - Real(M_PI); - clock_t clock_real = clock() - start; - - printf("%lu\t%.30f\t%li\t%.30f\t%li\t%.30f\t%li\n", intervals, error_float, clock_float, error_double, clock_double, Float(error_real), clock_real); + long double error_long = Integrate(f,0.0L,1.0L, intervals) - PI; + clock_t clock_long = clock() - start; + + printf("%lu\t%.30f\t%li\t%.30lf\t%li\t%.30llf\t%li", intervals, error_float, clock_float, error_double, clock_double, error_long, clock_long); + + #if REAL > REAL_LONG_DOUBLE + Real error_real = Integrate(f,Real(0.0L), Real(1.0L), intervals) - Real(PI); + clock_t clock_real = clock() - start; + printf("\t%.30lf\t%li\n", error_real, clock_real); + #else + printf("\n"); + #endif } }