fixed locale problems
This commit is contained in:
parent
43ee70cef8
commit
31bccc83b9
3 changed files with 93 additions and 62 deletions
64
src/json.hpp
64
src/json.hpp
|
@ -6114,24 +6114,26 @@ class basic_json
|
||||||
|
|
||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
{
|
{
|
||||||
// buffer size: precision (2^8-1 = 255) + other ('-.e-xxx' = 7) + null (1)
|
|
||||||
char buf[263];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
// check if number was parsed from a string
|
// check if number was parsed from a string
|
||||||
if (m_type.bits.parsed)
|
if (m_type.bits.parsed)
|
||||||
{
|
{
|
||||||
// check if parsed number had an exponent given
|
// check if parsed number had an exponent given
|
||||||
if (m_type.bits.has_exp)
|
if (m_type.bits.has_exp)
|
||||||
{
|
{
|
||||||
|
// buffer size: precision (2^8-1 = 255) + other ('-.e-xxx' = 7) + null (1)
|
||||||
|
char buf[263];
|
||||||
|
int len;
|
||||||
|
|
||||||
// handle capitalization of the exponent
|
// handle capitalization of the exponent
|
||||||
if (m_type.bits.exp_cap)
|
if (m_type.bits.exp_cap)
|
||||||
{
|
{
|
||||||
len = snprintf(buf, sizeof(buf), "%.*E", m_type.bits.precision, m_value.number_float) + 1;
|
len = snprintf(buf, sizeof(buf), "%.*E",
|
||||||
|
m_type.bits.precision, m_value.number_float) + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
len = snprintf(buf, sizeof(buf), "%.*e", m_type.bits.precision, m_value.number_float) + 1;
|
len = snprintf(buf, sizeof(buf), "%.*e",
|
||||||
|
m_type.bits.precision, m_value.number_float) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove '+' sign from the exponent if necessary
|
// remove '+' sign from the exponent if necessary
|
||||||
|
@ -6152,40 +6154,40 @@ class basic_json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
o << buf;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no exponent - output as a decimal
|
// no exponent - output as a decimal
|
||||||
snprintf(buf, sizeof(buf), "%.*f",
|
std::stringstream ss;
|
||||||
m_type.bits.precision, m_value.number_float);
|
ss.imbue(std::locale("C"));
|
||||||
|
ss << std::setprecision(m_type.bits.precision)
|
||||||
|
<< std::fixed << m_value.number_float;
|
||||||
|
o << ss.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_value.number_float == 0)
|
|
||||||
{
|
|
||||||
// special case for zero to get "0.0"/"-0.0"
|
|
||||||
if (std::signbit(m_value.number_float))
|
|
||||||
{
|
|
||||||
o << "-0.0";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
o << "0.0";
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise 6, 15 or 16 digits of precision allows
|
if (m_value.number_float == 0)
|
||||||
// round-trip IEEE 754 string->float->string,
|
{
|
||||||
// string->double->string or string->long double->string;
|
// special case for zero to get "0.0"/"-0.0"
|
||||||
// to be safe, we read this value from
|
o << (std::signbit(m_value.number_float) ? "-0.0" : "0.0");
|
||||||
// std::numeric_limits<number_float_t>::digits10
|
}
|
||||||
snprintf(buf, sizeof(buf), "%.*g",
|
else
|
||||||
std::numeric_limits<double>::digits10,
|
{
|
||||||
m_value.number_float);
|
// Otherwise 6, 15 or 16 digits of precision allows
|
||||||
|
// round-trip IEEE 754 string->float->string,
|
||||||
|
// string->double->string or string->long double->string;
|
||||||
|
// to be safe, we read this value from
|
||||||
|
// std::numeric_limits<number_float_t>::digits10
|
||||||
|
std::stringstream ss;
|
||||||
|
ss.imbue(std::locale("C"));
|
||||||
|
ss << std::setprecision(std::numeric_limits<double>::digits10)
|
||||||
|
<< m_value.number_float;
|
||||||
|
o << ss.str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
o << buf;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6114,24 +6114,26 @@ class basic_json
|
||||||
|
|
||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
{
|
{
|
||||||
// buffer size: precision (2^8-1 = 255) + other ('-.e-xxx' = 7) + null (1)
|
|
||||||
char buf[263];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
// check if number was parsed from a string
|
// check if number was parsed from a string
|
||||||
if (m_type.bits.parsed)
|
if (m_type.bits.parsed)
|
||||||
{
|
{
|
||||||
// check if parsed number had an exponent given
|
// check if parsed number had an exponent given
|
||||||
if (m_type.bits.has_exp)
|
if (m_type.bits.has_exp)
|
||||||
{
|
{
|
||||||
|
// buffer size: precision (2^8-1 = 255) + other ('-.e-xxx' = 7) + null (1)
|
||||||
|
char buf[263];
|
||||||
|
int len;
|
||||||
|
|
||||||
// handle capitalization of the exponent
|
// handle capitalization of the exponent
|
||||||
if (m_type.bits.exp_cap)
|
if (m_type.bits.exp_cap)
|
||||||
{
|
{
|
||||||
len = snprintf(buf, sizeof(buf), "%.*E", m_type.bits.precision, m_value.number_float) + 1;
|
len = snprintf(buf, sizeof(buf), "%.*E",
|
||||||
|
m_type.bits.precision, m_value.number_float) + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
len = snprintf(buf, sizeof(buf), "%.*e", m_type.bits.precision, m_value.number_float) + 1;
|
len = snprintf(buf, sizeof(buf), "%.*e",
|
||||||
|
m_type.bits.precision, m_value.number_float) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove '+' sign from the exponent if necessary
|
// remove '+' sign from the exponent if necessary
|
||||||
|
@ -6152,40 +6154,40 @@ class basic_json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
o << buf;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no exponent - output as a decimal
|
// no exponent - output as a decimal
|
||||||
snprintf(buf, sizeof(buf), "%.*f",
|
std::stringstream ss;
|
||||||
m_type.bits.precision, m_value.number_float);
|
ss.imbue(std::locale("C")); // fix locale problems
|
||||||
|
ss << std::setprecision(m_type.bits.precision)
|
||||||
|
<< std::fixed << m_value.number_float;
|
||||||
|
o << ss.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_value.number_float == 0)
|
|
||||||
{
|
|
||||||
// special case for zero to get "0.0"/"-0.0"
|
|
||||||
if (std::signbit(m_value.number_float))
|
|
||||||
{
|
|
||||||
o << "-0.0";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
o << "0.0";
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise 6, 15 or 16 digits of precision allows
|
if (m_value.number_float == 0)
|
||||||
// round-trip IEEE 754 string->float->string,
|
{
|
||||||
// string->double->string or string->long double->string;
|
// special case for zero to get "0.0"/"-0.0"
|
||||||
// to be safe, we read this value from
|
o << (std::signbit(m_value.number_float) ? "-0.0" : "0.0");
|
||||||
// std::numeric_limits<number_float_t>::digits10
|
}
|
||||||
snprintf(buf, sizeof(buf), "%.*g",
|
else
|
||||||
std::numeric_limits<double>::digits10,
|
{
|
||||||
m_value.number_float);
|
// Otherwise 6, 15 or 16 digits of precision allows
|
||||||
|
// round-trip IEEE 754 string->float->string,
|
||||||
|
// string->double->string or string->long double->string;
|
||||||
|
// to be safe, we read this value from
|
||||||
|
// std::numeric_limits<number_float_t>::digits10
|
||||||
|
std::stringstream ss;
|
||||||
|
ss.imbue(std::locale("C")); // fix locale problems
|
||||||
|
ss << std::setprecision(std::numeric_limits<double>::digits10)
|
||||||
|
<< m_value.number_float;
|
||||||
|
o << ss.str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
o << buf;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12369,5 +12369,32 @@ TEST_CASE("regression tests")
|
||||||
j_long_double = 1.23e45L;
|
j_long_double = 1.23e45L;
|
||||||
CHECK(j_long_double.get<long double>() == 1.23e45L);
|
CHECK(j_long_double.get<long double>() == 1.23e45L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("issue #228 - double values are serialized with commas as decimal points")
|
||||||
|
{
|
||||||
|
json j1a = 23.42;
|
||||||
|
json j1b = json::parse("23.42");
|
||||||
|
|
||||||
|
json j2a = 2342e-2;
|
||||||
|
//issue #230
|
||||||
|
//json j2b = json::parse("2342e-2");
|
||||||
|
|
||||||
|
json j3a = 10E3;
|
||||||
|
json j3b = json::parse("10E3");
|
||||||
|
json j3c = json::parse("10e3");
|
||||||
|
|
||||||
|
std::locale::global(std::locale("de_DE"));
|
||||||
|
|
||||||
|
CHECK(j1a.dump() == "23.42");
|
||||||
|
CHECK(j1b.dump() == "23.42");
|
||||||
|
|
||||||
|
CHECK(j2a.dump() == "23.42");
|
||||||
|
//issue #230
|
||||||
|
//CHECK(j2b.dump() == "23.42");
|
||||||
|
|
||||||
|
CHECK(j3a.dump() == "10000");
|
||||||
|
CHECK(j3b.dump() == "1E04");
|
||||||
|
CHECK(j3c.dump() == "1e04");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue