All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Functions | Variables
nlohmann::detail::dtoa_impl Namespace Reference

implements the Grisu2 algorithm for binary to decimal floating-point conversion. More...

Classes

struct  diyfp
 
struct  boundaries
 
struct  cached_power
 

Functions

template<typename Target , typename Source >
Target reinterpret_bits (const Source source)
 
template<typename FloatType >
boundaries compute_boundaries (FloatType value)
 
cached_power get_cached_power_for_binary_exponent (int e)
 
int find_largest_pow10 (const std::uint32_t n, std::uint32_t &pow10)
 
void grisu2_round (char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
 
void grisu2_digit_gen (char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
 
void grisu2 (char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
 
template<typename FloatType >
void grisu2 (char *buf, int &len, int &decimal_exponent, FloatType value)
 
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent (char *buf, int e)
 appends a decimal representation of e to buf More...
 
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer (char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
 prettify v = buf * 10^decimal_exponent More...
 

Variables

constexpr int kAlpha = -60
 
constexpr int kGamma = -32
 

Detailed Description

implements the Grisu2 algorithm for binary to decimal floating-point conversion.

This implementation is a slightly modified version of the reference implementation which may be obtained from http://florian.loitsch.com/publications (bench.tar.gz).

The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.

For a detailed description of the algorithm see:

[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming Language Design and Implementation, PLDI 2010 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately", Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language Design and Implementation, PLDI 1996

Function Documentation

JSON_HEDLEY_RETURNS_NON_NULL char* nlohmann::detail::dtoa_impl::append_exponent ( char *  buf,
int  e 
)
inline

appends a decimal representation of e to buf

Returns
a pointer to the element following the exponent.
Precondition
-1000 < e < 1000

Definition at line 13572 of file json.hpp.

13573 {
13574  assert(e > -1000);
13575  assert(e < 1000);
13576 
13577  if (e < 0)
13578  {
13579  e = -e;
13580  *buf++ = '-';
13581  }
13582  else
13583  {
13584  *buf++ = '+';
13585  }
13586 
13587  auto k = static_cast<std::uint32_t>(e);
13588  if (k < 10)
13589  {
13590  // Always print at least two digits in the exponent.
13591  // This is for compatibility with printf("%g").
13592  *buf++ = '0';
13593  *buf++ = static_cast<char>('0' + k);
13594  }
13595  else if (k < 100)
13596  {
13597  *buf++ = static_cast<char>('0' + k / 10);
13598  k %= 10;
13599  *buf++ = static_cast<char>('0' + k);
13600  }
13601  else
13602  {
13603  *buf++ = static_cast<char>('0' + k / 100);
13604  k %= 100;
13605  *buf++ = static_cast<char>('0' + k / 10);
13606  k %= 10;
13607  *buf++ = static_cast<char>('0' + k);
13608  }
13609 
13610  return buf;
13611 }
do i e
pdgs k
Definition: selectors.fcl:22
template<typename FloatType >
boundaries nlohmann::detail::dtoa_impl::compute_boundaries ( FloatType  value)

Compute the (normalized) diyfp representing the input number 'value' and its boundaries.

Precondition
value must be finite and positive

Definition at line 12831 of file json.hpp.

12832 {
12833  assert(std::isfinite(value));
12834  assert(value > 0);
12835 
12836  // Convert the IEEE representation into a diyfp.
12837  //
12838  // If v is denormal:
12839  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
12840  // If v is normalized:
12841  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
12842 
12843  static_assert(std::numeric_limits<FloatType>::is_iec559,
12844  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
12845 
12846  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
12847  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
12848  constexpr int kMinExp = 1 - kBias;
12849  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
12850 
12852 
12853  const std::uint64_t bits = reinterpret_bits<bits_type>(value);
12854  const std::uint64_t E = bits >> (kPrecision - 1);
12855  const std::uint64_t F = bits & (kHiddenBit - 1);
12856 
12857  const bool is_denormal = E == 0;
12858  const diyfp v = is_denormal
12859  ? diyfp(F, kMinExp)
12860  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
12861 
12862  // Compute the boundaries m- and m+ of the floating-point value
12863  // v = f * 2^e.
12864  //
12865  // Determine v- and v+, the floating-point predecessor and successor if v,
12866  // respectively.
12867  //
12868  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
12869  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
12870  //
12871  // v+ = v + 2^e
12872  //
12873  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
12874  // between m- and m+ round to v, regardless of how the input rounding
12875  // algorithm breaks ties.
12876  //
12877  // ---+-------------+-------------+-------------+-------------+--- (A)
12878  // v- m- v m+ v+
12879  //
12880  // -----------------+------+------+-------------+-------------+--- (B)
12881  // v- m- v m+ v+
12882 
12883  const bool lower_boundary_is_closer = F == 0 and E > 1;
12884  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
12885  const diyfp m_minus = lower_boundary_is_closer
12886  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
12887  : diyfp(2 * v.f - 1, v.e - 1); // (A)
12888 
12889  // Determine the normalized w+ = m+.
12890  const diyfp w_plus = diyfp::normalize(m_plus);
12891 
12892  // Determine w- = m- such that e_(w-) = e_(w+).
12893  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
12894 
12895  return {diyfp::normalize(v), w_minus, w_plus};
12896 }
process_name E
bool isfinite(Vector const &v)
Returns whether all components of the vector are finite.
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
do i e
temporary value
Vector normalize(Vector const &v)
Returns a vector parallel to v and with norm 1.
int nlohmann::detail::dtoa_impl::find_largest_pow10 ( const std::uint32_t  n,
std::uint32_t &  pow10 
)
inline

For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k. For n == 0, returns 1 and sets pow10 := 1.

Definition at line 13134 of file json.hpp.

13135 {
13136  // LCOV_EXCL_START
13137  if (n >= 1000000000)
13138  {
13139  pow10 = 1000000000;
13140  return 10;
13141  }
13142  // LCOV_EXCL_STOP
13143  else if (n >= 100000000)
13144  {
13145  pow10 = 100000000;
13146  return 9;
13147  }
13148  else if (n >= 10000000)
13149  {
13150  pow10 = 10000000;
13151  return 8;
13152  }
13153  else if (n >= 1000000)
13154  {
13155  pow10 = 1000000;
13156  return 7;
13157  }
13158  else if (n >= 100000)
13159  {
13160  pow10 = 100000;
13161  return 6;
13162  }
13163  else if (n >= 10000)
13164  {
13165  pow10 = 10000;
13166  return 5;
13167  }
13168  else if (n >= 1000)
13169  {
13170  pow10 = 1000;
13171  return 4;
13172  }
13173  else if (n >= 100)
13174  {
13175  pow10 = 100;
13176  return 3;
13177  }
13178  else if (n >= 10)
13179  {
13180  pow10 = 10;
13181  return 2;
13182  }
13183  else
13184  {
13185  pow10 = 1;
13186  return 1;
13187  }
13188 }
JSON_HEDLEY_RETURNS_NON_NULL char* nlohmann::detail::dtoa_impl::format_buffer ( char *  buf,
int  len,
int  decimal_exponent,
int  min_exp,
int  max_exp 
)
inline

prettify v = buf * 10^decimal_exponent

If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point notation. Otherwise it will be printed in exponential notation.

Precondition
min_exp < 0
max_exp > 0

Definition at line 13624 of file json.hpp.

13626 {
13627  assert(min_exp < 0);
13628  assert(max_exp > 0);
13629 
13630  const int k = len;
13631  const int n = len + decimal_exponent;
13632 
13633  // v = buf * 10^(n-k)
13634  // k is the length of the buffer (number of decimal digits)
13635  // n is the position of the decimal point relative to the start of the buffer.
13636 
13637  if (k <= n and n <= max_exp)
13638  {
13639  // digits[000]
13640  // len <= max_exp + 2
13641 
13642  std::memset(buf + k, '0', static_cast<size_t>(n - k));
13643  // Make it look like a floating-point number (#362, #378)
13644  buf[n + 0] = '.';
13645  buf[n + 1] = '0';
13646  return buf + (n + 2);
13647  }
13648 
13649  if (0 < n and n <= max_exp)
13650  {
13651  // dig.its
13652  // len <= max_digits10 + 1
13653 
13654  assert(k > n);
13655 
13656  std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
13657  buf[n] = '.';
13658  return buf + (k + 1);
13659  }
13660 
13661  if (min_exp < n and n <= 0)
13662  {
13663  // 0.[000]digits
13664  // len <= 2 + (-min_exp - 1) + max_digits10
13665 
13666  std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
13667  buf[0] = '0';
13668  buf[1] = '.';
13669  std::memset(buf + 2, '0', static_cast<size_t>(-n));
13670  return buf + (2 + (-n) + k);
13671  }
13672 
13673  if (k == 1)
13674  {
13675  // dE+123
13676  // len <= 1 + 5
13677 
13678  buf += 1;
13679  }
13680  else
13681  {
13682  // d.igitsE+123
13683  // len <= max_digits10 + 1 + 5
13684 
13685  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
13686  buf[1] = '.';
13687  buf += 1 + k;
13688  }
13689 
13690  *buf++ = 'e';
13691  return append_exponent(buf, n - 1);
13692 }
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:13572
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
pdgs k
Definition: selectors.fcl:22
cached_power nlohmann::detail::dtoa_impl::get_cached_power_for_binary_exponent ( int  e)
inline

For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c satisfies (Definition 3.2 from [1])

 alpha <= e_c + e + q <= gamma.

Definition at line 12970 of file json.hpp.

12971 {
12972  // Now
12973  //
12974  // alpha <= e_c + e + q <= gamma (1)
12975  // ==> f_c * 2^alpha <= c * 2^e * 2^q
12976  //
12977  // and since the c's are normalized, 2^(q-1) <= f_c,
12978  //
12979  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
12980  // ==> 2^(alpha - e - 1) <= c
12981  //
12982  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
12983  //
12984  // k = ceil( log_10( 2^(alpha - e - 1) ) )
12985  // = ceil( (alpha - e - 1) * log_10(2) )
12986  //
12987  // From the paper:
12988  // "In theory the result of the procedure could be wrong since c is rounded,
12989  // and the computation itself is approximated [...]. In practice, however,
12990  // this simple function is sufficient."
12991  //
12992  // For IEEE double precision floating-point numbers converted into
12993  // normalized diyfp's w = f * 2^e, with q = 64,
12994  //
12995  // e >= -1022 (min IEEE exponent)
12996  // -52 (p - 1)
12997  // -52 (p - 1, possibly normalize denormal IEEE numbers)
12998  // -11 (normalize the diyfp)
12999  // = -1137
13000  //
13001  // and
13002  //
13003  // e <= +1023 (max IEEE exponent)
13004  // -52 (p - 1)
13005  // -11 (normalize the diyfp)
13006  // = 960
13007  //
13008  // This binary exponent range [-1137,960] results in a decimal exponent
13009  // range [-307,324]. One does not need to store a cached power for each
13010  // k in this range. For each such k it suffices to find a cached power
13011  // such that the exponent of the product lies in [alpha,gamma].
13012  // This implies that the difference of the decimal exponents of adjacent
13013  // table entries must be less than or equal to
13014  //
13015  // floor( (gamma - alpha) * log_10(2) ) = 8.
13016  //
13017  // (A smaller distance gamma-alpha would require a larger table.)
13018 
13019  // NB:
13020  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
13021 
13022  constexpr int kCachedPowersMinDecExp = -300;
13023  constexpr int kCachedPowersDecStep = 8;
13024 
13025  static constexpr std::array<cached_power, 79> kCachedPowers =
13026  {
13027  {
13028  { 0xAB70FE17C79AC6CA, -1060, -300 },
13029  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
13030  { 0xBE5691EF416BD60C, -1007, -284 },
13031  { 0x8DD01FAD907FFC3C, -980, -276 },
13032  { 0xD3515C2831559A83, -954, -268 },
13033  { 0x9D71AC8FADA6C9B5, -927, -260 },
13034  { 0xEA9C227723EE8BCB, -901, -252 },
13035  { 0xAECC49914078536D, -874, -244 },
13036  { 0x823C12795DB6CE57, -847, -236 },
13037  { 0xC21094364DFB5637, -821, -228 },
13038  { 0x9096EA6F3848984F, -794, -220 },
13039  { 0xD77485CB25823AC7, -768, -212 },
13040  { 0xA086CFCD97BF97F4, -741, -204 },
13041  { 0xEF340A98172AACE5, -715, -196 },
13042  { 0xB23867FB2A35B28E, -688, -188 },
13043  { 0x84C8D4DFD2C63F3B, -661, -180 },
13044  { 0xC5DD44271AD3CDBA, -635, -172 },
13045  { 0x936B9FCEBB25C996, -608, -164 },
13046  { 0xDBAC6C247D62A584, -582, -156 },
13047  { 0xA3AB66580D5FDAF6, -555, -148 },
13048  { 0xF3E2F893DEC3F126, -529, -140 },
13049  { 0xB5B5ADA8AAFF80B8, -502, -132 },
13050  { 0x87625F056C7C4A8B, -475, -124 },
13051  { 0xC9BCFF6034C13053, -449, -116 },
13052  { 0x964E858C91BA2655, -422, -108 },
13053  { 0xDFF9772470297EBD, -396, -100 },
13054  { 0xA6DFBD9FB8E5B88F, -369, -92 },
13055  { 0xF8A95FCF88747D94, -343, -84 },
13056  { 0xB94470938FA89BCF, -316, -76 },
13057  { 0x8A08F0F8BF0F156B, -289, -68 },
13058  { 0xCDB02555653131B6, -263, -60 },
13059  { 0x993FE2C6D07B7FAC, -236, -52 },
13060  { 0xE45C10C42A2B3B06, -210, -44 },
13061  { 0xAA242499697392D3, -183, -36 },
13062  { 0xFD87B5F28300CA0E, -157, -28 },
13063  { 0xBCE5086492111AEB, -130, -20 },
13064  { 0x8CBCCC096F5088CC, -103, -12 },
13065  { 0xD1B71758E219652C, -77, -4 },
13066  { 0x9C40000000000000, -50, 4 },
13067  { 0xE8D4A51000000000, -24, 12 },
13068  { 0xAD78EBC5AC620000, 3, 20 },
13069  { 0x813F3978F8940984, 30, 28 },
13070  { 0xC097CE7BC90715B3, 56, 36 },
13071  { 0x8F7E32CE7BEA5C70, 83, 44 },
13072  { 0xD5D238A4ABE98068, 109, 52 },
13073  { 0x9F4F2726179A2245, 136, 60 },
13074  { 0xED63A231D4C4FB27, 162, 68 },
13075  { 0xB0DE65388CC8ADA8, 189, 76 },
13076  { 0x83C7088E1AAB65DB, 216, 84 },
13077  { 0xC45D1DF942711D9A, 242, 92 },
13078  { 0x924D692CA61BE758, 269, 100 },
13079  { 0xDA01EE641A708DEA, 295, 108 },
13080  { 0xA26DA3999AEF774A, 322, 116 },
13081  { 0xF209787BB47D6B85, 348, 124 },
13082  { 0xB454E4A179DD1877, 375, 132 },
13083  { 0x865B86925B9BC5C2, 402, 140 },
13084  { 0xC83553C5C8965D3D, 428, 148 },
13085  { 0x952AB45CFA97A0B3, 455, 156 },
13086  { 0xDE469FBD99A05FE3, 481, 164 },
13087  { 0xA59BC234DB398C25, 508, 172 },
13088  { 0xF6C69A72A3989F5C, 534, 180 },
13089  { 0xB7DCBF5354E9BECE, 561, 188 },
13090  { 0x88FCF317F22241E2, 588, 196 },
13091  { 0xCC20CE9BD35C78A5, 614, 204 },
13092  { 0x98165AF37B2153DF, 641, 212 },
13093  { 0xE2A0B5DC971F303A, 667, 220 },
13094  { 0xA8D9D1535CE3B396, 694, 228 },
13095  { 0xFB9B7CD9A4A7443C, 720, 236 },
13096  { 0xBB764C4CA7A44410, 747, 244 },
13097  { 0x8BAB8EEFB6409C1A, 774, 252 },
13098  { 0xD01FEF10A657842C, 800, 260 },
13099  { 0x9B10A4E5E9913129, 827, 268 },
13100  { 0xE7109BFBA19C0C9D, 853, 276 },
13101  { 0xAC2820D9623BF429, 880, 284 },
13102  { 0x80444B5E7AA7CF85, 907, 292 },
13103  { 0xBF21E44003ACDD2D, 933, 300 },
13104  { 0x8E679C2F5E44FF8F, 960, 308 },
13105  { 0xD433179D9C8CB841, 986, 316 },
13106  { 0x9E19DB92B4E31BA9, 1013, 324 },
13107  }
13108  };
13109 
13110  // This computation gives exactly the same results for k as
13111  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
13112  // for |e| <= 1500, but doesn't require floating-point operations.
13113  // NB: log_10(2) ~= 78913 / 2^18
13114  assert(e >= -1500);
13115  assert(e <= 1500);
13116  const int f = kAlpha - e - 1;
13117  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
13118 
13119  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
13120  assert(index >= 0);
13121  assert(static_cast<std::size_t>(index) < kCachedPowers.size());
13122 
13123  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
13124  assert(kAlpha <= cached.e + e + 64);
13125  assert(kGamma >= cached.e + e + 64);
13126 
13127  return cached;
13128 }
do i e
pdgs k
Definition: selectors.fcl:22
void nlohmann::detail::dtoa_impl::grisu2 ( char *  buf,
int &  len,
int &  decimal_exponent,
diyfp  m_minus,
diyfp  v,
diyfp  m_plus 
)
inline

v = buf * 10^decimal_exponent len is the length of the buffer (number of decimal digits) The buffer must be large enough, i.e. >= max_digits10.

Definition at line 13472 of file json.hpp.

13474 {
13475  assert(m_plus.e == m_minus.e);
13476  assert(m_plus.e == v.e);
13477 
13478  // --------(-----------------------+-----------------------)-------- (A)
13479  // m- v m+
13480  //
13481  // --------------------(-----------+-----------------------)-------- (B)
13482  // m- v m+
13483  //
13484  // First scale v (and m- and m+) such that the exponent is in the range
13485  // [alpha, gamma].
13486 
13487  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
13488 
13489  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
13490 
13491  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
13492  const diyfp w = diyfp::mul(v, c_minus_k);
13493  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
13494  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
13495 
13496  // ----(---+---)---------------(---+---)---------------(---+---)----
13497  // w- w w+
13498  // = c*m- = c*v = c*m+
13499  //
13500  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
13501  // w+ are now off by a small amount.
13502  // In fact:
13503  //
13504  // w - v * 10^k < 1 ulp
13505  //
13506  // To account for this inaccuracy, add resp. subtract 1 ulp.
13507  //
13508  // --------+---[---------------(---+---)---------------]---+--------
13509  // w- M- w M+ w+
13510  //
13511  // Now any number in [M-, M+] (bounds included) will round to w when input,
13512  // regardless of how the input rounding algorithm breaks ties.
13513  //
13514  // And digit_gen generates the shortest possible such number in [M-, M+].
13515  // Note that this does not mean that Grisu2 always generates the shortest
13516  // possible number in the interval (m-, m+).
13517  const diyfp M_minus(w_minus.f + 1, w_minus.e);
13518  const diyfp M_plus (w_plus.f - 1, w_plus.e );
13519 
13520  decimal_exponent = -cached.k; // = -(-k) = k
13521 
13522  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
13523 }
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:13231
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:12970
template<typename FloatType >
void nlohmann::detail::dtoa_impl::grisu2 ( char *  buf,
int &  len,
int &  decimal_exponent,
FloatType  value 
)

v = buf * 10^decimal_exponent len is the length of the buffer (number of decimal digits) The buffer must be large enough, i.e. >= max_digits10.

Definition at line 13532 of file json.hpp.

13533 {
13534  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
13535  "internal error: not enough precision");
13536 
13537  assert(std::isfinite(value));
13538  assert(value > 0);
13539 
13540  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
13541  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
13542  // decimal representations are not exactly "short".
13543  //
13544  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
13545  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
13546  // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
13547  // does.
13548  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
13549  // representation using the corresponding std::from_chars function recovers value exactly". That
13550  // indicates that single precision floating-point numbers should be recovered using
13551  // 'std::strtof'.
13552  //
13553  // NB: If the neighbors are computed for single-precision numbers, there is a single float
13554  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
13555  // value is off by 1 ulp.
13556 #if 0
13557  const boundaries w = compute_boundaries(static_cast<double>(value));
13558 #else
13559  const boundaries w = compute_boundaries(value);
13560 #endif
13561 
13562  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
13563 }
bool isfinite(Vector const &v)
Returns whether all components of the vector are finite.
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:12831
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:13472
temporary value
void nlohmann::detail::dtoa_impl::grisu2_digit_gen ( char *  buffer,
int &  length,
int &  decimal_exponent,
diyfp  M_minus,
diyfp  w,
diyfp  M_plus 
)
inline

Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+. M- and M+ must be normalized and share the same exponent -60 <= e <= -32.

Definition at line 13231 of file json.hpp.

13233 {
13234  static_assert(kAlpha >= -60, "internal error");
13235  static_assert(kGamma <= -32, "internal error");
13236 
13237  // Generates the digits (and the exponent) of a decimal floating-point
13238  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
13239  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
13240  //
13241  // <--------------------------- delta ---->
13242  // <---- dist --------->
13243  // --------------[------------------+-------------------]--------------
13244  // M- w M+
13245  //
13246  // Grisu2 generates the digits of M+ from left to right and stops as soon as
13247  // V is in [M-,M+].
13248 
13249  assert(M_plus.e >= kAlpha);
13250  assert(M_plus.e <= kGamma);
13251 
13252  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
13253  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
13254 
13255  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
13256  //
13257  // M+ = f * 2^e
13258  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
13259  // = ((p1 ) * 2^-e + (p2 )) * 2^e
13260  // = p1 + p2 * 2^e
13261 
13262  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
13263 
13264  auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
13265  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
13266 
13267  // 1)
13268  //
13269  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
13270 
13271  assert(p1 > 0);
13272 
13273  std::uint32_t pow10;
13274  const int k = find_largest_pow10(p1, pow10);
13275 
13276  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
13277  //
13278  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
13279  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
13280  //
13281  // M+ = p1 + p2 * 2^e
13282  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
13283  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
13284  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
13285  //
13286  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
13287  //
13288  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
13289  //
13290  // but stop as soon as
13291  //
13292  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
13293 
13294  int n = k;
13295  while (n > 0)
13296  {
13297  // Invariants:
13298  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
13299  // pow10 = 10^(n-1) <= p1 < 10^n
13300  //
13301  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
13302  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
13303  //
13304  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
13305  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
13306  //
13307  assert(d <= 9);
13308  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
13309  //
13310  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
13311  //
13312  p1 = r;
13313  n--;
13314  //
13315  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
13316  // pow10 = 10^n
13317  //
13318 
13319  // Now check if enough digits have been generated.
13320  // Compute
13321  //
13322  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
13323  //
13324  // Note:
13325  // Since rest and delta share the same exponent e, it suffices to
13326  // compare the significands.
13327  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
13328  if (rest <= delta)
13329  {
13330  // V = buffer * 10^n, with M- <= V <= M+.
13331 
13332  decimal_exponent += n;
13333 
13334  // We may now just stop. But instead look if the buffer could be
13335  // decremented to bring V closer to w.
13336  //
13337  // pow10 = 10^n is now 1 ulp in the decimal representation V.
13338  // The rounding procedure works with diyfp's with an implicit
13339  // exponent of e.
13340  //
13341  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
13342  //
13343  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
13344  grisu2_round(buffer, length, dist, delta, rest, ten_n);
13345 
13346  return;
13347  }
13348 
13349  pow10 /= 10;
13350  //
13351  // pow10 = 10^(n-1) <= p1 < 10^n
13352  // Invariants restored.
13353  }
13354 
13355  // 2)
13356  //
13357  // The digits of the integral part have been generated:
13358  //
13359  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
13360  // = buffer + p2 * 2^e
13361  //
13362  // Now generate the digits of the fractional part p2 * 2^e.
13363  //
13364  // Note:
13365  // No decimal point is generated: the exponent is adjusted instead.
13366  //
13367  // p2 actually represents the fraction
13368  //
13369  // p2 * 2^e
13370  // = p2 / 2^-e
13371  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
13372  //
13373  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
13374  //
13375  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
13376  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
13377  //
13378  // using
13379  //
13380  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
13381  // = ( d) * 2^-e + ( r)
13382  //
13383  // or
13384  // 10^m * p2 * 2^e = d + r * 2^e
13385  //
13386  // i.e.
13387  //
13388  // M+ = buffer + p2 * 2^e
13389  // = buffer + 10^-m * (d + r * 2^e)
13390  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
13391  //
13392  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
13393 
13394  assert(p2 > delta);
13395 
13396  int m = 0;
13397  for (;;)
13398  {
13399  // Invariant:
13400  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
13401  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
13402  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
13403  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
13404  //
13405  assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
13406  p2 *= 10;
13407  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
13408  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
13409  //
13410  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
13411  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
13412  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
13413  //
13414  assert(d <= 9);
13415  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
13416  //
13417  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
13418  //
13419  p2 = r;
13420  m++;
13421  //
13422  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
13423  // Invariant restored.
13424 
13425  // Check if enough digits have been generated.
13426  //
13427  // 10^-m * p2 * 2^e <= delta * 2^e
13428  // p2 * 2^e <= 10^m * delta * 2^e
13429  // p2 <= 10^m * delta
13430  delta *= 10;
13431  dist *= 10;
13432  if (p2 <= delta)
13433  {
13434  break;
13435  }
13436  }
13437 
13438  // V = buffer * 10^-m, with M- <= V <= M+.
13439 
13440  decimal_exponent -= m;
13441 
13442  // 1 ulp in the decimal representation is now 10^-m.
13443  // Since delta and dist are now scaled by 10^m, we need to do the
13444  // same with ulp in order to keep the units in sync.
13445  //
13446  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
13447  //
13448  const std::uint64_t ten_m = one.f;
13449  grisu2_round(buffer, length, dist, delta, p2, ten_m);
13450 
13451  // By construction this algorithm generates the shortest possible decimal
13452  // number (Loitsch, Theorem 6.2) which rounds back to w.
13453  // For an input number of precision p, at least
13454  //
13455  // N = 1 + ceil(p * log_10(2))
13456  //
13457  // decimal digits are sufficient to identify all binary floating-point
13458  // numbers (Matula, "In-and-Out conversions").
13459  // This implies that the algorithm does not produce more than N decimal
13460  // digits.
13461  //
13462  // N = 17 for p = 53 (IEEE double precision)
13463  // N = 9 for p = 24 (IEEE single precision)
13464 }
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.hpp:13190
tuple m
now if test mode generate materials, CRT shell, world, gdml header else just generate CRT shell for u...
then echo Cowardly refusing to create a new FHiCL file with the same name as the original one('${SourceName}')." >&2 exit 1 fi echo "'$
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:13134
pdgs k
Definition: selectors.fcl:22
esac echo uname r
physics associatedGroupsWithLeft p1
std::string sub(const std::string &a, const std::string &b)
Definition: TruthText.cxx:100
void nlohmann::detail::dtoa_impl::grisu2_round ( char *  buf,
int  len,
std::uint64_t  dist,
std::uint64_t  delta,
std::uint64_t  rest,
std::uint64_t  ten_k 
)
inline

Definition at line 13190 of file json.hpp.

13192 {
13193  assert(len >= 1);
13194  assert(dist <= delta);
13195  assert(rest <= delta);
13196  assert(ten_k > 0);
13197 
13198  // <--------------------------- delta ---->
13199  // <---- dist --------->
13200  // --------------[------------------+-------------------]--------------
13201  // M- w M+
13202  //
13203  // ten_k
13204  // <------>
13205  // <---- rest ---->
13206  // --------------[------------------+----+--------------]--------------
13207  // w V
13208  // = buf * 10^k
13209  //
13210  // ten_k represents a unit-in-the-last-place in the decimal representation
13211  // stored in buf.
13212  // Decrement buf by ten_k while this takes buf closer to w.
13213 
13214  // The tests are written in this order to avoid overflow in unsigned
13215  // integer arithmetic.
13216 
13217  while (rest < dist
13218  and delta - rest >= ten_k
13219  and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
13220  {
13221  assert(buf[len - 1] != '0');
13222  buf[len - 1]--;
13223  rest += ten_k;
13224  }
13225 }
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
template<typename Target , typename Source >
Target nlohmann::detail::dtoa_impl::reinterpret_bits ( const Source  source)

Definition at line 12690 of file json.hpp.

12691 {
12692  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
12693 
12694  Target target;
12695  std::memcpy(&target, &source, sizeof(Source));
12696  return target;
12697 }
do source

Variable Documentation

constexpr int nlohmann::detail::dtoa_impl::kAlpha = -60

Definition at line 12953 of file json.hpp.

constexpr int nlohmann::detail::dtoa_impl::kGamma = -32

Definition at line 12954 of file json.hpp.