Version: SMASH-3.2.2
smash::detail Namespace Reference

Functions

template<typename T >
constexpr auto type_name ()
 Get type of variable as string in a human-readable way. More...
 
template<typename N , typename = std::enable_if_t<std::is_floating_point_v<N>>>
bool almost_equal_knuthish (const N x, const N y, const N epsilon, const N threshold=N{0.0}) noexcept
 Compare whether two floating-point numbers are approximately equal à la Knuth up to a given tolerance. More...
 

Function Documentation

◆ type_name()

template<typename T >
constexpr auto smash::detail::type_name ( )
constexpr

Get type of variable as string in a human-readable way.

Template Parameters
TThe type to be returned.
Returns
A std::string containing the name of the type.

Definition at line 27 of file numeric_cast.h.

27  {
28  std::string_view name, prefix, suffix;
29 #ifdef __clang__
30  name = __PRETTY_FUNCTION__;
31  prefix = "auto smash::detail::type_name() [T = ";
32  suffix = "]";
33 #elif defined(__GNUC__)
34  name = __PRETTY_FUNCTION__;
35  prefix = "constexpr auto smash::detail::type_name() [with T = ";
36  suffix = "]";
37 #elif defined(_MSC_VER)
38  name = __FUNCSIG__;
39  prefix = "auto __cdecl smash::detail::type_name<";
40  suffix = ">(void)";
41 #else
42  name = "UNKNOWN";
43  prefix = "";
44  suffix = "";
45 #endif
46  name.remove_prefix(prefix.size());
47  name.remove_suffix(suffix.size());
48  return std::string{name};
49 }

◆ almost_equal_knuthish()

template<typename N , typename = std::enable_if_t<std::is_floating_point_v<N>>>
bool smash::detail::almost_equal_knuthish ( const N  x,
const N  y,
const N  epsilon,
const N  threshold = N{0.0} 
)
noexcept

Compare whether two floating-point numbers are approximately equal à la Knuth up to a given tolerance.

On top of Knuth's tolerance predicate some corner cases are treated and the caller can specify a threshold as last parameter to make the test consider numbers equal if the absolute value of their difference is below of it.

Parameters
[in]xFirst of the two numbers.
[in]ySecond of the two numbers.
[in]epsilonThe relative tolerance for the test.
[in]thresholdThreshold for the number comparison. By default this is zero, implying no threshold is considered.
Returns
false if either x or y is not a finite number, provided that the type supports non-numeric representations (i.e. is infinite or NAN);
true if x == y;
true if x == 0 and if \( |x| \le \varepsilon\);
true if y == 0 and if \( |y| \le \varepsilon\);
true if \( |x - y| \le M_\mathrm{threshold} \);
true if \( |x - y| \le \varepsilon \cdot \max(|x|, |y|) \) (Knuth's tolerance predicate);
false otherwise.

Definition at line 59 of file numerics.h.

60  {0.0}) noexcept {
61  assert(epsilon > 0);
62  assert(threshold >= 0);
63  if constexpr (std::numeric_limits<N>::is_iec559) {
64  if (!std::isfinite(x) || !std::isfinite(y)) {
65  return false;
66  }
67  }
68  if (x == y)
69  return true;
70  else if (x == 0)
71  return std::abs(y) <= epsilon;
72  else if (y == 0)
73  return std::abs(x) <= epsilon;
74  else
75  return std::abs(x - y) <= threshold ||
76  std::abs(x - y) <= epsilon * std::max(std::abs(x), std::abs(y));
77 }