2021-01-29 06:31:58 -05:00
|
|
|
//
|
|
|
|
// FILE: FLE.cpp
|
|
|
|
// AUTHOR: Rob Tillaart
|
|
|
|
// DATE: 2020-07-21
|
2022-12-08 11:29:26 -05:00
|
|
|
// VERSION: 0.1.3
|
2021-01-29 06:31:58 -05:00
|
|
|
// PURPOSE: Arduino library for float with error datatype
|
|
|
|
// URL: https://github.com/RobTillaart/FLE
|
|
|
|
//
|
|
|
|
// HISTORY
|
|
|
|
// 0.0.1 2020-07-21 initial version
|
|
|
|
// 0.1.0 2020-12-23 arduino-CI + unit tests
|
2021-05-28 07:27:47 -04:00
|
|
|
// 0.1.1 2021-05-27 fix arduino-lint
|
2021-06-16 07:32:34 -04:00
|
|
|
// 0.1.2 2021-06-15 add negation + unit tests
|
|
|
|
// add first comparisons + some experimental
|
2022-12-08 11:29:26 -05:00
|
|
|
// 0.1.3 2021-06-16 add shared()
|
2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
|
|
|
|
#include "FLE.h"
|
|
|
|
|
2021-05-28 07:27:47 -04:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
FLE::FLE(float val, float err)
|
|
|
|
{
|
|
|
|
_v = val;
|
|
|
|
_e = abs(err);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// PRINTABLE
|
|
|
|
size_t FLE::printTo(Print& p) const
|
|
|
|
{
|
|
|
|
size_t n = 0;
|
|
|
|
n += p.print(_v, _decimals);
|
|
|
|
n += p.print(' ');
|
|
|
|
n += p.print(_sep);
|
|
|
|
n += p.print(' ');
|
|
|
|
n += p.print(_e, _decimals);
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-16 07:32:34 -04:00
|
|
|
/////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// MATH OPERATORS
|
|
|
|
//
|
|
|
|
|
|
|
|
// NEGATION
|
|
|
|
FLE FLE::operator - ()
|
|
|
|
{
|
|
|
|
return FLE(-_v, _e);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
FLE FLE::operator + (const FLE &in)
|
|
|
|
{
|
|
|
|
return FLE(_v + in._v, _e + in._e);
|
|
|
|
}
|
|
|
|
|
2021-05-28 07:27:47 -04:00
|
|
|
|
2021-06-16 07:32:34 -04:00
|
|
|
// SUBTRACT
|
2021-01-29 06:31:58 -05:00
|
|
|
FLE FLE::operator - (const FLE &in)
|
|
|
|
{
|
|
|
|
return FLE(_v - in._v, _e + in._e);
|
|
|
|
}
|
|
|
|
|
2021-05-28 07:27:47 -04:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
FLE FLE::operator * (const FLE &in)
|
|
|
|
{
|
|
|
|
float val = _v * in._v;
|
|
|
|
float err = (relError() + in.relError()) * val;
|
|
|
|
return FLE(val, err);
|
|
|
|
}
|
|
|
|
|
2021-05-28 07:27:47 -04:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
FLE FLE::operator / (const FLE &in)
|
|
|
|
{
|
|
|
|
float val = _v / in._v;
|
|
|
|
float err = (relError() + in.relError()) * val;
|
|
|
|
return FLE(val, err);
|
|
|
|
}
|
|
|
|
|
2021-05-28 07:27:47 -04:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
FLE FLE::operator += (const FLE &in)
|
|
|
|
{
|
|
|
|
_v += in._v;
|
|
|
|
_e += in._e;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2021-05-28 07:27:47 -04:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
FLE FLE::operator -= (const FLE &in)
|
|
|
|
{
|
|
|
|
_v -= in._v;
|
|
|
|
_e += in._e;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2021-05-28 07:27:47 -04:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
FLE FLE::operator *= (const FLE &in)
|
|
|
|
{
|
|
|
|
float sum = relError() + in.relError();
|
|
|
|
_v *= in._v;
|
|
|
|
_e = sum * _v;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2021-05-28 07:27:47 -04:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
FLE FLE::operator /= (const FLE &in)
|
|
|
|
{
|
|
|
|
float sum = relError() + in.relError();
|
|
|
|
_v /= in._v;
|
|
|
|
_e = sum * _v;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-16 07:32:34 -04:00
|
|
|
/////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// BOOL OPERATORS
|
|
|
|
//
|
2022-12-08 11:29:26 -05:00
|
|
|
// bool FLE::operator == (const FLE in)
|
|
|
|
//{
|
|
|
|
// return ((_v == in._v) && (_e == in._e));
|
|
|
|
//}
|
|
|
|
|
2021-06-16 07:32:34 -04:00
|
|
|
bool FLE::operator == (const FLE &in)
|
|
|
|
{
|
|
|
|
return ((_v == in._v) && (_e == in._e));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FLE::operator != (const FLE &in)
|
|
|
|
{
|
|
|
|
return ((_v != in._v) || (_e != in._e));
|
|
|
|
}
|
|
|
|
|
|
|
|
// bool FLE::operator >= (const FLE &in)
|
|
|
|
// {
|
|
|
|
// return ((*this == in) || (low() >= in.high()));
|
|
|
|
// }
|
|
|
|
|
|
|
|
bool FLE::operator > (const FLE &in)
|
|
|
|
{
|
|
|
|
return low() > in.high();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// bool FLE::operator <= (const FLE &in)
|
|
|
|
// {
|
|
|
|
// return ((*this == in) || (high() <= in.low()) );
|
|
|
|
// }
|
|
|
|
|
|
|
|
bool FLE::operator < (const FLE &in)
|
|
|
|
{
|
|
|
|
return high() < in.low();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// MISC OPERATORS
|
|
|
|
//
|
|
|
|
bool FLE::in(FLE a)
|
|
|
|
{
|
|
|
|
return ( a.low() <= low() && high() <= a.high());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-12-08 11:29:26 -05:00
|
|
|
FLE FLE::shared(FLE a)
|
|
|
|
{
|
|
|
|
float v, e;
|
|
|
|
// six possible cases.
|
|
|
|
// case 1, 6
|
|
|
|
if ((*this < a) || (*this > a)) return FLE(NAN, NAN); // no overlap
|
|
|
|
|
|
|
|
// case 3, 4
|
|
|
|
if (a.in(*this)) return a;
|
|
|
|
if (this->in(a)) return *this;
|
|
|
|
|
|
|
|
// case 2
|
|
|
|
if (low() < a.low())
|
|
|
|
{
|
|
|
|
v = (a.low() + high())/2;
|
|
|
|
e = v - a.low();
|
|
|
|
}
|
|
|
|
// case 5
|
|
|
|
else
|
|
|
|
{
|
|
|
|
v = (low() + a.high())/2;
|
|
|
|
e = v - low();
|
|
|
|
}
|
|
|
|
return FLE(v, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FLE FLE::lower(FLE a)
|
|
|
|
{
|
|
|
|
return FLE(0,0); // TODO
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FLE FLE::higher(FLE a)
|
|
|
|
{
|
|
|
|
return FLE(0,0); // TODO
|
|
|
|
}
|
|
|
|
|
2021-06-16 07:32:34 -04:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////
|
|
|
|
//
|
2022-12-08 11:29:26 -05:00
|
|
|
// WEAK PROPOSITIONS TODO elaborate
|
2021-06-16 07:32:34 -04:00
|
|
|
//
|
2022-12-08 11:29:26 -05:00
|
|
|
// possible equal
|
|
|
|
bool FLE::peq(const FLE &a)
|
2021-06-16 07:32:34 -04:00
|
|
|
{
|
2022-12-08 11:29:26 -05:00
|
|
|
if (a.low() <= low() && a.high() >= low() ) return true;
|
|
|
|
if (low() <= a.low() && high() >= a.low() ) return true;
|
2021-06-16 07:32:34 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-12-08 11:29:26 -05:00
|
|
|
// possible not equal
|
|
|
|
bool FLE::pne(const FLE &a)
|
|
|
|
{
|
|
|
|
return !(*this == a);
|
|
|
|
}
|
|
|
|
|
|
|
|
// possible less than
|
|
|
|
bool FLE::plt(const FLE &a)
|
|
|
|
{
|
|
|
|
return (this->low() < a.low()); // TODO
|
|
|
|
}
|
|
|
|
|
|
|
|
// possible less equal
|
|
|
|
bool FLE::ple(const FLE &a)
|
|
|
|
{
|
|
|
|
return (this->low() <= a.low()); // TODO
|
|
|
|
}
|
|
|
|
|
|
|
|
// possible greater than
|
|
|
|
bool FLE::pgt(const FLE &a)
|
|
|
|
{
|
|
|
|
return (this->high() > a.high());
|
|
|
|
}
|
|
|
|
|
|
|
|
// possible greater equal
|
|
|
|
bool FLE::pge(const FLE &a)
|
2021-06-16 07:32:34 -04:00
|
|
|
{
|
2022-12-08 11:29:26 -05:00
|
|
|
return (this->high() >= a.high()); // TODO
|
2021-06-16 07:32:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
// -- END OF FILE --
|