0.1.15 Fraction

This commit is contained in:
rob tillaart 2023-02-03 13:14:59 +01:00
parent da6be76692
commit cea234e035
13 changed files with 417 additions and 119 deletions

View File

@ -6,7 +6,7 @@ jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: arduino/arduino-lint-action@v1 - uses: arduino/arduino-lint-action@v1
with: with:
library-manager: update library-manager: update

View File

@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1 - uses: ruby/setup-ruby@v1
with: with:
ruby-version: 2.6 ruby-version: 2.6

View File

@ -10,7 +10,7 @@ jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: json-syntax-check - name: json-syntax-check
uses: limitusus/json-syntax-check@v1 uses: limitusus/json-syntax-check@v1
with: with:

View File

@ -6,12 +6,20 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.1.15] - 2023-02-02
- update GitHub actions
- update license 2023
- update readme.md
- move code to .cpp
- change signature **double toDouble()**
- add **Fraction_performance.ino** to start performance testing.
## [0.1.14] - 2022-11-07 ## [0.1.14] - 2022-11-07
- add changelog.md - add changelog.md
- add rp2040 to build-CI - add rp2040 to build-CI
- update readme.md - update readme.md
## [0.1.13] - 2021-12-18 ## [0.1.13] - 2021-12-18
- update library.json - update library.json
- update license - update license
@ -30,40 +38,38 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
---- ----
Long time ago .... ## [0.1.9] - 2020-04-26
## [0.1.9]
- refactor - refactor
## [0.1.8] ## [0.1.8] - 2018-04-02
- refactor made constructors explicit - refactor made constructors explicit
- fix issue #33 double --> float - fix issue #33 double --> float
## [0.1.07] ## [0.1.07] - 2015-03-05
- major refactoring by Chris-A - major refactoring by Chris-A
## [0.1.06] ## [0.1.06] - 2015-02-15
- added proper(), mediant(), angle() - added proper(), mediant(), angle()
## [0.1.05] ## [0.1.05] - 2015-02-14
- tested negative Fractions math - tested negative Fractions math
- added constructors, - added constructors,
- minor refactoring - minor refactoring
## [0.1.04] ## [0.1.04] - 2015-02-09
- stabilizing code - stabilizing code
- add simplify() for some code paths. - add simplify() for some code paths.
## [0.1.03] ## [0.1.03] - 2015-02-07
- add toDouble() - add toDouble()
- tested several fractionize() codes - tested several fractionize() codes
- bug fixes. - bug fixes.
## [0.1.02] ## [0.1.02] - 2015-02-07
- faster fractionize code - faster fractionize code
## [0.1.01] ## [0.1.01] - 2015-02-03
- some fixes - some fixes
## [0.1.00] ## [0.1.00] - 2015-01-25
- initial version - initial version

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2015-2022 Rob Tillaart Copyright (c) 2015-2023 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -0,0 +1,166 @@
//
// FILE: fractionTest01.ino
// AUTHOR: Rob Tillaart
// PURPOSE: test sketch for fraction math
// DATE: 2015-01-25
// URL: https://github.com/RobTillaart/Fraction
#include "fraction.h"
uint32_t start, stop;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("FRACTION_LIB_VERSION: ");
Serial.println(FRACTION_LIB_VERSION);
Serial.println();
test_constructor();
test_math();
test_conversion();
test_misc();
Serial.println("\ndone...");
}
void loop()
{
}
void test_constructor()
{
Serial.println();
Serial.println(__FUNCTION__);
delay(10);
start = micros();
Fraction q(0.42);
Fraction a(1, 3);
Fraction aa(3, 9);
Fraction b(1, 4);
Fraction n(0, 5);
Fraction p(5, 1);
Fraction pi(PI);
Fraction e(EULER);
stop = micros();
Serial.print("TIME: \t");
Serial.println(stop - start);
Serial.println(q);
Serial.println(a);
Serial.println(aa);
Serial.println(b);
Serial.println(n);
Serial.println(p);
Serial.println(pi);
Serial.println(e);
}
void test_math()
{
Serial.println();
Serial.println(__FUNCTION__);
delay(10);
Fraction a(0, 1);
Fraction pi(PI);
Fraction e(EULER);
start = micros();
a = pi + e;
stop = micros();
Serial.print("TIME +: \t");
Serial.println(stop - start);
Serial.println(a);
delay(10);
start = micros();
a = pi - e;
stop = micros();
Serial.print("TIME -: \t");
Serial.println(stop - start);
Serial.println(a);
delay(10);
start = micros();
a = pi * e;
stop = micros();
Serial.print("TIME *: \t");
Serial.println(stop - start);
Serial.println(a);
delay(10);
start = micros();
a = pi / e;
stop = micros();
Serial.print("TIME /: \t");
Serial.println(stop - start);
Serial.println(a);
}
void test_conversion()
{
Serial.println();
Serial.println(__FUNCTION__);
delay(10);
Fraction e(EULER);
double d;
start = micros();
d = e.toDouble();
stop = micros();
Serial.print("TIME toDouble(): \t");
Serial.println(stop - start);
Serial.println(d, 7);
delay(10);
start = micros();
d = e.toFloat();
stop = micros();
Serial.print("TIME toFloat(): \t");
Serial.println(stop - start);
Serial.println(d, 7);
delay(10);
start = micros();
d = e.toAngle();
stop = micros();
Serial.print("TIME toAngle(): \t");
Serial.println(stop - start);
Serial.println(d, 7);
}
void test_misc()
{
Serial.println();
Serial.println(__FUNCTION__);
delay(10);
Fraction a(0, 1);
Fraction pi(PI);
Fraction e(EULER);
start = micros();
a = Fraction::mediant(pi, e);
stop = micros();
Serial.print("TIME mediant(): \t");
Serial.println(stop - start);
Serial.println(a);
delay(10);
start = micros();
a = Fraction::middle(pi, e);
stop = micros();
Serial.print("TIME middle(): \t");
Serial.println(stop - start);
Serial.println(a);
}
// -- END OF FILE --

