From: Mikhail Okunev Date: Mon, 31 Mar 2014 18:51:55 +0000 (-0700) Subject: Utility that converts from prettyPrint format back to double (e.g. 10M = 10 000 000) X-Git-Tag: v0.22.0~628 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=361946715a2d1a88b98d3f3ab30f7313262df96e;p=folly.git Utility that converts from prettyPrint format back to double (e.g. 10M = 10 000 000) Summary: Utility is doing reverse of prettyPrint. This is a first sketch. Test Plan: 1) We can reverse all tests from prettyPrint test and use for our function. For now I just reversed several of them 2) We can also test prettyPrint and prettyToDouble together by checking whether prettyToDouble(prettyPrint(X)) == X. This is implemented. Reviewed By: marcelo.juchem@fb.com FB internal diff: D1159879 --- diff --git a/folly/String.cpp b/folly/String.cpp index d8c25b55..bf3fc38c 100644 --- a/folly/String.cpp +++ b/folly/String.cpp @@ -180,6 +180,31 @@ const PrettySuffix kPrettyUnitsBinaryIECSuffixes[] = { { 0, 0 }, }; +const PrettySuffix kPrettySISuffixes[] = { + { "Y", 1e24L }, + { "Z", 1e21L }, + { "E", 1e18L }, + { "P", 1e15L }, + { "T", 1e12L }, + { "G", 1e9L }, + { "M", 1e6L }, + { "k", 1e3L }, + { "h", 1e2L }, + { "da", 1e1L }, + { "d", 1e-1L }, + { "c", 1e-2L }, + { "m", 1e-3L }, + { "u", 1e-6L }, + { "n", 1e-9L }, + { "p", 1e-12L }, + { "f", 1e-15L }, + { "a", 1e-18L }, + { "z", 1e-21L }, + { "y", 1e-24L }, + { " ", 0 }, + { 0, 0} +}; + const PrettySuffix* const kPrettySuffixes[PRETTY_NUM_TYPES] = { kPrettyTimeSuffixes, kPrettyBytesMetricSuffixes, @@ -188,6 +213,7 @@ const PrettySuffix* const kPrettySuffixes[PRETTY_NUM_TYPES] = { kPrettyUnitsMetricSuffixes, kPrettyUnitsBinarySuffixes, kPrettyUnitsBinaryIECSuffixes, + kPrettySISuffixes, }; } // namespace @@ -218,6 +244,50 @@ std::string prettyPrint(double val, PrettyType type, bool addSpace) { return std::string(buf); } +//TODO: +//1) Benchmark & optimize +double prettyToDouble(folly::StringPiece *const prettyString, + const PrettyType type) { + double value = folly::to(prettyString); + while (prettyString->size() > 0 && std::isspace(prettyString->front())) { + prettyString->advance(1); //Skipping spaces between number and suffix + } + const PrettySuffix* suffixes = kPrettySuffixes[type]; + int longestPrefixLen = -1; + int bestPrefixId = -1; + for (int j = 0 ; suffixes[j].suffix; ++j) { + if (suffixes[j].suffix[0] == ' '){//Checking for " " -> number rule. + if (longestPrefixLen == -1) { + longestPrefixLen = 0; //No characters to skip + bestPrefixId = j; + } + } else if (prettyString->startsWith(suffixes[j].suffix)) { + int suffixLen = strlen(suffixes[j].suffix); + //We are looking for a longest suffix matching prefix of the string + //after numeric value. We need this in case suffixes have common prefix. + if (suffixLen > longestPrefixLen) { + longestPrefixLen = suffixLen; + bestPrefixId = j; + } + } + } + if (bestPrefixId == -1) { //No valid suffix rule found + throw std::invalid_argument(folly::to( + "Unable to parse suffix \"", + prettyString->toString(), "\"")); + } + prettyString->advance(longestPrefixLen); + return suffixes[bestPrefixId].val ? value * suffixes[bestPrefixId].val : + value; +} + +double prettyToDouble(folly::StringPiece prettyString, const PrettyType type){ + double result = prettyToDouble(&prettyString, type); + detail::enforceWhitespace(prettyString.data(), + prettyString.data() + prettyString.size()); + return result; +} + std::string hexDump(const void* ptr, size_t size) { std::ostringstream os; hexDump(ptr, size, std::ostream_iterator(os, "\n")); diff --git a/folly/String.h b/folly/String.h index b5dc2417..0dd8c1b3 100644 --- a/folly/String.h +++ b/folly/String.h @@ -268,7 +268,8 @@ bool unhexlify(const InputString& input, OutputString& output); * PRETTY_UNITS_METRIC - k, M, G, etc (goes up by 10^3 = 1000 each time) * PRETTY_UNITS_BINARY - k, M, G, etc (goes up by 2^10 = 1024 each time) * PRETTY_UNITS_BINARY_IEC - Ki, Mi, Gi, etc - * + * PRETTY_SI - full SI metric prefixes from yocto to Yotta + * http://en.wikipedia.org/wiki/Metric_prefix * @author Mark Rabkin */ enum PrettyType { @@ -284,11 +285,38 @@ enum PrettyType { PRETTY_UNITS_BINARY, PRETTY_UNITS_BINARY_IEC, - PRETTY_NUM_TYPES + PRETTY_SI, + PRETTY_NUM_TYPES, }; std::string prettyPrint(double val, PrettyType, bool addSpace = true); +/** + * This utility converts StringPiece in pretty format (look above) to double, + * with progress information. Alters the StringPiece parameter + * to get rid of the already-parsed characters. + * Expects string in form {space}* [] + * If string is not in correct format, utility finds longest valid prefix and + * if there at least one, returns double value based on that prefix and + * modifies string to what is left after parsing. Throws and std::range_error + * exception if there is no correct parse. + * Examples(for PRETTY_UNITS_METRIC): + * '10M' => 10 000 000 + * '10 M' => 10 000 000 + * '10' => 10 + * '10 Mx' => 10 000 000, prettyString == "x" + * 'abc' => throws std::range_error + */ +double prettyToDouble(folly::StringPiece *const prettyString, + const PrettyType type); + +/* + * Same as prettyToDouble(folly::StringPiece*, PrettyType), but + * expects whole string to be correctly parseable. Throws std::range_error + * otherwise + */ +double prettyToDouble(folly::StringPiece prettyString, const PrettyType type); + /** * Write a hex dump of size bytes starting at ptr to out. * diff --git a/folly/test/StringTest.cpp b/folly/test/StringTest.cpp index cb3bcb7a..bfad26e9 100644 --- a/folly/test/StringTest.cpp +++ b/folly/test/StringTest.cpp @@ -312,115 +312,176 @@ double pow2(int exponent) { } } // namespace +struct PrettyTestCase{ + std::string prettyString; + double realValue; + PrettyType prettyType; +}; -TEST(PrettyPrint, Basic) { - // check time printing - EXPECT_EQ(string("8.53e+07 s "), prettyPrint(85.3e6, PRETTY_TIME)); - EXPECT_EQ(string("85.3 s "), prettyPrint(85.3, PRETTY_TIME)); - EXPECT_EQ(string("85.3 ms"), prettyPrint(85.3e-3, PRETTY_TIME)); - EXPECT_EQ(string("85.3 us"), prettyPrint(85.3e-6, PRETTY_TIME)); - EXPECT_EQ(string("85.3 ns"), prettyPrint(85.3e-9, PRETTY_TIME)); - EXPECT_EQ(string("85.3 ps"), prettyPrint(85.3e-12, PRETTY_TIME)); - EXPECT_EQ(string("8.53e-14 s "), prettyPrint(85.3e-15, PRETTY_TIME)); - - EXPECT_EQ(string("0 s "), prettyPrint(0, PRETTY_TIME)); - EXPECT_EQ(string("1 s "), prettyPrint(1.0, PRETTY_TIME)); - EXPECT_EQ(string("1 ms"), prettyPrint(1.0e-3, PRETTY_TIME)); - EXPECT_EQ(string("1 us"), prettyPrint(1.0e-6, PRETTY_TIME)); - EXPECT_EQ(string("1 ns"), prettyPrint(1.0e-9, PRETTY_TIME)); - EXPECT_EQ(string("1 ps"), prettyPrint(1.0e-12, PRETTY_TIME)); +PrettyTestCase prettyTestCases[] = +{ + {string("8.53e+07 s "), 85.3e6, PRETTY_TIME}, + {string("8.53e+07 s "), 85.3e6, PRETTY_TIME}, + {string("85.3 ms"), 85.3e-3, PRETTY_TIME}, + {string("85.3 us"), 85.3e-6, PRETTY_TIME}, + {string("85.3 ns"), 85.3e-9, PRETTY_TIME}, + {string("85.3 ps"), 85.3e-12, PRETTY_TIME}, + {string("8.53e-14 s "), 85.3e-15, PRETTY_TIME}, + + {string("0 s "), 0, PRETTY_TIME}, + {string("1 s "), 1.0, PRETTY_TIME}, + {string("1 ms"), 1.0e-3, PRETTY_TIME}, + {string("1 us"), 1.0e-6, PRETTY_TIME}, + {string("1 ns"), 1.0e-9, PRETTY_TIME}, + {string("1 ps"), 1.0e-12, PRETTY_TIME}, // check bytes printing - EXPECT_EQ(string("853 B "), prettyPrint(853., PRETTY_BYTES)); - EXPECT_EQ(string("833 kB"), prettyPrint(853.e3, PRETTY_BYTES)); - EXPECT_EQ(string("813.5 MB"), prettyPrint(853.e6, PRETTY_BYTES)); - EXPECT_EQ(string("7.944 GB"), prettyPrint(8.53e9, PRETTY_BYTES)); - EXPECT_EQ(string("794.4 GB"), prettyPrint(853.e9, PRETTY_BYTES)); - EXPECT_EQ(string("775.8 TB"), prettyPrint(853.e12, PRETTY_BYTES)); - - EXPECT_EQ(string("0 B "), prettyPrint(0, PRETTY_BYTES)); - EXPECT_EQ(string("1 B "), prettyPrint(pow2(0), PRETTY_BYTES)); - EXPECT_EQ(string("1 kB"), prettyPrint(pow2(10), PRETTY_BYTES)); - EXPECT_EQ(string("1 MB"), prettyPrint(pow2(20), PRETTY_BYTES)); - EXPECT_EQ(string("1 GB"), prettyPrint(pow2(30), PRETTY_BYTES)); - EXPECT_EQ(string("1 TB"), prettyPrint(pow2(40), PRETTY_BYTES)); - - EXPECT_EQ(string("853 B "), prettyPrint(853., PRETTY_BYTES_IEC)); - EXPECT_EQ(string("833 KiB"), prettyPrint(853.e3, PRETTY_BYTES_IEC)); - EXPECT_EQ(string("813.5 MiB"), prettyPrint(853.e6, PRETTY_BYTES_IEC)); - EXPECT_EQ(string("7.944 GiB"), prettyPrint(8.53e9, PRETTY_BYTES_IEC)); - EXPECT_EQ(string("794.4 GiB"), prettyPrint(853.e9, PRETTY_BYTES_IEC)); - EXPECT_EQ(string("775.8 TiB"), prettyPrint(853.e12, PRETTY_BYTES_IEC)); - - EXPECT_EQ(string("0 B "), prettyPrint(0, PRETTY_BYTES_IEC)); - EXPECT_EQ(string("1 B "), prettyPrint(pow2(0), PRETTY_BYTES_IEC)); - EXPECT_EQ(string("1 KiB"), prettyPrint(pow2(10), PRETTY_BYTES_IEC)); - EXPECT_EQ(string("1 MiB"), prettyPrint(pow2(20), PRETTY_BYTES_IEC)); - EXPECT_EQ(string("1 GiB"), prettyPrint(pow2(30), PRETTY_BYTES_IEC)); - EXPECT_EQ(string("1 TiB"), prettyPrint(pow2(40), PRETTY_BYTES_IEC)); + {string("853 B "), 853., PRETTY_BYTES}, + {string("833 kB"), 853.e3, PRETTY_BYTES}, + {string("813.5 MB"), 853.e6, PRETTY_BYTES}, + {string("7.944 GB"), 8.53e9, PRETTY_BYTES}, + {string("794.4 GB"), 853.e9, PRETTY_BYTES}, + {string("775.8 TB"), 853.e12, PRETTY_BYTES}, + + {string("0 B "), 0, PRETTY_BYTES}, + {string("1 B "), pow2(0), PRETTY_BYTES}, + {string("1 kB"), pow2(10), PRETTY_BYTES}, + {string("1 MB"), pow2(20), PRETTY_BYTES}, + {string("1 GB"), pow2(30), PRETTY_BYTES}, + {string("1 TB"), pow2(40), PRETTY_BYTES}, + + {string("853 B "), 853., PRETTY_BYTES_IEC}, + {string("833 KiB"), 853.e3, PRETTY_BYTES_IEC}, + {string("813.5 MiB"), 853.e6, PRETTY_BYTES_IEC}, + {string("7.944 GiB"), 8.53e9, PRETTY_BYTES_IEC}, + {string("794.4 GiB"), 853.e9, PRETTY_BYTES_IEC}, + {string("775.8 TiB"), 853.e12, PRETTY_BYTES_IEC}, + + {string("0 B "), 0, PRETTY_BYTES_IEC}, + {string("1 B "), pow2(0), PRETTY_BYTES_IEC}, + {string("1 KiB"), pow2(10), PRETTY_BYTES_IEC}, + {string("1 MiB"), pow2(20), PRETTY_BYTES_IEC}, + {string("1 GiB"), pow2(30), PRETTY_BYTES_IEC}, + {string("1 TiB"), pow2(40), PRETTY_BYTES_IEC}, // check bytes metric printing - EXPECT_EQ(string("853 B "), prettyPrint(853., PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("853 kB"), prettyPrint(853.e3, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("853 MB"), prettyPrint(853.e6, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("8.53 GB"), prettyPrint(8.53e9, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("853 GB"), prettyPrint(853.e9, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("853 TB"), prettyPrint(853.e12, PRETTY_BYTES_METRIC)); + {string("853 B "), 853., PRETTY_BYTES_METRIC}, + {string("853 kB"), 853.e3, PRETTY_BYTES_METRIC}, + {string("853 MB"), 853.e6, PRETTY_BYTES_METRIC}, + {string("8.53 GB"), 8.53e9, PRETTY_BYTES_METRIC}, + {string("853 GB"), 853.e9, PRETTY_BYTES_METRIC}, + {string("853 TB"), 853.e12, PRETTY_BYTES_METRIC}, - EXPECT_EQ(string("0 B "), prettyPrint(0, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("1 B "), prettyPrint(1.0, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("1 kB"), prettyPrint(1.0e+3, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("1 MB"), prettyPrint(1.0e+6, PRETTY_BYTES_METRIC)); + {string("0 B "), 0, PRETTY_BYTES_METRIC}, + {string("1 B "), 1.0, PRETTY_BYTES_METRIC}, + {string("1 kB"), 1.0e+3, PRETTY_BYTES_METRIC}, + {string("1 MB"), 1.0e+6, PRETTY_BYTES_METRIC}, - EXPECT_EQ(string("1 GB"), prettyPrint(1.0e+9, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("1 TB"), prettyPrint(1.0e+12, PRETTY_BYTES_METRIC)); + {string("1 GB"), 1.0e+9, PRETTY_BYTES_METRIC}, + {string("1 TB"), 1.0e+12, PRETTY_BYTES_METRIC}, // check metric-units (powers of 1000) printing - EXPECT_EQ(string("853 "), prettyPrint(853., PRETTY_UNITS_METRIC)); - EXPECT_EQ(string("853 k"), prettyPrint(853.e3, PRETTY_UNITS_METRIC)); - EXPECT_EQ(string("853 M"), prettyPrint(853.e6, PRETTY_UNITS_METRIC)); - EXPECT_EQ(string("8.53 bil"), prettyPrint(8.53e9, PRETTY_UNITS_METRIC)); - EXPECT_EQ(string("853 bil"), prettyPrint(853.e9, PRETTY_UNITS_METRIC)); - EXPECT_EQ(string("853 tril"), prettyPrint(853.e12, PRETTY_UNITS_METRIC)); + {string("853 "), 853., PRETTY_UNITS_METRIC}, + {string("853 k"), 853.e3, PRETTY_UNITS_METRIC}, + {string("853 M"), 853.e6, PRETTY_UNITS_METRIC}, + {string("8.53 bil"), 8.53e9, PRETTY_UNITS_METRIC}, + {string("853 bil"), 853.e9, PRETTY_UNITS_METRIC}, + {string("853 tril"), 853.e12, PRETTY_UNITS_METRIC}, // check binary-units (powers of 1024) printing - EXPECT_EQ(string("0 "), prettyPrint(0, PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1 "), prettyPrint(pow2(0), PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1 k"), prettyPrint(pow2(10), PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1 M"), prettyPrint(pow2(20), PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1 G"), prettyPrint(pow2(30), PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1 T"), prettyPrint(pow2(40), PRETTY_UNITS_BINARY)); - - EXPECT_EQ(string("1023 "), - prettyPrint(pow2(10) - 1, PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1024 k"), - prettyPrint(pow2(20) - 1, PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1024 M"), - prettyPrint(pow2(30) - 1, PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1024 G"), - prettyPrint(pow2(40) - 1, PRETTY_UNITS_BINARY)); - - EXPECT_EQ(string("0 "), prettyPrint(0, PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1 "), prettyPrint(pow2(0), PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1 Ki"), prettyPrint(pow2(10), PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1 Mi"), prettyPrint(pow2(20), PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1 Gi"), prettyPrint(pow2(30), PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1 Ti"), prettyPrint(pow2(40), PRETTY_UNITS_BINARY_IEC)); - - EXPECT_EQ(string("1023 "), - prettyPrint(pow2(10) - 1, PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1024 Ki"), - prettyPrint(pow2(20) - 1, PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1024 Mi"), - prettyPrint(pow2(30) - 1, PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1024 Gi"), - prettyPrint(pow2(40) - 1, PRETTY_UNITS_BINARY_IEC)); + {string("0 "), 0, PRETTY_UNITS_BINARY}, + {string("1 "), pow2(0), PRETTY_UNITS_BINARY}, + {string("1 k"), pow2(10), PRETTY_UNITS_BINARY}, + {string("1 M"), pow2(20), PRETTY_UNITS_BINARY}, + {string("1 G"), pow2(30), PRETTY_UNITS_BINARY}, + {string("1 T"), pow2(40), PRETTY_UNITS_BINARY}, + + {string("1023 "), pow2(10) - 1, PRETTY_UNITS_BINARY}, + {string("1024 k"), pow2(20) - 1, PRETTY_UNITS_BINARY}, + {string("1024 M"), pow2(30) - 1, PRETTY_UNITS_BINARY}, + {string("1024 G"), pow2(40) - 1, PRETTY_UNITS_BINARY}, + + {string("0 "), 0, PRETTY_UNITS_BINARY_IEC}, + {string("1 "), pow2(0), PRETTY_UNITS_BINARY_IEC}, + {string("1 Ki"), pow2(10), PRETTY_UNITS_BINARY_IEC}, + {string("1 Mi"), pow2(20), PRETTY_UNITS_BINARY_IEC}, + {string("1 Gi"), pow2(30), PRETTY_UNITS_BINARY_IEC}, + {string("1 Ti"), pow2(40), PRETTY_UNITS_BINARY_IEC}, + + {string("1023 "), pow2(10) - 1, PRETTY_UNITS_BINARY_IEC}, + {string("1024 Ki"), pow2(20) - 1, PRETTY_UNITS_BINARY_IEC}, + {string("1024 Mi"), pow2(30) - 1, PRETTY_UNITS_BINARY_IEC}, + {string("1024 Gi"), pow2(40) - 1, PRETTY_UNITS_BINARY_IEC}, + + //check border SI cases + + {string("1 Y"), 1e24, PRETTY_SI}, + {string("10 Y"), 1e25, PRETTY_SI}, + {string("1 y"), 1e-24, PRETTY_SI}, + {string("10 y"), 1e-23, PRETTY_SI}, // check that negative values work - EXPECT_EQ(string("-85.3 s "), prettyPrint(-85.3, PRETTY_TIME)); - EXPECT_EQ(string("-85.3 ms"), prettyPrint(-85.3e-3, PRETTY_TIME)); - EXPECT_EQ(string("-85.3 us"), prettyPrint(-85.3e-6, PRETTY_TIME)); - EXPECT_EQ(string("-85.3 ns"), prettyPrint(-85.3e-9, PRETTY_TIME)); + {string("-85.3 s "), -85.3, PRETTY_TIME}, + {string("-85.3 ms"), -85.3e-3, PRETTY_TIME}, + {string("-85.3 us"), -85.3e-6, PRETTY_TIME}, + {string("-85.3 ns"), -85.3e-9, PRETTY_TIME}, + // end of test + {string("endoftest"), 0, PRETTY_NUM_TYPES} +}; + +TEST(PrettyPrint, Basic) { + for (int i = 0; prettyTestCases[i].prettyType != PRETTY_NUM_TYPES; ++i){ + const PrettyTestCase& prettyTest = prettyTestCases[i]; + EXPECT_EQ(prettyTest.prettyString, + prettyPrint(prettyTest.realValue, prettyTest.prettyType)); + } +} + +TEST(PrettyToDouble, Basic) { + // check manually created tests + for (int i = 0; prettyTestCases[i].prettyType != PRETTY_NUM_TYPES; ++i){ + PrettyTestCase testCase = prettyTestCases[i]; + PrettyType formatType = testCase.prettyType; + double x = testCase.realValue; + std::string testString = testCase.prettyString; + double recoveredX; + try{ + recoveredX = prettyToDouble(testString, formatType); + } catch (std::range_error &ex){ + EXPECT_TRUE(false); + } + double relativeError = fabs(x) < 1e-5 ? (x-recoveredX) : + (x - recoveredX) / x; + EXPECT_NEAR(0, relativeError, 1e-3); + } + + // checks for compatibility with prettyPrint over the whole parameter space + for (int i = 0 ; i < PRETTY_NUM_TYPES; ++i){ + PrettyType formatType = static_cast(i); + for (double x = 1e-18; x < 1e40; x *= 1.9){ + bool addSpace = static_cast (i) == PRETTY_SI; + for (int it = 0; it < 2; ++it, addSpace = true){ + double recoveredX; + try{ + recoveredX = prettyToDouble(prettyPrint(x, formatType, addSpace), + formatType); + } catch (std::range_error &ex){ + EXPECT_TRUE(false); + } + double relativeError = (x - recoveredX) / x; + EXPECT_NEAR(0, relativeError, 1e-3); + } + } + } + + // check for incorrect values + EXPECT_THROW(prettyToDouble("10Mx", PRETTY_SI), std::range_error); + EXPECT_THROW(prettyToDouble("10 Mx", PRETTY_SI), std::range_error); + EXPECT_THROW(prettyToDouble("10 M x", PRETTY_SI), std::range_error); + + StringPiece testString = "10Mx"; + EXPECT_DOUBLE_EQ(prettyToDouble(&testString, PRETTY_UNITS_METRIC), 10e6); + EXPECT_EQ(testString, "x"); } TEST(PrettyPrint, HexDump) {