GY-63_MS5611/libraries/Fraction/examples/FractionMediant/FractionMediant.ino
2021-12-18 14:11:39 +01:00

109 lines
1.9 KiB
C++

//
// FILE: FractionMediant.ino
// AUTHOR: Rob Tillaart
// PURPOSE: Find fraction by binary search with mediant.
// DATE: 2020-04-21
//
// this method is not that fast but it shows a nice application for
// the mediant.
#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);
Serial.println(x.toDouble(), 10);
Serial.println();
f = EULER;
start = micros();
Fraction y = fractionize(f);
stop = micros();
Serial.println(stop - start);
Serial.println(y);
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);
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);
Serial.print("\t");
Serial.print(f, 10);
Serial.print("\t");
Serial.print(y.toDouble(), 10);
Serial.print("\t");
Serial.println(f - y.toDouble(), 10);
}
Fraction fractionize(float f)
{
float acc = 1e-6;
float d1 = 0;
float d2 = 0;
Fraction a(0, 1);
Fraction b(9999, 1);
Fraction q(f);
for (int i = 0; i < 500; i++)
{
Fraction c = Fraction::mediant(a, b); // NOTE middle(a,b) is slower and worse!
if ( c.toDouble() < f) a = c;
else b = c;
d1 = abs(f - a.toDouble());
d2 = abs(f - b.toDouble());
if (d1 < acc && d2 < acc) break;
}
if (d1 < d2) return a;
return b;
}
// -- END OF FILE --