View File

@ -0,0 +1,43 @@
IDE 1.8.19
Arduino UNO
Fraction_performance.ino
FRACTION_LIB_VERSION: 0.1.15
test_constructor
TIME: 5288
21/50
1/3
1/3
1/4
0/1
5/1
355/113
3985/1466
test_math
TIME +: 1056
16179/2761
TIME -: 1444
701/1657
TIME *: 1204
23578/2761
TIME /: 1240
10409/9006
test_conversion
TIME toDouble(): 44
2.718281
TIME toFloat(): 40
2.718281
TIME toAngle(): 200
69.802467
test_misc
TIME mediant(): 372
4340/1579
TIME middle(): 1252
16179/5522
done...

View File

@ -1,11 +1,9 @@
// //
// FILE: fraction.cpp // FILE: fraction.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.1.14 // VERSION: 0.1.15
// PURPOSE: Arduino library to implement a Fraction datatype // PURPOSE: Arduino library to implement a Fraction data type
// URL: https://github.com/RobTillaart/Fraction // URL: https://github.com/RobTillaart/Fraction
//
// HISTORY: see changelog.md
#include "fraction.h" #include "fraction.h"
@ -252,9 +250,15 @@ Fraction& Fraction::operator /= (const Fraction &c)
} }
float Fraction::toDouble() double Fraction::toDouble()
{ {
return (1.0 * n) / d; return double(n) / d;
}
float Fraction::toFloat()
{
return float(n) / d;
} }
@ -268,7 +272,19 @@ bool Fraction::isProper()
// visualize fraction as an angle in degrees // visualize fraction as an angle in degrees
float Fraction::toAngle() float Fraction::toAngle()
{ {
return atan2(n, d) * 180.0 / PI; return atan2(n, d) * (180.0 / PI);
}
int32_t Fraction::nominator()
{
return n;
}
int32_t Fraction::denominator()
{
return d;
} }
@ -313,7 +329,7 @@ Fraction Fraction::setDenominator(const Fraction &a, uint16_t b)
////////////////////////////////////// //////////////////////////////////////
// //
// PRIVATE // PROTECTED
// http://en.wikipedia.org/wiki/Binary_GCD_algorithm // http://en.wikipedia.org/wiki/Binary_GCD_algorithm
// //
int32_t Fraction::gcd(int32_t a , int32_t b) int32_t Fraction::gcd(int32_t a , int32_t b)

