Basic definition of base-10 floating point value. More...
#include <Number.h>
Public Member Functions | |
| bool | operator== (const number_t &other) const |
| bool | operator!= (const number_t &other) const |
| bool | sign () const |
| bool | operator< (const number_t &other) const |
| bool | operator> (const number_t &other) const |
| size_t | printTo (Print &p) const |
Static Public Member Functions | |
| static constexpr const number_t | min () |
| Smallest positive value. More... | |
| static constexpr const number_t | max () |
| Largest positive value. More... | |
| static constexpr const number_t | lowest () |
| Most negative value. More... | |
| static double | asFloat (number_t number) |
| static int64_t | asInt64 (number_t number) |
| static int | compare (number_t num1, number_t num2) |
| static const char * | format (char *buf, number_t number) |
| Convert number to string. More... | |
| static bool | parse (const char *value, unsigned length, number_t &number) |
| static number_t | parse (const char *value, unsigned length) |
| static constexpr number_t | normalise (unsigned mantissa, int exponent, bool isNeg) |
| Produce a normalised number_t from component values. More... | |
| static constexpr number_t | normalise (double mantissa) |
| static constexpr number_t | normalise (int mantissa, int exponent) |
| static constexpr number_t | normalise (int64_t value) |
Public Attributes | |
| int32_t | mantissa: 26 |
| int32_t | exponent: 6 |
Static Public Attributes | |
| static constexpr unsigned | maxMantissa {0x1ffffff} |
| static constexpr int | maxExponent {0x1f} |
| static constexpr unsigned | maxSignificantDigits {8} |
| static constexpr unsigned | minBufferSize {17} |
Detailed Description
Basic definition of base-10 floating point value.
value = mantissa * 10^exponent
This format is aimed to be a simple and transparent way to store floating-point numbers without the weird rounding issues of IEEE754 base-2 float / double.
Conversion to floating-point format is only done when required by the application. This can be avoided completely by using strings instead of floats to set values.
Constant values can also be specified which are converted at compile-time. See const_number_t.
Integer values can also be specified, but may be subject to rounding if too precise. Very large (or small) values can be used, such as 1.5e25. This would actually be stored as 15e4 {15, 24}.
It does not need to be computationally efficient, but does have advantages:
- structure is transparent - Base-10 operations can be performed efficiently without rounding errors - Serialising (converting to strings) and de-serialising is consistent and JSON-compatible
Some similarity to python's Decimal class, but with restriction on significant digits and exponent.
The initial version of this used 24 bits for the mantissa, but 8 bits for the exponent is overkill. Reducing exponent to 6 bits increases precision by 2 bits to give: smallest: 1e-31 largest: 33554431e31 (3.3554431e38)
Numbers always have a valid representation for ease of use and JSON compatibility. There is no definition for 'NaN' (not a number) or 'infinity. Values are never rounded down to 0, but clipped to the above valid range. Thus convering any number smaller than 1e-31 (but > 0) is stored as 1e-31. Applications can consider number_t::min() and number_t::max() as the 'overflow' values. As with the C++ STL, lowest() indicates the most negative value which is equivalent to -max().
The mantissa/exponent fields can be manipulated directly if required. For example, to convert terabytes to gigabytes we just subtract 3 from the exponent.
An example of custom arithmetic:
number_t multiplyBy2000(number_t value)
{
value.mantissa *= 2;
value.exponent += 3;
return value;
}
If there's a risk of over/under flowing in the calculation, do this:
number_t multiplyBy2000(number_t value)
{
int mantissa = value.mantissa * 2;
int exponent = value.exponent + 3;
return number_t::normalise(mantissa, exponent);
}
, avoiding overflow risk, multiplying a number by 2000 int mantissa = number.mantissa; int exponent = number.exponent; mantissa *= 2; exponent += 3; number_t new_number = number_t::normalise(number);
- Note
- This structure is not packed to ensure values stored in flash behave correctly.
Member Function Documentation
◆ asFloat()
|
static |
◆ asInt64()
|
static |
◆ compare()
◆ format()
|
static |
Convert number to string.
- Parameters
-
buf Buffer of at least number_t::minBufferSize number
- Return values
-
char* Points to string, may not be start of buf
- Note
- Always use return value to give implementation flexible use of buffer
◆ lowest()
|
inlinestaticconstexpr |
Most negative value.
◆ max()
|
inlinestaticconstexpr |
Largest positive value.
◆ min()
|
inlinestaticconstexpr |
Smallest positive value.
◆ normalise() [1/4]
|
inlinestaticconstexpr |
◆ normalise() [2/4]
|
inlinestaticconstexpr |
◆ normalise() [3/4]
|
inlinestaticconstexpr |
◆ normalise() [4/4]
|
inlinestaticconstexpr |
Produce a normalised number_t from component values.
- Parameters
-
mantissa Mantissa without sign, containing significant digits exponent Exponent isNeg true if mantissa is negative, false if positive
- Return values
-
number_t Normalised number value For example, 1000e9 and 10e11 are normalised to 1e12. This allows values to be directly compared for equality.
Mantissa has trailing 0's removed, although may be required for large negative exponents. For example, 100000e-30 exponent is at limit so cannot be reduced further.
If necessary, the mantissa is rounded to the nearest whole value. For example, 3141592654 is rounded up to 31415927.
If the value is out of range, number_t::overflow is returned.
◆ operator!=()
|
inline |
◆ operator<()
|
inline |
◆ operator==()
|
inline |
◆ operator>()
|
inline |
◆ parse() [1/2]
◆ parse() [2/2]
|
static |
◆ printTo()
|
inline |
◆ sign()
|
inline |
Member Data Documentation
◆ exponent
| int32_t ConfigDB::number_t::exponent |
◆ mantissa
| int32_t ConfigDB::number_t::mantissa |
◆ maxExponent
|
staticconstexpr |
◆ maxMantissa
|
staticconstexpr |
◆ maxSignificantDigits
|
staticconstexpr |
◆ minBufferSize
|
staticconstexpr |
The documentation for this struct was generated from the following file:
1.9.1