Ability to define Real as long double
authorSam Moore <matches@ucc.asn.au>
Mon, 21 Apr 2014 08:47:20 +0000 (16:47 +0800)
committerSam Moore <matches@ucc.asn.au>
Mon, 21 Apr 2014 08:47:20 +0000 (16:47 +0800)
`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.

src/main.cpp
src/real.cpp
src/real.h
src/tests/calculatepi.cpp

index d9f2a7f..9b33453 100644 (file)
@@ -2,7 +2,12 @@
 #include <unistd.h> // 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));
index 74c774b..7c70a92 100644 (file)
@@ -5,7 +5,8 @@ namespace IPDF
        // Maps the REAL to a string
        const char * g_real_name[] = {
                "single",
-               "double"
+               "double",
+               "long double"
        };
 
 }
index e6e69bc..0068472 100644 (file)
@@ -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
index 46348ff..0b7692b 100644 (file)
@@ -4,7 +4,7 @@
  * Compares results obtained with float, double, and Real.
  */
 #include "main.h"
-#include <cmath> // for PI
+#include <cmath>
 #include <ctime> // for performance measurements
 
 /** Function to integrate
@@ -19,7 +19,7 @@ template <class T> T f(const T & x)
 /**
  * Integrate f using the simpson rule
  */
-template <class T> T Integrate(T(*f)(const T&), const T & xmin, const T & xmax, uint64_t intervals)
+template <class T> 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 <class T> 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<float>(f<float>, 0.0, 1.0, intervals) - (float)(M_PI);
+               float error_float = Integrate<float>(f<float>, 0.0f, 1.0f, intervals) - float(PI);
                clock_t clock_float = clock() - start;
                start = clock();
-               double error_double = Integrate<double>(f<double>, 0.0, 1.0, intervals) - (double)(M_PI);
+               double error_double = Integrate<double>(f<double>, 0.0, 1.0, intervals) - double(PI);
                clock_t clock_double = clock() - start;
                start = clock();
-               Real error_real = Integrate<Real>(f<Real>, 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<long double>(f<long double>,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<Real>(f<Real>,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
        }
 }
 

UCC git Repository :: git.ucc.asn.au