View File

@ -2,15 +2,15 @@
// //
// FILE: fraction.h // FILE: fraction.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.1.14 // VERSION: 0.1.15
// PURPOSE: Arduino library to implement a Fraction datatype // PURPOSE: Arduino library to implement a Fraction data type
// URL: https://github.com/RobTillaart/Fraction // URL: https://github.com/RobTillaart/Fraction
// //
#include "Arduino.h" #include "Arduino.h"
#define FRACTION_LIB_VERSION (F("0.1.14")) #define FRACTION_LIB_VERSION (F("0.1.15"))
class Fraction: public Printable class Fraction: public Printable
@ -20,6 +20,7 @@ public:
explicit Fraction(float); explicit Fraction(float);
Fraction(int32_t, int32_t); Fraction(int32_t, int32_t);
// CONSTRUCTORS
explicit Fraction(int32_t p) : n(p), d(1) {} explicit Fraction(int32_t p) : n(p), d(1) {}
explicit Fraction(int16_t p) : n(p), d(1) {} explicit Fraction(int16_t p) : n(p), d(1) {}
explicit Fraction(int8_t p) : n(p), d(1) {} explicit Fraction(int8_t p) : n(p), d(1) {}
@ -30,7 +31,7 @@ public:
size_t printTo(Print& p) const; size_t printTo(Print& p) const;
// equalities // EQUALITIES
bool operator == (const Fraction&); bool operator == (const Fraction&);
// bool operator == (const float&); // bool operator == (const float&);
bool operator != (const Fraction&); bool operator != (const Fraction&);
@ -39,10 +40,10 @@ public:
bool operator < (const Fraction&); bool operator < (const Fraction&);
bool operator <= (const Fraction&); bool operator <= (const Fraction&);
// negation // NEGATE
Fraction operator - (); Fraction operator - ();
// basic maths // BASIC MATH
Fraction operator + (const Fraction&); Fraction operator + (const Fraction&);
Fraction operator - (const Fraction&); Fraction operator - (const Fraction&);
Fraction operator * (const Fraction&); Fraction operator * (const Fraction&);
@ -53,21 +54,19 @@ public:
Fraction& operator *= (const Fraction&); Fraction& operator *= (const Fraction&);
Fraction& operator /= (const Fraction&); Fraction& operator /= (const Fraction&);
// CONVERSION
float toDouble(); double toDouble();
float toFloat() { return toDouble(); }; float toFloat();
bool isProper(); // abs(f) < 1 bool isProper(); // abs(f) < 1
float toAngle(); float toAngle();
int32_t nominator();
int32_t denominator();
int32_t nominator() { return n; }; // MISCELLANEOUS (static)
int32_t denominator() { return d; };
static Fraction mediant(const Fraction&, const Fraction&); static Fraction mediant(const Fraction&, const Fraction&);
static Fraction middle(const Fraction&, const Fraction&); static Fraction middle(const Fraction&, const Fraction&);
// approximate a fraction with defined denominator // approximate a fraction with defined denominator
static Fraction setDenominator(const Fraction&, uint16_t); static Fraction setDenominator(const Fraction&, uint16_t);

View File

@ -15,7 +15,7 @@
"type": "git", "type": "git",
"url": "https://github.com/RobTillaart/Fraction.git" "url": "https://github.com/RobTillaart/Fraction.git"
}, },
"version": "0.1.14", "version": "0.1.15",
"frameworks": "arduino", "frameworks": "arduino",
"platforms": "*", "platforms": "*",
"headers": "fraction.h" "headers": "fraction.h"

View File

@ -1,5 +1,5 @@
name=Fraction name=Fraction
version=0.1.14 version=0.1.15
author=Rob Tillaart <rob.tillaart@gmail.com> author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com> maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library to implement a Fraction datatype sentence=Arduino library to implement a Fraction datatype

