| 16140 | */ |
| 16141 | JSON_HEDLEY_NON_NULL(1) |
| 16142 | inline void grisu2(char* buf, int& len, int& decimal_exponent, |
| 16143 | diyfp m_minus, diyfp v, diyfp m_plus) |
| 16144 | { |
| 16145 | JSON_ASSERT(m_plus.e == m_minus.e); |
| 16146 | JSON_ASSERT(m_plus.e == v.e); |
| 16147 | |
| 16148 | // --------(-----------------------+-----------------------)-------- (A) |
| 16149 | // m- v m+ |
| 16150 | // |
| 16151 | // --------------------(-----------+-----------------------)-------- (B) |
| 16152 | // m- v m+ |
| 16153 | // |
| 16154 | // First scale v (and m- and m+) such that the exponent is in the range |
| 16155 | // [alpha, gamma]. |
| 16156 | |
| 16157 | const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e); |
| 16158 | |
| 16159 | const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k |
| 16160 | |
| 16161 | // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma] |
| 16162 | const diyfp w = diyfp::mul(v, c_minus_k); |
| 16163 | const diyfp w_minus = diyfp::mul(m_minus, c_minus_k); |
| 16164 | const diyfp w_plus = diyfp::mul(m_plus, c_minus_k); |
| 16165 | |
| 16166 | // ----(---+---)---------------(---+---)---------------(---+---)---- |
| 16167 | // w- w w+ |
| 16168 | // = c*m- = c*v = c*m+ |
| 16169 | // |
| 16170 | // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and |
| 16171 | // w+ are now off by a small amount. |
| 16172 | // In fact: |
| 16173 | // |
| 16174 | // w - v * 10^k < 1 ulp |
| 16175 | // |
| 16176 | // To account for this inaccuracy, add resp. subtract 1 ulp. |
| 16177 | // |
| 16178 | // --------+---[---------------(---+---)---------------]---+-------- |
| 16179 | // w- M- w M+ w+ |
| 16180 | // |
| 16181 | // Now any number in [M-, M+] (bounds included) will round to w when input, |
| 16182 | // regardless of how the input rounding algorithm breaks ties. |
| 16183 | // |
| 16184 | // And digit_gen generates the shortest possible such number in [M-, M+]. |
| 16185 | // Note that this does not mean that Grisu2 always generates the shortest |
| 16186 | // possible number in the interval (m-, m+). |
| 16187 | const diyfp M_minus(w_minus.f + 1, w_minus.e); |
| 16188 | const diyfp M_plus (w_plus.f - 1, w_plus.e ); |
| 16189 | |
| 16190 | decimal_exponent = -cached.k; // = -(-k) = k |
| 16191 | |
| 16192 | grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus); |
| 16193 | } |
| 16194 | |
| 16195 | /*! |
| 16196 | v = buf * 10^decimal_exponent |
no test coverage detected