72#ifndef ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
73#define ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
98template <std::
size_t size>
123 using UInt =
unsigned long long;
126template <
typename RawType>
170template <
typename RawType>
186 static const std::size_t s_exponent_bitcount = s_bitcount - 1 - s_fraction_bitcount;
189 static const Bits s_sign_bitmask =
static_cast<Bits>(1) << (s_bitcount - 1);
192 static const Bits s_fraction_bitmask = ~static_cast<Bits>(0) >> (s_exponent_bitcount + 1);
195 static const Bits s_exponent_bitmask = ~(s_sign_bitmask | s_fraction_bitmask);
234 return ReinterpretBits(s_exponent_bitmask);
246 return s_exponent_bitmask & m_u.m_bits;
251 return s_fraction_bitmask & m_u.m_bits;
256 return s_sign_bitmask & m_u.m_bits;
263 return (exponentBits() == s_exponent_bitmask) && (fractionBits() != 0);
278 return distanceBetweenSignAndMagnitudeNumbers(m_u.m_bits, rhs.
m_u.
m_bits) <= m_max_ulps;
297 if (s_sign_bitmask & sam) {
302 return s_sign_bitmask | sam;
309 const Bits biased1 = signAndMagnitudeToBiased(sam1);
310 const Bits biased2 = signAndMagnitudeToBiased(sam2);
311 return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
326template <
typename FloatType>
332template <
typename RawType>
335 using Bits =
typename TypeWithSize<
sizeof(RawType)>::UInt;
336 Bits x_bits = *
reinterpret_cast<const Bits*
>(&x);
344template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
345bool isEqual(
const RawType& left,
const RawType& right) {
347 bool is_equal{
false};
349 if (not(isNan<RawType>(left) or isNan<RawType>(right))) {
350 using Bits =
typename TypeWithSize<
sizeof(RawType)>::UInt;
351 Bits l_bits = *
reinterpret_cast<const Bits*
>(&left);
352 Bits r_bits = *
reinterpret_cast<const Bits*
>(&right);
359template <std::
size_t max_ulps>
360inline bool isEqual(
const float& left,
const float& right) {
361 return (isEqual<float, max_ulps>(left, right));
364template <std::
size_t max_ulps>
365inline bool isEqual(
const double& left,
const double& right) {
366 return (isEqual<double, max_ulps>(left, right));
369template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
370inline bool isNotEqual(
const RawType& left,
const RawType& right) {
371 return (not isEqual<RawType, max_ulps>(left, right));
374template <std::
size_t max_ulps>
375inline bool isNotEqual(
const float& left,
const float& right) {
376 return (isNotEqual<float, max_ulps>(left, right));
379template <std::
size_t max_ulps>
380inline bool isNotEqual(
const double& left,
const double& right) {
381 return (isNotEqual<double, max_ulps>(left, right));
384template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
385bool isLess(
const RawType& left,
const RawType& right) {
388 if (left < right && (not isEqual<RawType, max_ulps>(left, right))) {
395template <std::
size_t max_ulps>
396inline bool isLess(
const float& left,
const float& right) {
397 return (isLess<float, max_ulps>(left, right));
400template <std::
size_t max_ulps>
401inline bool isLess(
const double& left,
const double& right) {
402 return (isLess<double, max_ulps>(left, right));
405template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
406bool isGreater(
const RawType& left,
const RawType& right) {
407 bool is_greater{
false};
409 if (left > right && (not isEqual<RawType, max_ulps>(left, right))) {
416template <std::
size_t max_ulps>
417inline bool isGreater(
const float& left,
const float& right) {
418 return (isGreater<float, max_ulps>(left, right));
421template <std::
size_t max_ulps>
422inline bool isGreater(
const double& left,
const double& right) {
423 return (isGreater<double, max_ulps>(left, right));
426template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
430 if (not isGreater<RawType, max_ulps>(left, right)) {
437template <std::
size_t max_ulps>
439 return (isLessOrEqual<float, max_ulps>(left, right));
442template <std::
size_t max_ulps>
444 return (isLessOrEqual<double, max_ulps>(left, right));
447template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
451 if (not isLess<RawType, max_ulps>(left, right)) {
458template <std::
size_t max_ulps>
460 return (isGreaterOrEqual<float, max_ulps>(left, right));
463template <std::
size_t max_ulps>
465 return (isGreaterOrEqual<double, max_ulps>(left, right));
518template <
typename RawType>
520#pragma GCC diagnostic push
521#pragma GCC diagnostic ignored "-Wfloat-equal"
522 return (left == right);
523#pragma GCC diagnostic pop
defines the macros to be used for explicit export of the symbols
Macro to silence unused variables warnings from the compiler.
Bits fractionBits() const
typename TypeWithSize< sizeof(RawType)>::UInt Bits
static RawType ReinterpretBits(const Bits &bits)
FloatingPoint(const RawType &x)
static Bits distanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, const Bits &sam2)
static Bits signAndMagnitudeToBiased(const Bits &sam)
static RawType Infinity()
bool AlmostEquals(const FloatingPoint &rhs) const
Bits exponentBits() const
const Bits & bits() const
#define ELEMENTS_API
Dummy definitions for the backward compatibility mode.
constexpr std::size_t defaultMaxUlps< float >()
bool almostEqual2sComplement(ELEMENTS_UNUSED const FloatType &a, ELEMENTS_UNUSED const FloatType &b, ELEMENTS_UNUSED const std::size_t &max_ulps=0)
ELEMENTS_API const double FLT_DEFAULT_TEST_TOLERANCE
Single precision float default test tolerance.
bool isLess(const RawType &left, const RawType &right)
constexpr std::size_t defaultMaxUlps()
constexpr std::size_t FLT_DEFAULT_MAX_ULPS
Single precision float default maximum unit in the last place.
ELEMENTS_API const double DBL_DEFAULT_TEST_TOLERANCE
Double precision float default test tolerance.
bool isNan(const RawType &x)
constexpr std::size_t DBL_DEFAULT_MAX_ULPS
Double precision float default maximum unit in the last place.
ELEMENTS_API bool realBitWiseEqual(const RawType &left, const RawType &right)
This function compares 2 floating point numbers bitwise. These are the strict equivalent of the "=="....
bool isGreaterOrEqual(const RawType &left, const RawType &right)
bool isLessOrEqual(const RawType &left, const RawType &right)
bool isNotEqual(const RawType &left, const RawType &right)
bool isGreater(const RawType &left, const RawType &right)
constexpr std::size_t defaultMaxUlps< double >()
bool isEqual(const RawType &left, const RawType &right)