TerraForge3D  2.3.1
3D Terrain And Landscape Generator

◆ mul()

static diyfp nlohmann::detail::dtoa_impl::diyfp::mul ( const diyfp x,
const diyfp y 
)
inlinestaticnoexcept

returns x * y

Note
The result is rounded. (Only the upper q bits are returned.)

Definition at line 15614 of file json.hpp.

15615 {
15616 static_assert(kPrecision == 64, "internal error");
15617 // Computes:
15618 // f = round((x.f * y.f) / 2^q)
15619 // e = x.e + y.e + q
15620 // Emulate the 64-bit * 64-bit multiplication:
15621 //
15622 // p = u * v
15623 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15624 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15625 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15626 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15627 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15628 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15629 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15630 //
15631 // (Since Q might be larger than 2^32 - 1)
15632 //
15633 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15634 //
15635 // (Q_hi + H does not overflow a 64-bit int)
15636 //
15637 // = p_lo + 2^64 p_hi
15638 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15639 const std::uint64_t u_hi = x.f >> 32u;
15640 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15641 const std::uint64_t v_hi = y.f >> 32u;
15642 const std::uint64_t p0 = u_lo * v_lo;
15643 const std::uint64_t p1 = u_lo * v_hi;
15644 const std::uint64_t p2 = u_hi * v_lo;
15645 const std::uint64_t p3 = u_hi * v_hi;
15646 const std::uint64_t p0_hi = p0 >> 32u;
15647 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15648 const std::uint64_t p1_hi = p1 >> 32u;
15649 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15650 const std::uint64_t p2_hi = p2 >> 32u;
15651 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15652 // The full product might now be computed as
15653 //
15654 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15655 // p_lo = p0_lo + (Q << 32)
15656 //
15657 // But in this particular case here, the full p_lo is not required.
15658 // Effectively we only need to add the highest bit in p_lo to p_hi (and
15659 // Q_hi + 1 does not overflow).
15660 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15661 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15662 return {h, x.e + y.e + 64};
15663 }