From a5469cdd24ed4e8e8c63121078850015df1faedc Mon Sep 17 00:00:00 2001 From: rob tillaart Date: Sun, 1 Mar 2015 12:03:22 +0100 Subject: [PATCH] + initial version 0.1.00 --- libraries/Fraction/fraction.cpp | 241 ++++++++++++++++++++++++++++++++ libraries/Fraction/fraction.h | 60 ++++++++ 2 files changed, 301 insertions(+) create mode 100644 libraries/Fraction/fraction.cpp create mode 100644 libraries/Fraction/fraction.h diff --git a/libraries/Fraction/fraction.cpp b/libraries/Fraction/fraction.cpp new file mode 100644 index 00000000..5df98545 --- /dev/null +++ b/libraries/Fraction/fraction.cpp @@ -0,0 +1,241 @@ +// +// FILE: fraction.h +// AUTHOR: Rob Tillaart +// VERSION: 0.1.00 +// PURPOSE: library for fractions for Arduino +// URL: +// +// Released to the public domain +// +// TODO +// - negative fractions +// - divide by zero errors +// - test extensively +// - better print output for whole numbers? + +#include "fraction.h" + +Fraction::Fraction(double f) +{ + if (f == 0.0) + { + n = 0; + d = 1; + return; + } + // Normalize + bool neg = f < 0; + if (neg) f = -f; + bool rec = f > 1; + if (rec) f = 1/f; + + fractionize(f); + simplify(); + + if (neg) n = -n; + if (rec) + { + int32_t t = n; + n = d; + d = t; + } +} + +Fraction::Fraction(int32_t p, int32_t q) +{ + if (p == 0) + { + n = 0; + d = 1; + return; + } + n = abs(p); + d = abs(q); + simplify(); + // get sign right + if ((p<0) != (q<0)) n = -n; +} + +Fraction::Fraction(int32_t p) +{ + n = p; + d = 1; +} + +Fraction::Fraction(int16_t p) +{ + n = p; + d = 1; +} + +Fraction::Fraction(int8_t p) +{ + n = p; + d = 1; +} + +Fraction::Fraction(const Fraction &f) +{ + n = f.n; + d = f.d; +} + + +// PRINTING +size_t Fraction::printTo(Print& p) const +{ + size_t s = 0; + s += p.print(n, DEC); + s += p.print('/'); + s += p.print(d, DEC); + return s; +}; + +// EQUALITIES +bool Fraction::operator == (Fraction c) +{ + return (n == c.n) && (d == c.d); +} + +bool Fraction::operator != (Fraction c) +{ + return (n != c.n) || (d != c.d); +} + +bool Fraction::operator > (Fraction c) +{ + return (n * c.d) > (d * c.n); +} + +bool Fraction::operator >= (Fraction c) +{ + return (n * c.d) >= (d * c.n); +} + +bool Fraction::operator < (Fraction c) +{ + return (n * c.d) < (d * c.n); +} + +bool Fraction::operator <= (Fraction c) +{ + return (n * c.d) <= (d * c.n); +} + +// NEGATE +Fraction Fraction::operator - () +{ + return Fraction(-d, n); +} + +// BASIC MATH +Fraction Fraction::operator + (Fraction c) +{ + if (d == c.d) return Fraction(n + c.n, d); + int32_t dd = d * c.d; + return Fraction(n*c.d + c.n*d, dd); +} + +Fraction Fraction::operator - (Fraction c) +{ + if (d == c.d) return Fraction(n - c.n, d); + int32_t dd = d * c.d; + return Fraction(n*c.d - c.n*d, dd); +} + +Fraction Fraction::operator * (Fraction c) +{ + return Fraction(n*c.n, d*c.d); +} + +Fraction Fraction::operator / (Fraction c) +{ + return Fraction(n*c.d, d*c.n); +} + +void Fraction::operator += (Fraction c) +{ + if (d == c.d) + { + n += c.n; + return; + } + n = n * c.d + c.n * d; + d *= c.d; +} + +void Fraction::operator -= (Fraction c) +{ + if (d == c.d) + { + n -= c.n; + return; + } + n = n * c.d - c.n * d; + d *= c.d; +} + +void Fraction::operator *= (Fraction c) +{ + n *= c.n; + d *= c.d; +} + +void Fraction::operator /= (Fraction c) +{ + n *= c.d; + d *= c.n; +} + +// PRIVATE +int32_t Fraction::gcd(int32_t a , int32_t b) +{ + long c; + while ( a != 0 ) + { + c = a; + a = b % a; + b = c; + } + return b; +} + +// not that simple ... +void Fraction::simplify() +{ + int32_t x = gcd(n, d); + n = n/x; + d = d/x; + while (d > 10000) + { + n = round(n * 0.1); + d = round(d * 0.1); + x = gcd(n, d); + n = n/x; + d = d/x; + } +} + +// PRE: 0 <= f < 1.0 +double Fraction::fractionize(double f) +{ + long nn = 1, dd = 1; + + float r = 1 / f; + float delta = f * dd - nn; + float mindelta = 1; + while (abs(delta) > 0.00001) + { + dd++; + if (delta < 0) + { + nn++; + dd = nn * r; + } + delta = f * dd - nn; + } + n = nn; + d = dd; + return delta; +} +// --- END OF FILE --- \ No newline at end of file diff --git a/libraries/Fraction/fraction.h b/libraries/Fraction/fraction.h new file mode 100644 index 00000000..4b9b2e16 --- /dev/null +++ b/libraries/Fraction/fraction.h @@ -0,0 +1,60 @@ +// +// FILE: fraction.h +// AUTHOR: Rob Tillaart +// VERSION: 0.1.00 +// PURPOSE: demo library for fractions for Arduino +// URL: +// +// Released to the public domain +// + +#ifndef Fraction_h +#define Fraction_h + +#include "Arduino.h" + +#define FRACTIONLIBVERSION "0.1.00" + +class Fraction: public Printable +{ +public: + + Fraction(double); + Fraction(int32_t, int32_t); + Fraction(int32_t); + Fraction(int16_t); + Fraction(int8_t); + Fraction(const Fraction&); + + size_t printTo(Print& p) const; + + bool operator == (Fraction); + bool operator != (Fraction); + bool operator > (Fraction); + bool operator >= (Fraction); + bool operator < (Fraction); + bool operator <= (Fraction); + + Fraction operator - (); // negation + + Fraction operator + (Fraction); + Fraction operator - (Fraction); + Fraction operator * (Fraction); + Fraction operator / (Fraction); + + void operator += (Fraction); + void operator -= (Fraction); + void operator *= (Fraction); + void operator /= (Fraction); + +private: + void simplify(); + double fractionize(double); + int32_t gcd(int32_t, int32_t); + + int32_t n; + int32_t d; +}; + +#endif +// -- END OF FILE -- \ No newline at end of file