> I want to know if there are any standard workarounds that are used often.
Remember, the type is call **floating**-point.
[number's radix point can "float" anywhere to the left, right, or between the significant digits](https://en.wikipedia.org/wiki/Floating-point_arithmetic)
---
Any form of of rating the _error_ of `a, b` is subject to the particular needs of code. The below uses a general discussion.
Floating point values are generally overall distributed logarithmically. That implies the _error_ between `a, b` is assessed as `(a-b)/max_magnitude(a, b)`. Then the error of 1500, 3000 is like the error to 0.00015, 0.00030.
Yet within a power-of-2, floating point values are distributed linearly. That implies the _error_ between `a, b` is assessed as `(a-b)/floor(log2(max_magnitude(a, b)))`. Then the error of 2.100, 2.200 is like the error to 2.800, 2.900.
Both approaches have trouble near [sub-normal numbers](https://en.wikipedia.org/wiki/Subnormal_number) (due to reduced precision), zeros (division by 0), and infinities.
A 3rd, and recommended approach, is to consider each floating point value as an indexed value. Consider all possible positive `float` values (+0.0 ... Infinity) are ordered and indexed 0, 1, 2, ... N. Negative values are indexed -0, -1, -2, ... -N. Then the _error_ between `a, b` is then `index(a) - index(b)`. The difference is related to the [unit in the last place (ULP)](https://en.wikipedia.org/wiki/Unit_in_the_last_place).
This allows for a consistent _error_ measurement across the entire ordered `float` range. See below code.
---
Math functions like `sin(x)`, `sqrt(x)`, `log(x)` are often rated as if the
`x` was exact and the `y = f(x)` (with is finite precision) is rated against the _mathematical_ f(x) with it infinite precision. This _error_ is rated in a like manner as if the math result may exist as a fractional index between two `float` indexes. Combined with ULP, we can say the _error_ of a good `sqrt(x)` versus √x is at most 0.5 ULP. Good implementations of transcendental functions line `sin()`, `log()` have an error < 1.0 ULP.
```
// Return the indexed absolute difference of 2 float values.
// Overlay a float and access it as an integer to determine its "index".
// Take advantage the + ascending float values,
// when examined as integers are sequenced in ascending integer order.
// Assumes floating-point endian is like integer endian.
// Not valid for not-a-numbers.
unsigned long ULP_diff(float x, float y) {
assert(sizeof(float) == sizeof(uint32_t));
union {
float f;
int32_t ll;
uint32_t ull;
} ux, uy;
ux.f = x;
uy.f = y;
if (ux.ll < 0) {
ux.ll = INT32_MIN - ux.ll;
}
if (uy.ll < 0) {
uy.ll = INT32_MIN - uy.ll;
}
unsigned long diff;
if (ux.ll >= uy.ll) {
diff = ux.ull - uy.ull;
} else {
diff = uy.ull - ux.ull;
}
return diff;
}
```