MCPcopy Create free account
hub / github.com/OpenFodder/openfodder / diyfp

Class diyfp

Source/Utils/json.hpp:14388–14504  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

14386 }
14387
14388 struct diyfp // f * 2^e
14389 {
14390 static constexpr int kPrecision = 64; // = q
14391
14392 std::uint64_t f = 0;
14393 int e = 0;
14394
14395 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
14396
14397 /*!
14398 @brief returns x - y
14399 @pre x.e == y.e and x.f >= y.f
14400 */
14401 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
14402 {
14403 JSON_ASSERT(x.e == y.e);
14404 JSON_ASSERT(x.f >= y.f);
14405
14406 return { x.f - y.f, x.e };
14407 }
14408
14409 /*!
14410 @brief returns x * y
14411 @note The result is rounded. (Only the upper q bits are returned.)
14412 */
14413 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
14414 {
14415 static_assert(kPrecision == 64, "internal error");
14416
14417 // Computes:
14418 // f = round((x.f * y.f) / 2^q)
14419 // e = x.e + y.e + q
14420
14421 // Emulate the 64-bit * 64-bit multiplication:
14422 //
14423 // p = u * v
14424 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
14425 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
14426 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
14427 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
14428 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
14429 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
14430 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
14431 //
14432 // (Since Q might be larger than 2^32 - 1)
14433 //
14434 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
14435 //
14436 // (Q_hi + H does not overflow a 64-bit int)
14437 //
14438 // = p_lo + 2^64 p_hi
14439
14440 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
14441 const std::uint64_t u_hi = x.f >> 32u;
14442 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
14443 const std::uint64_t v_hi = y.f >> 32u;
14444
14445 const std::uint64_t p0 = u_lo * v_lo;

Callers 1

compute_boundariesFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected