72 #ifndef ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
73 #define ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
78 #include <type_traits>
99 template <std::
size_t size>
124 using UInt =
unsigned long long;
127 template <
typename RawType>
171 template <
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);
327 template <
typename FloatType>
333 template <
typename RawType>
336 using Bits =
typename TypeWithSize<
sizeof(RawType)>::UInt;
346 template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
347 bool 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;
363 template <std::
size_t max_ulps>
364 inline bool isEqual(
const float& left,
const float& right) {
365 return (isEqual<float, max_ulps>(left, right));
368 template <std::
size_t max_ulps>
369 inline bool isEqual(
const double& left,
const double& right) {
370 return (isEqual<double, max_ulps>(left, right));
373 template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
374 inline bool isNotEqual(
const RawType& left,
const RawType& right) {
375 return (not isEqual<RawType, max_ulps>(left, right));
378 template <std::
size_t max_ulps>
379 inline bool isNotEqual(
const float& left,
const float& right) {
380 return (isNotEqual<float, max_ulps>(left, right));
383 template <std::
size_t max_ulps>
384 inline bool isNotEqual(
const double& left,
const double& right) {
385 return (isNotEqual<double, max_ulps>(left, right));
388 template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
389 bool isLess(
const RawType& left,
const RawType& right) {
392 if (left < right && (not isEqual<RawType, max_ulps>(left, right))) {
399 template <std::
size_t max_ulps>
400 inline bool isLess(
const float& left,
const float& right) {
401 return (isLess<float, max_ulps>(left, right));
404 template <std::
size_t max_ulps>
405 inline bool isLess(
const double& left,
const double& right) {
406 return (isLess<double, max_ulps>(left, right));
409 template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
410 bool isGreater(
const RawType& left,
const RawType& right) {
411 bool is_greater{
false};
413 if (left > right && (not isEqual<RawType, max_ulps>(left, right))) {
420 template <std::
size_t max_ulps>
421 inline bool isGreater(
const float& left,
const float& right) {
422 return (isGreater<float, max_ulps>(left, right));
425 template <std::
size_t max_ulps>
426 inline bool isGreater(
const double& left,
const double& right) {
427 return (isGreater<double, max_ulps>(left, right));
430 template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
434 if (not isGreater<RawType, max_ulps>(left, right)) {
441 template <std::
size_t max_ulps>
443 return (isLessOrEqual<float, max_ulps>(left, right));
446 template <std::
size_t max_ulps>
448 return (isLessOrEqual<double, max_ulps>(left, right));
451 template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
455 if (not isLess<RawType, max_ulps>(left, right)) {
462 template <std::
size_t max_ulps>
464 return (isGreaterOrEqual<float, max_ulps>(left, right));
467 template <std::
size_t max_ulps>
469 return (isGreaterOrEqual<double, max_ulps>(left, right));
522 template <
typename RawType>
524 #pragma GCC diagnostic push
525 #pragma GCC diagnostic ignored "-Wfloat-equal"
526 return (left == right);
527 #pragma GCC diagnostic pop
532 #endif // ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_