ATLAS Offline Software
Static Public Member Functions | List of all members
FloatingPointHelpers::ConversionHelper< FLarge, FSmall > Struct Template Reference

#include <FPHelpers.h>

Collaboration diagram for FloatingPointHelpers::ConversionHelper< FLarge, FSmall >:

Static Public Member Functions

template<class T >
constexpr static T down_convert (const T pattern, const RoundingModes rt=RoundingModes::Default)
 
template<class T >
constexpr static T up_convert (const T pattern, [[maybe_unused]] const RoundingModes rt=RoundingModes::Default)
 

Detailed Description

template<class FLarge, class FSmall>
struct FloatingPointHelpers::ConversionHelper< FLarge, FSmall >

Definition at line 707 of file FPHelpers.h.

Member Function Documentation

◆ down_convert()

template<class FLarge , class FSmall >
template<class T >
constexpr static T FloatingPointHelpers::ConversionHelper< FLarge, FSmall >::down_convert ( const pattern,
const RoundingModes  rt = RoundingModes::Default 
)
inlinestaticconstexpr

Definition at line 714 of file FPHelpers.h.

715  {
716  using FDest = FSmall;
717  using FSource = FLarge;
718  using namespace OperatorsHelper;
719 
720  const bool sign_bit = pattern & FSource::template sign_mask<T>();
721 
722  const T exponent = (pattern & FSource::template exponent_mask<T>()) >> FSource::mantissa_size_bits();
723  const T mantissa = pattern & FSource::template mantissa_mask<T>();
724 
725  constexpr T delta_exponents = FSource::template exponent_bias<T>() - FDest::template exponent_bias<T>();
726 
727  const bool exponent_full = (exponent > delta_exponents + FDest::template max_exponent_with_bias<T>());
728  const bool delete_mantissa = exponent_full && exponent <= FSource::template max_exponent_with_bias<T>();
729  //If the number is clamped to infinity, we must delete the mantissa
730  //so we don't get a NaN!
731  const bool denormal = exponent <= delta_exponents;
732  const bool zero = exponent + FDest::mantissa_size_bits() <= delta_exponents;
733 
734  const T final_exponent = min(clamped_sub(exponent, delta_exponents), FDest::template max_exponent_with_bias<T>() + 1);
735 
736  const T extra_mantissa_shift = clamped_sub(delta_exponents + 1, exponent) * denormal;
737  const T total_mantissa_shift = (FSource::mantissa_size_bits() - FDest::mantissa_size_bits()) + extra_mantissa_shift;
738 
739  const T mantissa_keep_mask = safe_lshift(FDest::template mantissa_mask<T>(), total_mantissa_shift) & FSource::template mantissa_mask<T>();
740  const T check_for_rounding_mask = FSource::template mantissa_mask<T>() & (~mantissa_keep_mask);
741  const T last_mantissa_bit = safe_lshift(FDest::template mantissa_mask<T>(), total_mantissa_shift) & FSource::template mantissa_mask<T>();
742  const T first_discarded_bit_mask = last_mantissa_bit >> 1;
743  //In case total_mantissa_shift == 0, this is 0 too.
744 
745  const T extra_denormal_bit = safe_rshift(T(denormal) << FDest::mantissa_size_bits(), extra_mantissa_shift);
746 
747  const bool round_up = (mantissa & check_for_rounding_mask) > first_discarded_bit_mask;
748  const bool tie_break = ((mantissa & check_for_rounding_mask) == first_discarded_bit_mask);
749 
750  const bool round_bit = FDest::template round_results<T>(sign_bit, mantissa & last_mantissa_bit, round_up, tie_break, rt) && !(exponent_full && !delete_mantissa && !denormal);
751  //The last part is so that NaN get truncated instead of rounded.
752 
753  T final_mantissa = (safe_rshift(mantissa, total_mantissa_shift) | extra_denormal_bit) + round_bit;
754 
755  final_mantissa *= !delete_mantissa;
756 
757  return sign_bit * FDest::template sign_mask<T>() | ((final_exponent << FDest::mantissa_size_bits()) | final_mantissa) * !zero;
758 
759  }

◆ up_convert()

template<class FLarge , class FSmall >
template<class T >
constexpr static T FloatingPointHelpers::ConversionHelper< FLarge, FSmall >::up_convert ( const pattern,
[[maybe_unused] ] const RoundingModes  rt = RoundingModes::Default 
)
inlinestaticconstexpr

Definition at line 762 of file FPHelpers.h.

763  {
764  using FDest = FLarge;
765  using FSource = FSmall;
766  using namespace OperatorsHelper;
767 
768  const bool sign_bit = pattern & FSource::template sign_mask<T>();
769  T exponent = (pattern & FSource::template exponent_mask<T>()) >> FSource::mantissa_size_bits();
770  T mantissa = pattern & FSource::template mantissa_mask<T>();
771 
772  constexpr T delta_exponents = (FDest::template exponent_bias<T>() - FSource::template exponent_bias<T>());
773 
774  if (exponent == 0 && FDest::exponent_size_bits() > FSource::exponent_size_bits())
775  {
776  const unsigned int leading_zeros = LeadingZerosPortability::count_leading_zeros<T>(mantissa);
777  const unsigned int shift_amount = leading_zeros - (sizeof(T) * CHAR_BIT - FSource::mantissa_size_bits()) + 1;
778  const unsigned int exponent_offset = (mantissa != 0) * (shift_amount - 1);
779  mantissa = (mantissa << shift_amount) & FSource::template mantissa_mask<T>();
780 
781  exponent = delta_exponents - exponent_offset;
782  }
783  else if (exponent > FSource::template max_exponent_with_bias<T>())
784  //Infinity or NaN
785  {
786  exponent = FDest::template max_exponent_with_bias<T>() + 1;
787  }
788  else
789  {
790  exponent = exponent + delta_exponents;
791  }
792 
793 
794  return sign_bit * FDest::template sign_mask<T>() | (exponent << FDest::mantissa_size_bits()) | (mantissa << (FDest::mantissa_size_bits() - FSource::mantissa_size_bits()));
795 
796  }

The documentation for this struct was generated from the following file:
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:26
taskman.template
dictionary template
Definition: taskman.py:317
min
#define min(a, b)
Definition: cfImp.cxx:40
zero
void zero(TH2 *h)
zero the contents of a 2d histogram
Definition: comparitor.cxx:435
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35