View File

@ -14,44 +14,109 @@ Arduino library to implement a Fraction data type (experimental).
## Description ## Description
The fraction library implements fractional numbers a.k.a. Q, The fraction library implements fractional numbers a.k.a. Q,
(integers are Z and floats/doubles are R), (integers are Z and floats/doubles are R), and the conversion to floats.
and the conversion to floats.
The code is working with a number of limitations among others: The code is working with a number of limitations a.o.:
- denominator is max 4 digits to keep code for multiply and divide simple - denominator is max 4 digits to keep code for multiply and divide simple
- Fractions are not exact (even floats are not exact) - Fractions are not exact, even floats are not exact.
- the range of numbers supported is limited. - the range of numbers supported is limited.
- code is experimental still. - code is experimental still.
That said, the library is useful e.g. to display float numbers as a fraction. That said, the library is useful e.g. to display float numbers as a fraction.
From programming point of view the **fractionize()** function, converting a double From programming point of view the **fractionize(float)** function, converting a double
into a fraction is a nice programming problem, fast with a minimal error. into a fraction is a nice programming problem, fast with a minimal error.
In short, use fractions with care otherwise your sketch might get broken ;) In short, use fractions with care otherwise your sketch might get broken ;)
## Operations ## Interface
See examples ```cpp
#include "fraction.h"
```
#### Constructors
- **explicit Fraction(double)**
- **explicit Fraction(float)**
- **Fraction(int32_t nominator, int32_t denominator)**
- **explicit Fraction(int32_t p)**
- **explicit Fraction(int16_t p)**
- **explicit Fraction(int8_t p)**
- **explicit Fraction(uint32_t p)**
- **explicit Fraction(uint16_t p)**
- **explicit Fraction(uint8_t p)**
- **Fraction(const Fraction &f)**
#### Printable
The Fraction library implements Printable, so one can do.
```cpp
Fraction fr(PI);
Serial.print(fr); // print 355/113
```
#### Equalities
The Fraction library implements ==, !=, >=, >, <, <=
#### Basic Math
The Fraction library implements, + - * / += -= *= /= and - (negation)
#### Conversion
- **double toDouble()** idem.
- **float toFloat()** idem.
- **bool isProper()** absolute value < 1.
- **float toAngle()** returns 0..360 degrees.
- **int32_t nominator()** idem.
- **int32_t denominator()** idem.
#### Miscellaneous (static)
- **Fraction mediant(const Fraction&, const Fraction&)**
- **Fraction middle(const Fraction&, const Fraction&)**
- **Fraction setDenominator(const Fraction&, uint16_t)**
## Use with care ## Use with care
The library is reasonably tested, and if problems arise please let me know. The library is reasonably tested. If problems arise please open an issue.
## Future ## Future
#### must #### Must
- improve documentation - improve documentation
- test test test ... - test test test ...
#### should #### Should
- investigate divide by zero errors
- investigate better fractionize() - depends on nom/denom size - performance testing
- investigate divide by zero errors
- NAN in fraction? => 0/0 ?
- INF in fraction? => 1/0 and -1/0?
- investigate better **fractionize()**
- depends on nom/denom size
- returns the error..
#### Could
#### could
- extend unit tests - extend unit tests
- experiment with bigger nominator/denominator using all of 32767 possibilities ? - experiment with bigger nominator/denominator using all of 32767 possibilities ?
- add famous constants as Fraction e.g FRAC_PI = (355, 113) ?? - add famous constants as Fraction e.g
- FRAC_PI = 355/113
- FRAC_E = 3985/1466
#### Wont

View File

@ -35,6 +35,7 @@ unittest_setup()
fprintf(stderr, "FRACTION_LIB_VERSION: %s\n", (char*) FRACTION_LIB_VERSION); fprintf(stderr, "FRACTION_LIB_VERSION: %s\n", (char*) FRACTION_LIB_VERSION);
} }
unittest_teardown() unittest_teardown()
{ {
} }
@ -89,4 +90,6 @@ unittest(test_math)
unittest_main() unittest_main()
// --------
// -- END OF FILE --