aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2016-09-18 14:48:00 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2016-09-18 16:02:38 -0700
commit521caa5774d7be04e9682091a251d8bc8721008f (patch)
tree3896ee018f79cc7c0e00b7b99bc2e107ff116fcf
parent7767742e20b5480a5e95590a16254ab25566db99 (diff)
Add strings::HumanReadableNum to tensorflow/core/lib/strings/numbers.h
Move HumanReadableElapsedTime from tensorflow/core/lib/strings/str_util.h to tensorflow/core/lib/strings/numbers.h to match the other HumanReadable* routines. Change: 133533798
-rw-r--r--tensorflow/core/lib/strings/numbers.cc79
-rw-r--r--tensorflow/core/lib/strings/numbers.h13
-rw-r--r--tensorflow/core/lib/strings/numbers_test.cc31
-rw-r--r--tensorflow/core/lib/strings/str_util.cc53
-rw-r--r--tensorflow/core/lib/strings/str_util.h9
-rw-r--r--tensorflow/core/lib/strings/str_util_test.cc19
6 files changed, 122 insertions, 82 deletions
diff --git a/tensorflow/core/lib/strings/numbers.cc b/tensorflow/core/lib/strings/numbers.cc
index a3212451b4..de7bd30a47 100644
--- a/tensorflow/core/lib/strings/numbers.cc
+++ b/tensorflow/core/lib/strings/numbers.cc
@@ -1,5 +1,4 @@
/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
@@ -23,6 +22,7 @@ limitations under the License.
#include <cmath>
#include <unordered_map>
+#include "tensorflow/core/lib/strings/stringprintf.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/macros.h"
#include "tensorflow/core/platform/types.h"
@@ -399,6 +399,30 @@ bool HexStringToUint64(const StringPiece& s, uint64* result) {
return true;
}
+string HumanReadableNum(int64 value) {
+ string s;
+ if (value < 0) {
+ s += "-";
+ value = -value;
+ }
+ if (value < 1000) {
+ Appendf(&s, "%lld", value);
+ } else if (value >= static_cast<int64>(1e15)) {
+ // Number bigger than 1E15; use that notation.
+ Appendf(&s, "%0.3G", static_cast<double>(value));
+ } else {
+ static const char units[] = "kMBT";
+ const char* unit = units;
+ while (value >= static_cast<int64>(1000000)) {
+ value /= static_cast<int64>(1000);
+ ++unit;
+ CHECK(unit < units + TF_ARRAYSIZE(units));
+ }
+ Appendf(&s, "%.2f%c", value / 1000.0, *unit);
+ }
+ return s;
+}
+
string HumanReadableNumBytes(int64 num_bytes) {
if (num_bytes == kint64min) {
// Special case for number with not representable negation.
@@ -434,5 +458,58 @@ string HumanReadableNumBytes(int64 num_bytes) {
return string(buf);
}
+string HumanReadableElapsedTime(double seconds) {
+ string human_readable;
+
+ if (seconds < 0) {
+ human_readable = "-";
+ seconds = -seconds;
+ }
+
+ // Start with us and keep going up to years.
+ // The comparisons must account for rounding to prevent the format breaking
+ // the tested condition and returning, e.g., "1e+03 us" instead of "1 ms".
+ const double microseconds = seconds * 1.0e6;
+ if (microseconds < 999.5) {
+ strings::Appendf(&human_readable, "%0.3g us", microseconds);
+ return human_readable;
+ }
+ double milliseconds = seconds * 1e3;
+ if (milliseconds >= .995 && milliseconds < 1) {
+ // Round half to even in Appendf would convert this to 0.999 ms.
+ milliseconds = 1.0;
+ }
+ if (milliseconds < 999.5) {
+ strings::Appendf(&human_readable, "%0.3g ms", milliseconds);
+ return human_readable;
+ }
+ if (seconds < 60.0) {
+ strings::Appendf(&human_readable, "%0.3g s", seconds);
+ return human_readable;
+ }
+ seconds /= 60.0;
+ if (seconds < 60.0) {
+ strings::Appendf(&human_readable, "%0.3g min", seconds);
+ return human_readable;
+ }
+ seconds /= 60.0;
+ if (seconds < 24.0) {
+ strings::Appendf(&human_readable, "%0.3g h", seconds);
+ return human_readable;
+ }
+ seconds /= 24.0;
+ if (seconds < 30.0) {
+ strings::Appendf(&human_readable, "%0.3g days", seconds);
+ return human_readable;
+ }
+ if (seconds < 365.2425) {
+ strings::Appendf(&human_readable, "%0.3g months", seconds / 30.436875);
+ return human_readable;
+ }
+ seconds /= 365.2425;
+ strings::Appendf(&human_readable, "%0.3g years", seconds);
+ return human_readable;
+}
+
} // namespace strings
} // namespace tensorflow
diff --git a/tensorflow/core/lib/strings/numbers.h b/tensorflow/core/lib/strings/numbers.h
index 2125bf884c..31b6abbac6 100644
--- a/tensorflow/core/lib/strings/numbers.h
+++ b/tensorflow/core/lib/strings/numbers.h
@@ -122,11 +122,24 @@ bool safe_strtof(const char* str, float* value);
// Values may be rounded on over- and underflow.
bool safe_strtod(const char* str, double* value);
+// Converts from an int64 to a human readable string representing the
+// same number, using decimal powers. e.g. 1200000 -> "1.20M".
+string HumanReadableNum(int64 value);
+
// Converts from an int64 representing a number of bytes to a
// human readable string representing the same number.
// e.g. 12345678 -> "11.77MiB".
string HumanReadableNumBytes(int64 num_bytes);
+// Converts a time interval as double to a human readable
+// string. For example:
+// 0.001 -> "1 ms"
+// 10.0 -> "10 s"
+// 933120.0 -> "10.8 days"
+// 39420000.0 -> "1.25 years"
+// -10 -> "-10 s"
+string HumanReadableElapsedTime(double seconds);
+
} // namespace strings
} // namespace tensorflow
diff --git a/tensorflow/core/lib/strings/numbers_test.cc b/tensorflow/core/lib/strings/numbers_test.cc
index 66f820762f..e15161de66 100644
--- a/tensorflow/core/lib/strings/numbers_test.cc
+++ b/tensorflow/core/lib/strings/numbers_test.cc
@@ -58,6 +58,18 @@ TEST(Uint64ToHexString, Ints) {
EXPECT_FALSE(HexStringToUint64("0000000000000000xyz", &dummy));
}
+TEST(HumanReadableNum, Basic) {
+ EXPECT_EQ(HumanReadableNum(823), "823");
+ EXPECT_EQ(HumanReadableNum(1024), "1.02k");
+ EXPECT_EQ(HumanReadableNum(4000), "4.00k");
+ EXPECT_EQ(HumanReadableNum(999499), "999.50k");
+ EXPECT_EQ(HumanReadableNum(1000000), "1.00M");
+ EXPECT_EQ(HumanReadableNum(1048575), "1.05M");
+ EXPECT_EQ(HumanReadableNum(1048576), "1.05M");
+ EXPECT_EQ(HumanReadableNum(23956812342), "23.96B");
+ EXPECT_EQ(HumanReadableNum(123456789012345678), "1.23E+17");
+}
+
TEST(HumanReadableNumBytes, Bytes) {
EXPECT_EQ("0B", HumanReadableNumBytes(0));
EXPECT_EQ("4B", HumanReadableNumBytes(4));
@@ -85,6 +97,25 @@ TEST(HumanReadableNumBytes, Bytes) {
EXPECT_EQ("-8E", HumanReadableNumBytes(kint64min));
}
+TEST(HumanReadableElapsedTime, Basic) {
+ EXPECT_EQ(HumanReadableElapsedTime(-10), "-10 s");
+ EXPECT_EQ(HumanReadableElapsedTime(-0.001), "-1 ms");
+ EXPECT_EQ(HumanReadableElapsedTime(-60.0), "-1 min");
+ EXPECT_EQ(HumanReadableElapsedTime(0.00000001), "0.01 us");
+ EXPECT_EQ(HumanReadableElapsedTime(0.0000012), "1.2 us");
+ EXPECT_EQ(HumanReadableElapsedTime(0.0012), "1.2 ms");
+ EXPECT_EQ(HumanReadableElapsedTime(0.12), "120 ms");
+ EXPECT_EQ(HumanReadableElapsedTime(1.12), "1.12 s");
+ EXPECT_EQ(HumanReadableElapsedTime(90.0), "1.5 min");
+ EXPECT_EQ(HumanReadableElapsedTime(600.0), "10 min");
+ EXPECT_EQ(HumanReadableElapsedTime(9000.0), "2.5 h");
+ EXPECT_EQ(HumanReadableElapsedTime(87480.0), "1.01 days");
+ EXPECT_EQ(HumanReadableElapsedTime(7776000.0), "2.96 months");
+ EXPECT_EQ(HumanReadableElapsedTime(78840000.0), "2.5 years");
+ EXPECT_EQ(HumanReadableElapsedTime(382386614.40), "12.1 years");
+ EXPECT_EQ(HumanReadableElapsedTime(DBL_MAX), "5.7e+300 years");
+}
+
TEST(safe_strto32, Int32s) {
int32 result;
diff --git a/tensorflow/core/lib/strings/str_util.cc b/tensorflow/core/lib/strings/str_util.cc
index c3627d4286..6a794839f2 100644
--- a/tensorflow/core/lib/strings/str_util.cc
+++ b/tensorflow/core/lib/strings/str_util.cc
@@ -343,58 +343,5 @@ bool SplitAndParseAsInts(StringPiece text, char delim,
return true;
}
-string HumanReadableElapsedTime(double seconds) {
- string human_readable;
-
- if (seconds < 0) {
- human_readable = "-";
- seconds = -seconds;
- }
-
- // Start with us and keep going up to years.
- // The comparisons must account for rounding to prevent the format breaking
- // the tested condition and returning, e.g., "1e+03 us" instead of "1 ms".
- const double microseconds = seconds * 1.0e6;
- if (microseconds < 999.5) {
- strings::Appendf(&human_readable, "%0.3g us", microseconds);
- return human_readable;
- }
- double milliseconds = seconds * 1e3;
- if (milliseconds >= .995 && milliseconds < 1) {
- // Round half to even in Appendf would convert this to 0.999 ms.
- milliseconds = 1.0;
- }
- if (milliseconds < 999.5) {
- strings::Appendf(&human_readable, "%0.3g ms", milliseconds);
- return human_readable;
- }
- if (seconds < 60.0) {
- strings::Appendf(&human_readable, "%0.3g s", seconds);
- return human_readable;
- }
- seconds /= 60.0;
- if (seconds < 60.0) {
- strings::Appendf(&human_readable, "%0.3g min", seconds);
- return human_readable;
- }
- seconds /= 60.0;
- if (seconds < 24.0) {
- strings::Appendf(&human_readable, "%0.3g h", seconds);
- return human_readable;
- }
- seconds /= 24.0;
- if (seconds < 30.0) {
- strings::Appendf(&human_readable, "%0.3g days", seconds);
- return human_readable;
- }
- if (seconds < 365.2425) {
- strings::Appendf(&human_readable, "%0.3g months", seconds / 30.436875);
- return human_readable;
- }
- seconds /= 365.2425;
- strings::Appendf(&human_readable, "%0.3g years", seconds);
- return human_readable;
-}
-
} // namespace str_util
} // namespace tensorflow
diff --git a/tensorflow/core/lib/strings/str_util.h b/tensorflow/core/lib/strings/str_util.h
index 5f42c2cfcd..288b599441 100644
--- a/tensorflow/core/lib/strings/str_util.h
+++ b/tensorflow/core/lib/strings/str_util.h
@@ -85,15 +85,6 @@ string Uppercase(StringPiece s);
// set of characters that can be used as word boundaries.
void TitlecaseString(string* s, StringPiece delimiters);
-// Converts a time interval as double to a human readable
-// string. For example:
-// 0.001 -> "1 ms"
-// 10.0 -> "10 s"
-// 933120.0 -> "10.8 days"
-// 39420000.0 -> "1.25 years"
-// -10 -> "-10 s"
-string HumanReadableElapsedTime(double seconds);
-
// Join functionality
template <typename T>
string Join(const T& s, const char* sep);
diff --git a/tensorflow/core/lib/strings/str_util_test.cc b/tensorflow/core/lib/strings/str_util_test.cc
index b57089b857..091691c7b2 100644
--- a/tensorflow/core/lib/strings/str_util_test.cc
+++ b/tensorflow/core/lib/strings/str_util_test.cc
@@ -297,23 +297,4 @@ TEST(TitlecaseString, Basic) {
ASSERT_EQ(s, "Dense");
}
-TEST(HumanReadableElapsedTime, Basic) {
- EXPECT_EQ(str_util::HumanReadableElapsedTime(-10), "-10 s");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(-0.001), "-1 ms");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(-60.0), "-1 min");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(0.00000001), "0.01 us");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(0.0000012), "1.2 us");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(0.0012), "1.2 ms");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(0.12), "120 ms");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(1.12), "1.12 s");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(90.0), "1.5 min");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(600.0), "10 min");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(9000.0), "2.5 h");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(87480.0), "1.01 days");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(7776000.0), "2.96 months");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(78840000.0), "2.5 years");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(382386614.40), "12.1 years");
- EXPECT_EQ(str_util::HumanReadableElapsedTime(DBL_MAX), "5.7e+300 years");
-}
-
} // namespace tensorflow