Fix rounding
This commit is contained in:
parent
e61cac687d
commit
b8d34e0db3
@ -266,7 +266,9 @@ const char basic_data<T>::DIGITS[] =
|
|||||||
factor * 1000000000
|
factor * 1000000000
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const uint32_t basic_data<T>::POWERS_OF_10_32[] = {1, FMT_POWERS_OF_10(1)};
|
const uint64_t basic_data<T>::POWERS_OF_10_64[] = {
|
||||||
|
1, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ull),
|
||||||
|
10000000000000000000ull};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const uint32_t basic_data<T>::ZERO_OR_POWERS_OF_10_32[] = {0,
|
const uint32_t basic_data<T>::ZERO_OR_POWERS_OF_10_32[] = {0,
|
||||||
@ -334,7 +336,7 @@ template <typename T> const wchar_t basic_data<T>::WRESET_COLOR[] = L"\x1b[0m";
|
|||||||
|
|
||||||
template <typename T> struct bits {
|
template <typename T> struct bits {
|
||||||
static FMT_CONSTEXPR_DECL const int value =
|
static FMT_CONSTEXPR_DECL const int value =
|
||||||
sizeof(T) * std::numeric_limits<unsigned char>::digits;
|
static_cast<int>(sizeof(T) * std::numeric_limits<unsigned char>::digits);
|
||||||
};
|
};
|
||||||
|
|
||||||
// A handmade floating-point number f * pow(2, e).
|
// A handmade floating-point number f * pow(2, e).
|
||||||
@ -523,7 +525,7 @@ FMT_FUNC int grisu2_gen_digits(char* buf, uint32_t hi, uint64_t lo, int& exp,
|
|||||||
uint64_t remainder = (static_cast<uint64_t>(hi) << -one.e) + lo;
|
uint64_t remainder = (static_cast<uint64_t>(hi) << -one.e) + lo;
|
||||||
if (remainder <= delta || size > max_digits) {
|
if (remainder <= delta || size > max_digits) {
|
||||||
return grisu2_round(buf, size, max_digits, delta, remainder,
|
return grisu2_round(buf, size, max_digits, delta, remainder,
|
||||||
static_cast<uint64_t>(data::POWERS_OF_10_32[exp])
|
static_cast<uint64_t>(data::POWERS_OF_10_64[exp])
|
||||||
<< -one.e,
|
<< -one.e,
|
||||||
diff.f, exp)
|
diff.f, exp)
|
||||||
? size
|
? size
|
||||||
@ -540,7 +542,7 @@ FMT_FUNC int grisu2_gen_digits(char* buf, uint32_t hi, uint64_t lo, int& exp,
|
|||||||
--exp;
|
--exp;
|
||||||
if (lo < delta || size > max_digits) {
|
if (lo < delta || size > max_digits) {
|
||||||
return grisu2_round(buf, size, max_digits, delta, lo, one.f,
|
return grisu2_round(buf, size, max_digits, delta, lo, one.f,
|
||||||
diff.f * data::POWERS_OF_10_32[-exp], exp)
|
diff.f * data::POWERS_OF_10_64[-exp], exp)
|
||||||
? size
|
? size
|
||||||
: -1;
|
: -1;
|
||||||
}
|
}
|
||||||
@ -692,6 +694,7 @@ FMT_FUNC gen_digits_params process_specs(const core_format_specs& specs,
|
|||||||
params.upper = true;
|
params.upper = true;
|
||||||
FMT_FALLTHROUGH
|
FMT_FALLTHROUGH
|
||||||
case '\0':
|
case '\0':
|
||||||
|
num_digits = 17;
|
||||||
case 'g':
|
case 'g':
|
||||||
params.trailing_zeros = (specs.flags & HASH_FLAG) != 0;
|
params.trailing_zeros = (specs.flags & HASH_FLAG) != 0;
|
||||||
if (-4 <= exp && exp < num_digits + 1) {
|
if (-4 <= exp && exp < num_digits + 1) {
|
||||||
@ -759,7 +762,7 @@ grisu2_format(Double value, buffer& buf, core_format_specs specs) {
|
|||||||
++lower.f; // \tilde{M}^- + 1 ulp -> M^-_{\uparrow}.
|
++lower.f; // \tilde{M}^- + 1 ulp -> M^-_{\uparrow}.
|
||||||
uint64_t delta = upper.f - lower.f;
|
uint64_t delta = upper.f - lower.f;
|
||||||
fp diff = upper - scaled_value; // wp_w in Grisu.
|
fp diff = upper - scaled_value; // wp_w in Grisu.
|
||||||
// lo (p2 in Grisu) contains the least significants digits of scaled_upper.
|
// lo (p2 in Grisu) contains the least significants digits of scaled upper.
|
||||||
// lo = upper % one.
|
// lo = upper % one.
|
||||||
uint64_t lo = upper.f & (one.f - 1);
|
uint64_t lo = upper.f & (one.f - 1);
|
||||||
gen_digits_params params = process_specs(specs, cached_exp + exp, buf);
|
gen_digits_params params = process_specs(specs, cached_exp + exp, buf);
|
||||||
|
@ -750,7 +750,7 @@ template <typename T> struct int_traits {
|
|||||||
// Static data is placed in this class template to allow header-only
|
// Static data is placed in this class template to allow header-only
|
||||||
// configuration.
|
// configuration.
|
||||||
template <typename T = void> struct FMT_API basic_data {
|
template <typename T = void> struct FMT_API basic_data {
|
||||||
static const uint32_t POWERS_OF_10_32[];
|
static const uint64_t POWERS_OF_10_64[];
|
||||||
static const uint32_t ZERO_OR_POWERS_OF_10_32[];
|
static const uint32_t ZERO_OR_POWERS_OF_10_32[];
|
||||||
static const uint64_t ZERO_OR_POWERS_OF_10_64[];
|
static const uint64_t ZERO_OR_POWERS_OF_10_64[];
|
||||||
static const uint64_t POW10_SIGNIFICANDS[];
|
static const uint64_t POW10_SIGNIFICANDS[];
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "gtest.h"
|
#include "gtest.h"
|
||||||
|
|
||||||
bool reported_skipped;
|
static bool reported_skipped;
|
||||||
|
|
||||||
#undef TEST
|
#undef TEST
|
||||||
#define TEST(test_fixture, test_name) \
|
#define TEST(test_fixture, test_name) \
|
||||||
@ -39,3 +39,8 @@ TEST(GrisuTest, Inf) {
|
|||||||
TEST(GrisuTest, Zero) {
|
TEST(GrisuTest, Zero) {
|
||||||
EXPECT_EQ("0", fmt::format("{}", 0.0));
|
EXPECT_EQ("0", fmt::format("{}", 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(GrisuTest, Round) {
|
||||||
|
EXPECT_EQ("1.9156918820264798e-56",
|
||||||
|
fmt::format("{}", 1.9156918820264798e-56));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user