aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/core/lib/strings/numbers.cc
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2018-03-22 10:21:59 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-03-22 10:26:30 -0700
commited0c4037ec47e3a7d1e5d23514951e5256b8a30f (patch)
tree8e25a50570c03d40663e64c0b13f2e74349cb177 /tensorflow/core/lib/strings/numbers.cc
parent010e3e401cef883aa0fff334d3f5e56a88e3f5e4 (diff)
Small cleanup StrCat related number formatting
- Resolve inconsistency in return values (pointer to start vs end of buffer) - Instead, return the number of chars written as this turns out to be most useful to callers - Removes the need for redundant strlen calls. PiperOrigin-RevId: 190085812
Diffstat (limited to 'tensorflow/core/lib/strings/numbers.cc')
-rw-r--r--tensorflow/core/lib/strings/numbers.cc49
1 files changed, 28 insertions, 21 deletions
diff --git a/tensorflow/core/lib/strings/numbers.cc b/tensorflow/core/lib/strings/numbers.cc
index f5822fad8e..516decc3c0 100644
--- a/tensorflow/core/lib/strings/numbers.cc
+++ b/tensorflow/core/lib/strings/numbers.cc
@@ -106,19 +106,22 @@ T locale_independent_strtonum(const char* str, const char** endptr) {
namespace strings {
-char* FastInt32ToBufferLeft(int32 i, char* buffer) {
+size_t FastInt32ToBufferLeft(int32 i, char* buffer) {
uint32 u = i;
+ size_t length = 0;
if (i < 0) {
*buffer++ = '-';
+ ++length;
// We need to do the negation in modular (i.e., "unsigned")
// arithmetic; MSVC++ apparently warns for plain "-u", so
// we write the equivalent expression "0 - u" instead.
u = 0 - u;
}
- return FastUInt32ToBufferLeft(u, buffer);
+ length += FastUInt32ToBufferLeft(u, buffer);
+ return length;
}
-char* FastUInt32ToBufferLeft(uint32 i, char* buffer) {
+size_t FastUInt32ToBufferLeft(uint32 i, char* buffer) {
char* start = buffer;
do {
*buffer++ = ((i % 10) + '0');
@@ -126,19 +129,22 @@ char* FastUInt32ToBufferLeft(uint32 i, char* buffer) {
} while (i > 0);
*buffer = 0;
std::reverse(start, buffer);
- return buffer;
+ return buffer - start;
}
-char* FastInt64ToBufferLeft(int64 i, char* buffer) {
+size_t FastInt64ToBufferLeft(int64 i, char* buffer) {
uint64 u = i;
+ size_t length = 0;
if (i < 0) {
*buffer++ = '-';
+ ++length;
u = 0 - u;
}
- return FastUInt64ToBufferLeft(u, buffer);
+ length += FastUInt64ToBufferLeft(u, buffer);
+ return length;
}
-char* FastUInt64ToBufferLeft(uint64 i, char* buffer) {
+size_t FastUInt64ToBufferLeft(uint64 i, char* buffer) {
char* start = buffer;
do {
*buffer++ = ((i % 10) + '0');
@@ -146,19 +152,18 @@ char* FastUInt64ToBufferLeft(uint64 i, char* buffer) {
} while (i > 0);
*buffer = 0;
std::reverse(start, buffer);
- return buffer;
+ return buffer - start;
}
static const double kDoublePrecisionCheckMax = DBL_MAX / 1.000000000000001;
-char* DoubleToBuffer(double value, char* buffer) {
+size_t DoubleToBuffer(double value, char* buffer) {
// DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all
// platforms these days. Just in case some system exists where DBL_DIG
// is significantly larger -- and risks overflowing our buffer -- we have
// this assert.
static_assert(DBL_DIG < 20, "DBL_DIG is too big");
- bool full_precision_needed = true;
if (std::abs(value) <= kDoublePrecisionCheckMax) {
int snprintf_result =
snprintf(buffer, kFastToBufferSize, "%.*g", DBL_DIG, value);
@@ -167,18 +172,20 @@ char* DoubleToBuffer(double value, char* buffer) {
// larger than the precision we asked for.
DCHECK(snprintf_result > 0 && snprintf_result < kFastToBufferSize);
- full_precision_needed =
- locale_independent_strtonum<double>(buffer, nullptr) != value;
+ if (locale_independent_strtonum<double>(buffer, nullptr) == value) {
+ // Round-tripping the string to double works; we're done.
+ return snprintf_result;
+ }
+ // else: full precision formatting needed. Fall through.
}
- if (full_precision_needed) {
- int snprintf_result =
- snprintf(buffer, kFastToBufferSize, "%.*g", DBL_DIG + 2, value);
+ int snprintf_result =
+ snprintf(buffer, kFastToBufferSize, "%.*g", DBL_DIG + 2, value);
- // Should never overflow; see above.
- DCHECK(snprintf_result > 0 && snprintf_result < kFastToBufferSize);
- }
- return buffer;
+ // Should never overflow; see above.
+ DCHECK(snprintf_result > 0 && snprintf_result < kFastToBufferSize);
+
+ return snprintf_result;
}
namespace {
@@ -325,7 +332,7 @@ bool safe_strtod(const char* str, double* value) {
return *str != '\0' && *endptr == '\0';
}
-char* FloatToBuffer(float value, char* buffer) {
+size_t FloatToBuffer(float value, char* buffer) {
// FLT_DIG is 6 for IEEE-754 floats, which are used on almost all
// platforms these days. Just in case some system exists where FLT_DIG
// is significantly larger -- and risks overflowing our buffer -- we have
@@ -347,7 +354,7 @@ char* FloatToBuffer(float value, char* buffer) {
// Should never overflow; see above.
DCHECK(snprintf_result > 0 && snprintf_result < kFastToBufferSize);
}
- return buffer;
+ return snprintf_result;
}
string FpToString(Fprint fp) {