Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion include/nlohmann/detail/conversions/zmij.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ JSON_HEDLEY_ALWAYS_INLINE shortest_decimal to_shortest(std::uint64_t bits) noexc
const uint128_parts p10 = pow10(-dec_exp - 1);
const uint128_parts p = umul192_hi128(p10.high, p10.low, bin_sig << static_cast<unsigned>(shift));
std::uint64_t integral = p.high >> static_cast<unsigned>(extra_shift);
const std::uint64_t fractional = (p.high << static_cast<unsigned>(64 - extra_shift)) | (p.low >> static_cast<unsigned>(extra_shift));
// (no casts in the shifts: MSVC 2015 warns C4554 on them despite the parentheses)
constexpr unsigned fractional_low_shift = static_cast<unsigned>(extra_shift);
constexpr unsigned fractional_high_shift = 64u - fractional_low_shift;
const std::uint64_t fractional = (p.high << fractional_high_shift) | (p.low >> fractional_low_shift);
std::uint64_t digit = 0;
bool round_up = false;
bool round_down = false;
Expand Down
5 changes: 4 additions & 1 deletion single_include/nlohmann/json.hpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 7 additions & 17 deletions tests/src/unit-to_chars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@ using nlohmann::detail::dtoa_impl::reinterpret_bits;
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <limits>
#include <locale>
#include <random>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -689,20 +686,13 @@ void check_shortest(double v)
const std::string& digits = de.first;
if (digits.size() > 1)
{
// the decimals of one digit fewer next to the value
// (a stream rather than snprintf("%.*e"), whose output GCC cannot bound)
std::ostringstream shorter;
shorter.imbue(std::locale::classic());
shorter << std::scientific << std::setprecision(static_cast<int>(digits.size()) - 2) << v;
const auto near = digits_and_exponent(shorter.str());
// as an integer with digits.size() - 1 digits
std::string m = near.first;
int e = near.second;
while (m.size() < digits.size() - 1)
{
m += '0';
--e;
}
// the decimals of one digit fewer next to the value: v lies within
// half a unit of the last digit of text, so the closest ones are the
// truncated digits and their successor
// (not a stream with std::setprecision(digits.size() - 2): the
// standard library of MSVC 2017 ignores a precision of 0)
const std::string m = digits.substr(0, digits.size() - 1);
const int e = de.second + 1;
const std::uint64_t mid = std::stoull(m);
for (const std::uint64_t candidate :
{
Expand Down
Loading