25#ifndef JAU_FLOAT_MATH_HPP_
26#define JAU_FLOAT_MATH_HPP_
50 using namespace jau::int_literals;
126 std::enable_if_t<std::is_floating_point_v<T>,
bool> =
true>
131 union { T_uint u; T f; } iec559 = { .f = a };
144 union { uint32_t u;
float f; } iec559 = { .f = a };
174 if( std::isnan(a) ) {
182 union { uint32_t u;
float f; } iec559 = { .u = a };
194 union { uint64_t u;
double f; } iec559 = { .f = a };
221 if( std::isnan(a) ) {
228 union { uint64_t u;
double f; } iec559 = { .u = a };
239 typename std::enable_if_t<std::is_floating_point_v<T>, T>
253 typename std::enable_if_t<std::is_floating_point_v<T>,
bool>
254 constexpr is_zero(
const T& a,
const T& epsilon=std::numeric_limits<T>::epsilon()) noexcept {
255 return std::abs(a) < epsilon;
260 typename std::enable_if_t<std::is_floating_point_v<T>,
bool>
261 constexpr is_zero2f(
const T& a,
const T& b,
const T& epsilon=std::numeric_limits<T>::epsilon()) noexcept {
262 return std::abs(a) < epsilon && std::abs(b) < epsilon;
267 typename std::enable_if_t<std::is_floating_point_v<T>,
bool>
268 constexpr is_zero3f(
const T& a,
const T& b,
const T& c,
const T& epsilon=std::numeric_limits<T>::epsilon()) noexcept {
269 return std::abs(a) < epsilon && std::abs(b) < epsilon && std::abs(c) < epsilon;
274 typename std::enable_if_t<std::is_floating_point_v<T>,
bool>
275 constexpr is_zero4f(
const T& a,
const T& b,
const T& c,
const T& d,
const T& epsilon=std::numeric_limits<T>::epsilon()) noexcept {
276 return std::abs(a) < epsilon && std::abs(b) < epsilon && std::abs(c) < epsilon && std::abs(d) < epsilon;
284 typename std::enable_if_t<std::is_floating_point_v<T>,
bool>
305 std::enable_if_t<std::is_floating_point_v<T>,
bool> =
true>
306 constexpr int compare(
const T a,
const T b)
noexcept {
315 typedef typename std::make_signed_t<T_uint> T_int;
316 const T_int a_bits =
static_cast<T_int
>(
bit_value(a) );
317 const T_int b_bits =
static_cast<T_int
>(
bit_value(b) );
318 if( a_bits == b_bits ) {
320 }
else if( a_bits < b_bits ) {
346 std::enable_if_t<std::is_floating_point_v<T>,
bool> =
true>
347 constexpr int compare(
const T a,
const T b,
const T epsilon)
noexcept {
348 if( std::abs(a - b) < epsilon ) {
369 typename std::enable_if_t<std::is_floating_point_v<T>,
bool>
392 typename std::enable_if_t<std::is_floating_point_v<T>,
bool>
393 constexpr equals(
const T& a,
const T& b,
const T& epsilon=std::numeric_limits<T>::epsilon()) noexcept {
394 if( std::abs(a - b) < epsilon ) {
411 typename std::enable_if_t<std::is_floating_point_v<T>,
bool>
412 constexpr equals2(
const T& a,
const T& b,
const T& epsilon=std::numeric_limits<T>::epsilon()) noexcept {
413 return std::abs(a - b) < epsilon;
434 typename std::enable_if_t<std::is_floating_point_v<T>,
bool>
435 constexpr equals(
const T& a,
const T& b,
int ulp,
const T& epsilon=std::numeric_limits<T>::epsilon()) noexcept {
436 return equals(a, b, epsilon * ulp);
458 typename std::enable_if_t<std::is_floating_point_v<T>,
bool>
459 almost_equal(
const T& a,
const T& b,
int ulp=1,
const T& epsilon=std::numeric_limits<T>::epsilon()) noexcept
461 const T diff = std::fabs(a-b);
462 if( ( diff <= epsilon * std::fabs(a+b) * ulp ) ||
463 ( diff < std::numeric_limits<T>::min() ) ) {
473 std::enable_if_t<std::is_floating_point_v<T>,
bool> =
true>
480 std::enable_if_t<std::is_floating_point_v<T>,
bool> =
true>
482 return arc_degree * (T)M_PI / (T)180.0;
487 std::enable_if_t<std::is_floating_point_v<T>,
bool> =
true>
489 return rad * (T)180.0 / (T)M_PI;
504 std::enable_if_t<std::is_floating_point_v<T>,
bool> =
true>
508 const bool rowMajorOrder,
const jau::nsize_t row)
noexcept {
535 std::enable_if_t<std::is_floating_point_v<T>,
bool> =
true>
536 std::string&
mat_to_string(std::string& sb,
const std::string& rowPrefix,
const std::string& f,
538 const bool rowMajorOrder)
noexcept {
539 sb.append(rowPrefix).append(
"{\n");
541 sb.append(rowPrefix).append(
" ");
545 sb.append(rowPrefix).append(
"}").append(
"\n");
std::string & row_to_string(std::string &sb, const std::string &f, const T a[], const jau::nsize_t rows, const jau::nsize_t columns, const bool rowMajorOrder, const jau::nsize_t row) noexcept
Appends a row of floating points to the given string sb
std::enable_if_t< std::is_floating_point_v< T >, bool > almost_equal(const T &a, const T &b, int ulp=1, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true, if both floating point values are equal in the sense that their potential difference is...
std::enable_if_t< std::is_floating_point_v< T >, bool > constexpr equals(const T &a, const T &b, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if both values are equal, i.e.
constexpr uint32_t bit_value(const float a) noexcept
Returns the unsigned integer representation according to IEEE 754 (IEC 559) single floating-point bit...
constexpr uint32_t const float_iec559_positive_inf_bitval
Positive infinity bit-value of IEEE 754 (IEC 559) single float-point bit layout, i....
constexpr float float_value(const uint32_t a) noexcept
Converting IEEE 754 (IEC 559) single floating-point bit layout to float, see bit_value()
std::string & mat_to_string(std::string &sb, const std::string &rowPrefix, const std::string &f, const T a[], const jau::nsize_t rows, const jau::nsize_t columns, const bool rowMajorOrder) noexcept
Appends a matrix of floating points to the given string sb
constexpr uint64_t const double_iec559_exp_mask
Exponent mask bits 52-62 of IEEE 754 (IEC 559) double double-point bit layout, i.e.
constexpr uint32_t const float_iec559_mant_mask
Mantissa mask bits 0-22 of IEEE 754 (IEC 559) single float-point bit layout, i.e.
std::enable_if_t< std::is_floating_point_v< T >, bool > constexpr equals_raw(const T &a, const T &b) noexcept
Returns true if both values are equal disregarding epsilon but considering NaN, -Inf and +Inf.
constexpr uint32_t const float_iec559_exp_mask
Exponent mask bits 23-30 of IEEE 754 (IEC 559) single float-point bit layout, i.e.
std::enable_if_t< std::is_floating_point_v< T >, T > machineEpsilon() noexcept
Calculates the smallest floating point value approximation the given type T can represent,...
constexpr uint64_t const double_iec559_sign_bit
Signed bit 63 of IEEE 754 (IEC 559) double double-point bit layout, i.e.
constexpr uint32_t const float_iec559_nan_bitval
NaN bit-value of IEEE 754 (IEC 559) single float-point bit layout, i.e.
constexpr uint64_t const double_iec559_mant_mask
Mantissa mask bits 0-51 of IEEE 754 (IEC 559) double double-point bit layout, i.e.
std::enable_if_t< std::is_floating_point_v< T >, bool > constexpr is_zero4f(const T &a, const T &b, const T &c, const T &d, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if all given values a, b, c and d are less than epsilon, w/ epsilon > 0.
constexpr T rad_to_adeg(const T rad) noexcept
Converts radians to arc-degree.
std::enable_if_t< std::is_floating_point_v< T >, bool > constexpr is_zero(const T &a, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if the given value is less than epsilon, w/ epsilon > 0.
constexpr T adeg_to_rad(const T arc_degree) noexcept
Converts arc-degree to radians.
constexpr uint32_t const float_iec559_negative_inf_bitval
Negative infinity bit-value of IEEE 754 (IEC 559) single float-point bit layout, i....
jau::uint_bytes_t< sizeof(double)> double_uint_t
jau::uint_bytes_t< sizeof(float)> float_uint_t
std::enable_if_t< std::is_floating_point_v< T >, bool > constexpr is_zero3f(const T &a, const T &b, const T &c, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if all given values a, b and c are less than epsilon, w/ epsilon > 0.
std::enable_if_t< std::is_floating_point_v< T >, bool > constexpr equals2(const T &a, const T &b, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if both values are equal, i.e.
jau::uint_bytes_t< sizeof(T)> bit_value_raw(const T a) noexcept
Returns the unsigned integer representation according to IEEE 754 (IEC 559) floating-point bit layout...
constexpr uint32_t const float_iec559_sign_bit
Signed bit 31 of IEEE 754 (IEC 559) single float-point bit layout, i.e.
constexpr int compare(const T a, const T b) noexcept
Returns -1, 0 or 1 if a is less, equal or greater than b, disregarding epsilon but considering NaN,...
std::enable_if_t< std::is_floating_point_v< T >, bool > constexpr is_zero2f(const T &a, const T &b, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if all given values a and b are less than epsilon, w/ epsilon > 0.
constexpr jau::sint_bytes_t< sizeof(T)> round_to_int(const T v) noexcept
Returns the rounded value cast to int.
constexpr uint64_t const double_iec559_negative_inf_bitval
Negative infinity bit-value of IEEE 754 (IEC 559) double double-point bit layout, i....
constexpr double double_value(const uint64_t a) noexcept
Converting IEEE 754 (IEC 559) double floating-point bit layout to double, see bit_value()
constexpr uint64_t const double_iec559_nan_bitval
NaN bit-value of IEEE 754 (IEC 559) double double-point bit layout, i.e.
std::enable_if_t< std::is_floating_point_v< T >, bool > constexpr is_zero_raw(const T &a) noexcept
Returns true if the given value is zero, disregarding epsilon but considering NaN,...
constexpr uint64_t const double_iec559_positive_inf_bitval
Positive infinity bit-value of IEEE 754 (IEC 559) double double-point bit layout, i....
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
typename sint_bytes< bytesize >::type sint_bytes_t
Alias template for sint_bytes.
typename uint_bytes< bytesize >::type uint_bytes_t
Alias template for uint_bytes.
std::string format_string(const char *format,...)
Returns a string according to printf() formatting rules and variable number of arguments following th...
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.