MCPcopy Create free account
hub / github.com/InteractiveComputerGraphics/SPlisHSPlasH / compute_boundaries

Function compute_boundaries

extern/json/json.hpp:17010–17075  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

17008*/
17009template<typename FloatType>
17010boundaries compute_boundaries(FloatType value)
17011{
17012 JSON_ASSERT(std::isfinite(value));
17013 JSON_ASSERT(value > 0);
17014
17015 // Convert the IEEE representation into a diyfp.
17016 //
17017 // If v is denormal:
17018 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
17019 // If v is normalized:
17020 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
17021
17022 static_assert(std::numeric_limits<FloatType>::is_iec559,
17023 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
17024
17025 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
17026 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
17027 constexpr int kMinExp = 1 - kBias;
17028 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
17029
17030 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
17031
17032 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
17033 const std::uint64_t E = bits >> (kPrecision - 1);
17034 const std::uint64_t F = bits & (kHiddenBit - 1);
17035
17036 const bool is_denormal = E == 0;
17037 const diyfp v = is_denormal
17038 ? diyfp(F, kMinExp)
17039 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
17040
17041 // Compute the boundaries m- and m+ of the floating-point value
17042 // v = f * 2^e.
17043 //
17044 // Determine v- and v+, the floating-point predecessor and successor if v,
17045 // respectively.
17046 //
17047 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
17048 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
17049 //
17050 // v+ = v + 2^e
17051 //
17052 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
17053 // between m- and m+ round to v, regardless of how the input rounding
17054 // algorithm breaks ties.
17055 //
17056 // ---+-------------+-------------+-------------+-------------+--- (A)
17057 // v- m- v m+ v+
17058 //
17059 // -----------------+------+------+-------------+-------------+--- (B)
17060 // v- m- v m+ v+
17061
17062 const bool lower_boundary_is_closer = F == 0 && E > 1;
17063 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
17064 const diyfp m_minus = lower_boundary_is_closer
17065 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
17066 : diyfp(2 * v.f - 1, v.e - 1); // (A)
17067

Callers 1

json.hppFile · 0.85

Calls 2

diyfpClass · 0.85
normalizeFunction · 0.85

Tested by

no test coverage detected