Write out full resolution floats in flatbuffer to JSON
It turns out that we were missing a 1--2 digits of precision
necessary to fully represent floats/doubles. In most cases where we
would care about bit-perfect
This moves all of our flatbuffer->JSON conversion to use
std::format/std::to_chars, which specifically guarantee that you will be
able to read the number back fully, while truncating numbers reasonably
so that e.g. 0.1 actually renders reasonably to the human eye.
In doing so, this also reduces some of the inconsistencies between the
two FlatbufferToJson methods.
This forces updates in a variety of tests that make use of this code and
which check for exactly identical serialized JSON values.
Change-Id: Idbf6a5614043ce4d6c02f3104991e30fdca23334
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/fast_string_builder.cc b/aos/fast_string_builder.cc
index 0445535..00fe001 100644
--- a/aos/fast_string_builder.cc
+++ b/aos/fast_string_builder.cc
@@ -1,5 +1,7 @@
#include "aos/fast_string_builder.h"
+#include <charconv>
+
namespace aos {
FastStringBuilder::FastStringBuilder(std::size_t initial_size) {
@@ -30,20 +32,22 @@
void FastStringBuilder::Append(float val) {
std::size_t index = str_.size();
- Resize(17);
- int result = absl::SNPrintF(str_.data() + index, 17, "%.6g", val);
- PCHECK(result != -1);
- CHECK(result < 17);
- str_.resize(index + result);
+ constexpr std::size_t kMaxSize = 17;
+ Resize(kMaxSize);
+ const std::to_chars_result result =
+ std::to_chars(str_.data() + index, str_.data() + index + kMaxSize, val);
+ CHECK(result.ec == std::errc()) << std::make_error_code(result.ec).message();
+ str_.resize(result.ptr - str_.data());
}
void FastStringBuilder::Append(double val) {
std::size_t index = str_.size();
- Resize(25);
- int result = absl::SNPrintF(str_.data() + index, 25, "%.15g", val);
- PCHECK(result != -1);
- CHECK(result < 25);
- str_.resize(index + result);
+ constexpr std::size_t kMaxSize = 25;
+ Resize(kMaxSize);
+ const std::to_chars_result result =
+ std::to_chars(str_.data() + index, str_.data() + index + kMaxSize, val);
+ CHECK(result.ec == std::errc()) << std::make_error_code(result.ec).message();
+ str_.resize(result.ptr - str_.data());
}
void FastStringBuilder::AppendChar(char val) {