ToString function now returns double values with precision 15 (#1576)
The DoubleToString function has been updated to handle higher precision doubles correctly. The unnecessary string length restriction has been removed, allowing the function to convert the full double value without prematurely truncating it. This change ensures that the string representation of doubles is more accurate, especially for very large or very small numbers. Unit tests have been added to verify the correct behavior for a range of double values.
This commit is contained in:
parent
2e4d27c59a
commit
c772cab766
@ -957,7 +957,7 @@ TypedValue ToString(const TypedValue *args, int64_t nargs, const FunctionContext
|
||||
return TypedValue(std::to_string(arg.ValueInt()), ctx.memory);
|
||||
}
|
||||
if (arg.IsDouble()) {
|
||||
return TypedValue(std::to_string(arg.ValueDouble()), ctx.memory);
|
||||
return TypedValue(memgraph::utils::DoubleToString(arg.ValueDouble()), ctx.memory);
|
||||
}
|
||||
if (arg.IsDate()) {
|
||||
return TypedValue(arg.ValueDate().ToString(), ctx.memory);
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2023 Memgraph Ltd.
|
||||
// Copyright 2024 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@ -17,6 +17,7 @@
|
||||
#include <charconv>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <random>
|
||||
@ -459,4 +460,30 @@ inline std::string_view Substr(const std::string_view string, size_t pos = 0, si
|
||||
return string.substr(pos, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a double value to a string representation.
|
||||
* Precision of converted value is 16.
|
||||
* Function also removes trailing zeros after the dot.
|
||||
*
|
||||
* @param value The double value to be converted.
|
||||
*
|
||||
* @return The string representation of the double value.
|
||||
*
|
||||
* @throws None
|
||||
*/
|
||||
inline std::string DoubleToString(const double value) {
|
||||
static const int PRECISION = 15;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::setprecision(PRECISION) << std::fixed << value;
|
||||
auto sv = ss.view();
|
||||
|
||||
// Because of setprecision and fixed manipulator we are guaranteed to have the dot
|
||||
sv = sv.substr(0, sv.find_last_not_of('0') + 1);
|
||||
if (sv.ends_with('.')) {
|
||||
sv = sv.substr(0, sv.size() - 1);
|
||||
}
|
||||
return std::string(sv);
|
||||
}
|
||||
|
||||
} // namespace memgraph::utils
|
||||
|
@ -2075,9 +2075,10 @@ TYPED_TEST(FunctionTest, ToStringInteger) {
|
||||
}
|
||||
|
||||
TYPED_TEST(FunctionTest, ToStringDouble) {
|
||||
EXPECT_EQ(this->EvaluateFunction("TOSTRING", -42.42).ValueString(), "-42.420000");
|
||||
EXPECT_EQ(this->EvaluateFunction("TOSTRING", 0.0).ValueString(), "0.000000");
|
||||
EXPECT_EQ(this->EvaluateFunction("TOSTRING", 238910.2313217).ValueString(), "238910.231322");
|
||||
EXPECT_EQ(this->EvaluateFunction("TOSTRING", -42.42).ValueString(), "-42.420000000000002");
|
||||
EXPECT_EQ(this->EvaluateFunction("TOSTRING", 0.0).ValueString(), "0");
|
||||
EXPECT_EQ(this->EvaluateFunction("TOSTRING", 238910.2313217).ValueString(), "238910.231321700004628");
|
||||
EXPECT_EQ(this->EvaluateFunction("TOSTRING", 238910.23132171234).ValueString(), "238910.231321712344652");
|
||||
}
|
||||
|
||||
TYPED_TEST(FunctionTest, ToStringBool) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2023 Memgraph Ltd.
|
||||
// Copyright 2024 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@ -171,3 +171,22 @@ TEST(String, Substr) {
|
||||
EXPECT_EQ(Substr(string, string.size() - 1, 1), string.substr(string.size() - 1, 1));
|
||||
EXPECT_EQ(Substr(string, string.size() - 1, 2), string.substr(string.size() - 1, 2));
|
||||
}
|
||||
|
||||
TEST(String, DoubleToString) {
|
||||
EXPECT_EQ(DoubleToString(0), "0");
|
||||
EXPECT_EQ(DoubleToString(1), "1");
|
||||
EXPECT_EQ(DoubleToString(1234567890123456), "1234567890123456");
|
||||
EXPECT_EQ(DoubleToString(static_cast<double>(12345678901234567)), "12345678901234568");
|
||||
EXPECT_EQ(DoubleToString(0.5), "0.5");
|
||||
EXPECT_EQ(DoubleToString(1.0), "1");
|
||||
EXPECT_EQ(DoubleToString(5.8), "5.8");
|
||||
EXPECT_EQ(DoubleToString(1.01234000), "1.01234");
|
||||
EXPECT_EQ(DoubleToString(1.036837585345), "1.036837585345");
|
||||
EXPECT_EQ(DoubleToString(103.6837585345), "103.683758534500001");
|
||||
EXPECT_EQ(DoubleToString(1.01234567890123456789), "1.012345678901235");
|
||||
EXPECT_EQ(DoubleToString(1234567.01234567891234567), "1234567.012345678871498");
|
||||
EXPECT_EQ(DoubleToString(0.00001), "0.00001");
|
||||
EXPECT_EQ(DoubleToString(0.00000000000001), "0.00000000000001");
|
||||
EXPECT_EQ(DoubleToString(0.000000000000001), "0.000000000000001");
|
||||
EXPECT_EQ(DoubleToString(0.0000000000000001), "0");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user