mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
109 lines
1.9 KiB
C++
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 --
|
|
|