72#ifndef ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
73#define ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
99template <std::
size_t size>
124 using UInt =
unsigned long long;
127template <
typename RawType>
171template <
typename RawType>
187 static const std::size_t s_exponent_bitcount = s_bitcount - 1 - s_fraction_bitcount;
190 static const Bits s_sign_bitmask =
static_cast<Bits>(1) << (s_bitcount - 1);
193 static const Bits s_fraction_bitmask = ~static_cast<Bits>(0) >> (s_exponent_bitcount + 1);
196 static const Bits s_exponent_bitmask = ~(s_sign_bitmask | s_fraction_bitmask);
235 return ReinterpretBits(s_exponent_bitmask);
247 return s_exponent_bitmask & m_u.m_bits;
252 return s_fraction_bitmask & m_u.m_bits;
257 return s_sign_bitmask & m_u.m_bits;
264 return (exponentBits() == s_exponent_bitmask) && (fractionBits() != 0);
279 return distanceBetweenSignAndMagnitudeNumbers(m_u.m_bits, rhs.
m_u.
m_bits) <= m_max_ulps;
298 if (s_sign_bitmask & sam) {
303 return s_sign_bitmask | sam;
310 const Bits biased1 = signAndMagnitudeToBiased(sam1);
311 const Bits biased2 = signAndMagnitudeToBiased(sam2);
312 return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
327template <
typename FloatType>
333template <
typename RawType>
336 using Bits =
typename TypeWithSize<
sizeof(RawType)>::UInt;
346template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
347bool isEqual(
const RawType& left,
const RawType& right) {
349 bool is_equal{
false};
351 if (not(isNan<RawType>(left) or isNan<RawType>(right))) {
352 using Bits =
typename TypeWithSize<
sizeof(RawType)>::UInt;
363template <std::
size_t max_ulps>
364inline bool isEqual(
const float& left,
const float& right) {
365 return (isEqual<float, max_ulps>(left, right));
368template <std::
size_t max_ulps>
369inline bool isEqual(
const double& left,
const double& right) {
370 return (isEqual<double, max_ulps>(left, right));
373template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
374inline bool isNotEqual(
const RawType& left,
const RawType& right) {
375 return (not isEqual<RawType, max_ulps>(left, right));
378template <std::
size_t max_ulps>
379inline bool isNotEqual(
const float& left,
const float& right) {
380 return (isNotEqual<float, max_ulps>(left, right));
383template <std::
size_t max_ulps>
384inline bool isNotEqual(
const double& left,
const double& right) {
385 return (isNotEqual<double, max_ulps>(left, right));
388template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
389bool isLess(
const RawType& left,
const RawType& right) {
392 if (left < right && (not isEqual<RawType, max_ulps>(left, right))) {
399template <std::
size_t max_ulps>
400inline bool isLess(
const float& left,
const float& right) {
401 return (isLess<float, max_ulps>(left, right));
404template <std::
size_t max_ulps>
405inline bool isLess(
const double& left,
const double& right) {
406 return (isLess<double, max_ulps>(left, right));
409template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
410bool isGreater(
const RawType& left,
const RawType& right) {
411 bool is_greater{
false};
413 if (left > right && (not isEqual<RawType, max_ulps>(left, right))) {
420template <std::
size_t max_ulps>
421inline bool isGreater(
const float& left,
const float& right) {
422 return (isGreater<float, max_ulps>(left, right));
425template <std::
size_t max_ulps>
426inline bool isGreater(
const double& left,
const double& right) {
427 return (isGreater<double, max_ulps>(left, right));
430template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
434 if (not isGreater<RawType, max_ulps>(left, right)) {
441template <std::
size_t max_ulps>
443 return (isLessOrEqual<float, max_ulps>(left, right));
446template <std::
size_t max_ulps>
448 return (isLessOrEqual<double, max_ulps>(left, right));
451template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
455 if (not isLess<RawType, max_ulps>(left, right)) {
462template <std::
size_t max_ulps>
464 return (isGreaterOrEqual<float, max_ulps>(left, right));
467template <std::
size_t max_ulps>
469 return (isGreaterOrEqual<double, max_ulps>(left, right));
522template <
typename RawType>
524#pragma GCC diagnostic push
525#pragma GCC diagnostic ignored "-Wfloat-equal"
526 return (left == right);
527#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)