From ed0c4037ec47e3a7d1e5d23514951e5256b8a30f Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" Date: Thu, 22 Mar 2018 10:21:59 -0700 Subject: 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 --- tensorflow/core/lib/strings/numbers.cc | 49 +++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'tensorflow/core/lib/strings/numbers.cc') 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(buffer, nullptr) != value; + if (locale_independent_strtonum(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) { -- cgit v1.2.3