Skip to content

Commit

Permalink
update examples
Browse files Browse the repository at this point in the history
  • Loading branch information
RobTillaart committed Apr 24, 2024
1 parent 4fa3c4b commit aba83cf
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- add **fraction_sqrts.ino** test sketch
- add **fraction_fast.ino**, fast determination of fraction with 9900 as denominator.
- this is very fast, with an accuracy ~1e-4
- add **fraction_full_scan.ino** for a full scan search.
- optimized **FractionMediant.ino** determine fraction with mediant.
- add **fraction_setDenominator.ino** demo
- add **FactionPowers2.ino**, fast determination of fraction with powers of 2.- add examples including tests.
- update readme.md

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ The format is "(n/d)", where n has optionally the sign.

- **Fraction mediant(const Fraction&, const Fraction&)**
- **Fraction middle(const Fraction&, const Fraction&)**
- **Fraction setDenominator(const Fraction&, uint16_t)**
- **Fraction setDenominator(const Fraction&, uint16_t)** (might be simplified still)


## Use with care
Expand Down
106 changes: 106 additions & 0 deletions examples/Fraction_full_scan/Fraction_full_scan.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//
// FILE: Fraction_full_scan.ino
// AUTHOR: Rob Tillaart
// PURPOSE: Find fraction by full scan possible values.
// URL: https://github.com/RobTillaart/Fraction
//
// This method is very slow but it scans the whole range (in fact only half)
// for all possible fractions, resulting in very good approximations.
// Works for positive values only (for now).
//
// Takes up to 3 seconds per search on a 16 MHz UNO.
// Takes up to 12 milliseconds per search on a 240 MHz ESP32.

#include "fraction.h"


uint32_t start, stop;


void setup()
{
Serial.begin(115200);
Serial.print(__FILE__);
Serial.println();
Serial.println();

float f = PI;
start = micros();
Fraction x = fractionize(f);
stop = micros();
Serial.println(stop - start);
Serial.println(x.toString());
Serial.println(x.toDouble(), 10);
Serial.println();

f = EULER;
start = micros();
Fraction y = fractionize(f);
stop = micros();
Serial.println(stop - start);
Serial.println(y.toString());
Serial.println(y.toDouble(), 10);
Serial.println();

Serial.println("done...\n");
}


void loop()
{
float f = random(1000000) * 0.000001;

// reference
start = micros();
Fraction y(f);
stop = micros();

Serial.println();
Serial.print(stop - start);
Serial.print("\t");
Serial.print(y.toString());
Serial.print("\t");
Serial.print(f, 10);
Serial.print("\t");
Serial.print(y.toDouble(), 10);
Serial.print("\t");
Serial.println(f - y.toDouble(), 10);

// mediant method.
start = micros();
y = fractionize(f);
stop = micros();

Serial.print(stop - start);
Serial.print("\t");
Serial.print(y.toString());
Serial.print("\t");
Serial.print(f, 10);
Serial.print("\t");
Serial.print(y.toDouble(), 10);
Serial.print("\t");
Serial.println(f - y.toDouble(), 10);
}

// very very slow but very good.
Fraction fractionize(float f)
{
int best = 1;
float smallest = 1.0;
// smaller denominators will all be detected as 5000..10000 are multiples.
for (int d = 5000; d < 10000; d++)
{
Fraction frac(f * d + 0.5, d);
float tmp = abs(f - frac.toFloat());
if ( tmp < smallest)
{
smallest = tmp;
best = d;
}
}
Fraction frac(round(f * best), best);
return frac;
}


// -- END OF FILE --
51 changes: 51 additions & 0 deletions examples/Fraction_setDenominator/Fraction_setDenominator.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// FILE: Fraction_setDenominator.ino
// AUTHOR: Rob Tillaart
// PURPOSE: Calculate fraction with well chosen number.
// URL: https://github.com/RobTillaart/Fraction


#include "fraction.h"


void setup()
{
Serial.begin(115200);
Serial.print(__FILE__);
Serial.println();
Serial.println();

Fraction pi(PI);
Fraction appr = Fraction::setDenominator(pi, 32);
Serial.println(pi.toString());
Serial.println(pi.toDouble(), 10);
Serial.println(appr.toString());
Serial.println(appr.toDouble(), 10);
Serial.println();

Fraction ee(EULER);
appr = Fraction::setDenominator(ee, 32);
Serial.println(ee.toString());
Serial.println(ee.toDouble(), 10);
Serial.println(appr.toString());
Serial.println(appr.toDouble(), 10);
Serial.println();

Fraction tt(0.125);
appr = Fraction::setDenominator(tt, 32);
Serial.println(tt.toString());
Serial.println(tt.toDouble(), 10);
Serial.println(appr.toString());
Serial.println(appr.toDouble(), 10);
Serial.println();

Serial.println("done...\n");
}


void loop()
{
}


// -- END OF FILE --

0 comments on commit aba83cf

Please sign in to comment.