Fast Methods for Cosmological Simulations
FastSim serves as a tool for quick N-body simulations in modified gravity.
nlohmann::detail::dtoa_impl::diyfp Struct Reference

#include <json.hpp>

Public Member Functions

constexpr diyfp (uint64_t f_, int e_) noexcept
 

Static Public Member Functions

static diyfp sub (const diyfp &x, const diyfp &y) noexcept
 returns x - y More...
 
static diyfp mul (const diyfp &x, const diyfp &y) noexcept
 returns x * y More...
 
static diyfp normalize (diyfp x) noexcept
 normalize x such that the significand is >= 2^(q-1) More...
 
static diyfp normalize_to (const diyfp &x, const int target_exponent) noexcept
 normalize x such that the result has the exponent E More...
 

Public Attributes

uint64_t f = 0
 
int e = 0
 

Static Public Attributes

static constexpr int kPrecision = 64
 

Detailed Description

Definition at line 9725 of file json.hpp.

Constructor & Destructor Documentation

constexpr nlohmann::detail::dtoa_impl::diyfp::diyfp ( uint64_t  f_,
int  e_ 
)
inlinenoexcept

Definition at line 9732 of file json.hpp.

Member Function Documentation

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 9750 of file json.hpp.

References ccl_test_distances::h, and x.

9751  {
9752  static_assert(kPrecision == 64, "internal error");
9753 
9754  // Computes:
9755  // f = round((x.f * y.f) / 2^q)
9756  // e = x.e + y.e + q
9757 
9758  // Emulate the 64-bit * 64-bit multiplication:
9759  //
9760  // p = u * v
9761  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
9762  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
9763  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
9764  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
9765  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
9766  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
9767  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
9768  //
9769  // (Since Q might be larger than 2^32 - 1)
9770  //
9771  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
9772  //
9773  // (Q_hi + H does not overflow a 64-bit int)
9774  //
9775  // = p_lo + 2^64 p_hi
9776 
9777  const uint64_t u_lo = x.f & 0xFFFFFFFF;
9778  const uint64_t u_hi = x.f >> 32;
9779  const uint64_t v_lo = y.f & 0xFFFFFFFF;
9780  const uint64_t v_hi = y.f >> 32;
9781 
9782  const uint64_t p0 = u_lo * v_lo;
9783  const uint64_t p1 = u_lo * v_hi;
9784  const uint64_t p2 = u_hi * v_lo;
9785  const uint64_t p3 = u_hi * v_hi;
9786 
9787  const uint64_t p0_hi = p0 >> 32;
9788  const uint64_t p1_lo = p1 & 0xFFFFFFFF;
9789  const uint64_t p1_hi = p1 >> 32;
9790  const uint64_t p2_lo = p2 & 0xFFFFFFFF;
9791  const uint64_t p2_hi = p2 >> 32;
9792 
9793  uint64_t Q = p0_hi + p1_lo + p2_lo;
9794 
9795  // The full product might now be computed as
9796  //
9797  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
9798  // p_lo = p0_lo + (Q << 32)
9799  //
9800  // But in this particular case here, the full p_lo is not required.
9801  // Effectively we only need to add the highest bit in p_lo to p_hi (and
9802  // Q_hi + 1 does not overflow).
9803 
9804  Q += uint64_t{1} << (64 - 32 - 1); // round, ties up
9805 
9806  const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
9807 
9808  return {h, x.e + y.e + 64};
9809  }
static constexpr int kPrecision
Definition: json.hpp:9727
static CCL_BEGIN_DECLS double x[111][8]
static diyfp nlohmann::detail::dtoa_impl::diyfp::normalize ( diyfp  x)
inlinestaticnoexcept

normalize x such that the significand is >= 2^(q-1)

Precondition
x.f != 0

Definition at line 9815 of file json.hpp.

References x.

9816  {
9817  assert(x.f != 0);
9818 
9819  while ((x.f >> 63) == 0)
9820  {
9821  x.f <<= 1;
9822  x.e--;
9823  }
9824 
9825  return x;
9826  }
static CCL_BEGIN_DECLS double x[111][8]
static diyfp nlohmann::detail::dtoa_impl::diyfp::normalize_to ( const diyfp x,
const int  target_exponent 
)
inlinestaticnoexcept

normalize x such that the result has the exponent E

Precondition
e >= x.e and the upper e - x.e bits of x.f must be zero.

Definition at line 9832 of file json.hpp.

References x.

9833  {
9834  const int delta = x.e - target_exponent;
9835 
9836  assert(delta >= 0);
9837  assert(((x.f << delta) >> delta) == x.f);
9838 
9839  return {x.f << delta, target_exponent};
9840  }
static CCL_BEGIN_DECLS double x[111][8]
static diyfp nlohmann::detail::dtoa_impl::diyfp::sub ( const diyfp x,
const diyfp y 
)
inlinestaticnoexcept

returns x - y

Precondition
x.e == y.e and x.f >= y.f

Definition at line 9738 of file json.hpp.

References x.

9739  {
9740  assert(x.e == y.e);
9741  assert(x.f >= y.f);
9742 
9743  return {x.f - y.f, x.e};
9744  }
static CCL_BEGIN_DECLS double x[111][8]

Member Data Documentation

int nlohmann::detail::dtoa_impl::diyfp::e = 0
uint64_t nlohmann::detail::dtoa_impl::diyfp::f = 0
constexpr int nlohmann::detail::dtoa_impl::diyfp::kPrecision = 64
static

Definition at line 9727 of file json.hpp.


The documentation for this struct was generated from the following file: