72 #ifndef ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
73 #define ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
77 #include <type_traits>
98 template <std::
size_t size>
123 using UInt =
unsigned long long;
126 template <
typename RawType>
170 template <
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);
326 template <
typename FloatType>
332 template <
typename RawType>
336 Bits x_bits = *
reinterpret_cast<const Bits*
>(&x);
344 template <
typename RawType, std::
size_t max_ulps = defaultMaxUlps<RawType>()>
345 bool isEqual(
const RawType& left,
const RawType& right) {
347 bool is_equal{
false};
349 if (not(isNan<RawType>(left) or isNan<RawType>(right))) {
351 Bits l_bits = *
reinterpret_cast<const Bits*
>(&left);
352 Bits r_bits = *
reinterpret_cast<const Bits*
>(&right);
359 template <std::
size_t max_ulps>
360 inline bool isEqual(
const float& left,
const float& right) {
361 return (isEqual<float, max_ulps>(left, right));
364 template <std::
size_t max_ulps>
365 inline bool isEqual(
const double& left,
const double& right) {
366 return (isEqual<double, max_ulps>(left, right));
369 template <
typename RawType, std::
size_t max_ulps = defaultMaxUlps<RawType>()>
370 inline bool isNotEqual(
const RawType& left,
const RawType& right) {
371 return (not isEqual<RawType, max_ulps>(left, right));
374 template <std::
size_t max_ulps>
375 inline bool isNotEqual(
const float& left,
const float& right) {
376 return (isNotEqual<float, max_ulps>(left, right));
379 template <std::
size_t max_ulps>
380 inline bool isNotEqual(
const double& left,
const double& right) {
381 return (isNotEqual<double, max_ulps>(left, right));
384 template <
typename RawType, std::
size_t max_ulps = defaultMaxUlps<RawType>()>
385 bool isLess(
const RawType& left,
const RawType& right) {
388 if (left < right && (not isEqual<RawType, max_ulps>(left, right))) {
395 template <std::
size_t max_ulps>
396 inline bool isLess(
const float& left,
const float& right) {
397 return (isLess<float, max_ulps>(left, right));
400 template <std::
size_t max_ulps>
401 inline bool isLess(
const double& left,
const double& right) {
402 return (isLess<double, max_ulps>(left, right));
405 template <
typename RawType, std::
size_t max_ulps = defaultMaxUlps<RawType>()>
406 bool isGreater(
const RawType& left,
const RawType& right) {
407 bool is_greater{
false};
409 if (left > right && (not isEqual<RawType, max_ulps>(left, right))) {
416 template <std::
size_t max_ulps>
417 inline bool isGreater(
const float& left,
const float& right) {
418 return (isGreater<float, max_ulps>(left, right));
421 template <std::
size_t max_ulps>
422 inline bool isGreater(
const double& left,
const double& right) {
423 return (isGreater<double, max_ulps>(left, right));
426 template <
typename RawType, std::
size_t max_ulps = defaultMaxUlps<RawType>()>
430 if (not isGreater<RawType, max_ulps>(left, right)) {
437 template <std::
size_t max_ulps>
439 return (isLessOrEqual<float, max_ulps>(left, right));
442 template <std::
size_t max_ulps>
444 return (isLessOrEqual<double, max_ulps>(left, right));
447 template <
typename RawType, std::
size_t max_ulps = defaultMaxUlps<RawType>()>
451 if (not isLess<RawType, max_ulps>(left, right)) {
458 template <std::
size_t max_ulps>
460 return (isGreaterOrEqual<float, max_ulps>(left, right));
463 template <std::
size_t max_ulps>
465 return (isGreaterOrEqual<double, max_ulps>(left, right));
518 template <
typename RawType>
520 #pragma GCC diagnostic push
521 #pragma GCC diagnostic ignored "-Wfloat-equal"
522 return (left == right);
523 #pragma GCC diagnostic pop
528 #endif // ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
Bits exponentBits() const
bool isGreaterOrEqual(const RawType &left, const RawType &right)
static Bits signAndMagnitudeToBiased(const Bits &sam)
Bits fractionBits() const
Macro to silence unused variables warnings from the compiler.
static RawType ReinterpretBits(const Bits &bits)
ELEMENTS_API const double DBL_DEFAULT_TEST_TOLERANCE
Double precision float default test tolerance.
constexpr std::size_t FLT_DEFAULT_MAX_ULPS
Single precision float default maximum unit in the last place.
bool almostEqual2sComplement(ELEMENTS_UNUSED const FloatType &a, ELEMENTS_UNUSED const FloatType &b, ELEMENTS_UNUSED const std::size_t &max_ulps=0)
typename TypeWithSize< sizeof(RawType)>::UInt Bits
bool isGreater(const RawType &left, const RawType &right)
defines the macros to be used for explicit export of the symbols
bool isLessOrEqual(const RawType &left, const RawType &right)
bool AlmostEquals(const FloatingPoint &rhs) const
constexpr std::size_t defaultMaxUlps< double >()
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 "=="...
#define ELEMENTS_API
Dummy definitions for the backward compatibility mode.
const Bits & bits() const
static Bits distanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, const Bits &sam2)
constexpr std::size_t defaultMaxUlps< float >()
static RawType Infinity()
bool isEqual(const RawType &left, const RawType &right)
bool isNan(const RawType &x)
bool isNotEqual(const RawType &left, const RawType &right)
constexpr std::size_t defaultMaxUlps()
bool isLess(const RawType &left, const RawType &right)
constexpr std::size_t DBL_DEFAULT_MAX_ULPS
Double precision float default maximum unit in the last place.
ELEMENTS_API const double FLT_DEFAULT_TEST_TOLERANCE
Single precision float default test tolerance.
FloatingPoint(const RawType &x)