diff --git a/src/lib/format-obj.cpp b/src/lib/format-obj.cpp index a08a66e73..082d56a56 100644 --- a/src/lib/format-obj.cpp +++ b/src/lib/format-obj.cpp @@ -52,6 +52,7 @@ #include #endif +#include #include #include #include @@ -75,6 +76,15 @@ namespace { // hard-wired configuration for debugging output.... /** show only this amount of trailing bytes from an address */ const size_t DIAGNOSTICS_ADDRESS_SUFFIX_LEN = 4; + + + /** maximum decimal digits able to pass through a round trip without value change */ + template + constexpr size_t PRECISION_DECIMAL = std::numeric_limits::digits10; + + /** decimal digits require tod represent each different floating-point value */ + template + constexpr size_t PRECISION_COMPLETE = std::numeric_limits::max_digits10; } @@ -329,7 +339,18 @@ namespace util { using std::noshowbase; using std::ostringstream; using std::ostream; - + + template + string + showFloatingPoint (F val, size_t precision) noexcept + try { + ostringstream buffer; + buffer.precision (precision); + buffer << val; + return buffer.str(); + } + catch(...) + { return FAILURE_INDICATOR; } /** * @return fixed point string representation, never empty @@ -338,28 +359,16 @@ namespace util { * we do want a predictable string representation of simple fractional * values like `0.1` (which can not be represented as binary floats) */ - string - showDouble (double val) noexcept - try { - ostringstream buffer; - buffer.precision (DIAGNOSTICS_DOUBLE_PRECISION); - buffer << val; - return buffer.str(); - } - catch(...) - { return FAILURE_INDICATOR; } + string showDouble (double val) noexcept { return showFloatingPoint (val, DIAGNOSTICS_DOUBLE_PRECISION); } + string showFloat (float val) noexcept { return showFloatingPoint (val, DIAGNOSTICS_FLOAT_PRECISION); } + string showDecimal (double val) noexcept { return showFloatingPoint (val, PRECISION_DECIMAL); } + string showDecimal (float val) noexcept { return showFloatingPoint (val, PRECISION_DECIMAL); } + string showDecimal (f128 val) noexcept { return showFloatingPoint (val, PRECISION_DECIMAL); } - string - showFloat (float val) noexcept - try { - ostringstream buffer; - buffer.precision (DIAGNOSTICS_FLOAT_PRECISION); - buffer << val; - return buffer.str(); - } - catch(...) - { return FAILURE_INDICATOR; } + string showComplete (double val) noexcept { return showFloatingPoint (val, PRECISION_COMPLETE); } + string showComplete (float val) noexcept { return showFloatingPoint (val, PRECISION_COMPLETE); } + string showComplete (f128 val) noexcept { return showFloatingPoint (val, PRECISION_COMPLETE); } string diff --git a/src/lib/format-obj.hpp b/src/lib/format-obj.hpp index 79a6970ab..b1a72d044 100644 --- a/src/lib/format-obj.hpp +++ b/src/lib/format-obj.hpp @@ -100,6 +100,13 @@ namespace util { return showHash(hash,1); } + std::string showDecimal (double) noexcept; + std::string showDecimal (float) noexcept; + std::string showDecimal (f128) noexcept; + std::string showComplete (double)noexcept; + std::string showComplete (float) noexcept; + std::string showComplete (f128) noexcept; + namespace { diff --git a/src/lib/integral.hpp b/src/lib/integral.hpp index 05b3bfae7..c22564ddc 100644 --- a/src/lib/integral.hpp +++ b/src/lib/integral.hpp @@ -38,6 +38,9 @@ using uchar = unsigned char; using uint = unsigned int; +using f128 = long double; +static_assert(10 <= sizeof(f128)); + const uint LIFE_AND_UNIVERSE_4EVER = 42; diff --git a/src/lib/meta/util.hpp b/src/lib/meta/util.hpp index 391f3304b..515d01509 100644 --- a/src/lib/meta/util.hpp +++ b/src/lib/meta/util.hpp @@ -37,6 +37,7 @@ #ifndef LIB_META_UTIL_H #define LIB_META_UTIL_H +#include "lib/integral.hpp" #include #include @@ -425,10 +426,20 @@ namespace util { : lib::meta::BOOL_FALSE_STR; } - /** pretty-print a double in fixed-point format */ + /** pretty-print a double in (rounded) fixed-point format */ std::string showDouble (double) noexcept; std::string showFloat (float) noexcept; + /** show maximum reproducible decimal representation */ + std::string showDecimal (double) noexcept; + std::string showDecimal (float) noexcept; + std::string showDecimal (f128) noexcept; + + /** show enough decimal digits to represent every distinct value */ + std::string showComplete (double) noexcept; + std::string showComplete (float) noexcept; + std::string showComplete (f128) noexcept; + std::string showSize (size_t) noexcept; diff --git a/src/lib/rational.hpp b/src/lib/rational.hpp index 955017e2b..800c44c3e 100644 --- a/src/lib/rational.hpp +++ b/src/lib/rational.hpp @@ -68,6 +68,7 @@ #define LIB_RATIONAL_H +#include "lib/integral.hpp" #include "lib/util-quant.hpp" #include @@ -129,7 +130,6 @@ namespace util { { u = 0!=u? u:1; auto [d,r] = util::iDiv (num, den); - using f128 = long double; // round to smallest integer fraction, to shake off "number dust" f128 const ROUND_ULP = 1 + 1/(f128(std::numeric_limits::max()) * 2); diff --git a/src/lib/stat/csv.hpp b/src/lib/stat/csv.hpp index 2457525c4..d807210f3 100644 --- a/src/lib/stat/csv.hpp +++ b/src/lib/stat/csv.hpp @@ -80,22 +80,14 @@ namespace stat { inline string format4Csv (VAL const& val) { - std::ostringstream oss; - oss.precision (std::numeric_limits::digits10); /////////////////////////////OOO herausfinden ob hier lexical_cast genügt ==> dann toString() - oss << val; - return oss.str(); - } - - inline string - format4Csv (string const& val) - { - return '"'+val+'"'; - } - - inline string - format4Csv (bool boo) - { - return util::showBool(boo); ///////////////////////OOO würde toSting() das korrekt hinbekommen + if constexpr (std::is_floating_point_v) + return util::showDecimal (val); + // standard textual rendering + auto res = util::toString (val); + if constexpr (std::is_arithmetic_v) + return res; // includes bool + else + return '"'+res+'"'; } }//(End)Implementation diff --git a/tests/library/stat/data-csv-test.cpp b/tests/library/stat/data-csv-test.cpp index 0b7ce287c..3f254fb0b 100644 --- a/tests/library/stat/data-csv-test.cpp +++ b/tests/library/stat/data-csv-test.cpp @@ -232,6 +232,54 @@ namespace test{ void verify_CSV_Format() { + string line; + double val = 1.0 / 3; + int64_t ii = -100000; + + appendCsvField (line, ii); + CHECK (line == "-100000"_expect); +SHOW_EXPR(val) +SHOW_EXPL(val) +SHOW_EXPR(std::to_string(val)) +SHOW_EXPR(format4Csv(val)); +SHOW_EXPR(util::showDecimal(val)) +SHOW_EXPR(util::showComplete(val)) + double vval = parseAs(format4Csv(val)); +SHOW_EXPR(vval) +SHOW_EXPL(vval) +SHOW_EXPR(std::to_string(vval)) +SHOW_EXPR(format4Csv(vval)); +SHOW_EXPR(util::showDecimal(val)) +SHOW_EXPR(util::showComplete(val)) + vval = parseAs(boost::lexical_cast(val)); +SHOW_EXPR(vval) +SHOW_EXPL(vval) +SHOW_EXPR(std::to_string(vval)) +SHOW_EXPR(format4Csv(vval)); +SHOW_EXPR(util::showDecimal(val)) +SHOW_EXPR(util::showComplete(val)) + bool boo; +SHOW_EXPR(boo); +SHOW_EXPL(boo) +SHOW_EXPR(std::to_string(boo)) +SHOW_EXPR(format4Csv(boo)); +SHOW_EXPR(format4Csv(-42)); +SHOW_EXPR(format4Csv(uint64_t(-42))); + auto moo = f128(1) / 3; +SHOW_EXPR(moo) +SHOW_EXPL(moo) +SHOW_EXPR(std::to_string(moo)) +SHOW_EXPR(format4Csv(moo)); +SHOW_EXPR(util::showDecimal(moo)) +SHOW_EXPR(util::showComplete(moo)) + auto oo = 1.0f / 3; +SHOW_EXPR(oo) +SHOW_EXPL(oo) +SHOW_EXPR(std::to_string(oo)) +SHOW_EXPR(format4Csv(oo)); +SHOW_EXPR(util::showDecimal(oo)) +SHOW_EXPR(util::showComplete(oo)) +SHOW_EXPR(format4Csv(lib::time::Time(1,2,3,4))); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 0d2ab6ca6..201aadd78 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -112030,15 +112030,103 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + + + - - + + + + + + + + +

+ was auch immer das ist.... +

+ + +
+
+ + + + + + + + + + + + +

+ empirisch(debug) ⟹ 17 Stellen +

+ + +
+ + + +
+
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -