diff --git a/util/logging.cc b/util/logging.cc
index d48b6dd..0c2890f 100644
--- a/util/logging.cc
+++ b/util/logging.cc
@@ -46,28 +46,38 @@ std::string EscapeString(const Slice& value) {
 }
 
 bool ConsumeDecimalNumber(Slice* in, uint64_t* val) {
-  uint64_t v = 0;
-  int digits = 0;
-  while (!in->empty()) {
-    char c = (*in)[0];
-    if (c >= '0' && c <= '9') {
-      ++digits;
-      // |delta| intentionally unit64_t to avoid Android crash (see log).
-      const uint64_t delta = (c - '0');
-      static const uint64_t kMaxUint64 = ~static_cast<uint64_t>(0);
-      if (v > kMaxUint64/10 ||
-          (v == kMaxUint64/10 && delta > kMaxUint64%10)) {
-        // Overflow
-        return false;
-      }
-      v = (v * 10) + delta;
-      in->remove_prefix(1);
-    } else {
+  // Constants that will be optimized away.
+  constexpr const uint64_t kMaxUint64 = std::numeric_limits<uint64_t>::max();
+  constexpr const char kLastDigitOfMaxUint64 =
+      '0' + static_cast<char>(kMaxUint64 % 10);
+
+  uint64_t value = 0;
+
+  // reinterpret_cast-ing from char* to unsigned char* to avoid signedness.
+  const unsigned char* start =
+      reinterpret_cast<const unsigned char*>(in->data());
+
+  const unsigned char* end = start + in->size();
+  const unsigned char* current = start;
+  for (; current != end; ++current) {
+    const unsigned char ch = *current;
+    if (ch < '0' || ch > '9')
       break;
+
+    // Overflow check.
+    // kMaxUint64 / 10 is also constant and will be optimized away.
+    if (value > kMaxUint64 / 10 ||
+        (value == kMaxUint64 / 10 && ch > kLastDigitOfMaxUint64)) {
+      return false;
     }
+
+    value = (value * 10) + (ch - '0');
   }
-  *val = v;
-  return (digits > 0);
+
+  *val = value;
+  const size_t digits_consumed = current - start;
+  in->remove_prefix(digits_consumed);
+  return digits_consumed != 0;
 }
 
 }  // namespace leveldb