diff --git a/src/json.hpp b/src/json.hpp
index 0dfc11fd..ff409559 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -10619,19 +10619,19 @@ basic_json_parser_66:
                 // skip if definitely not an integer
                 if (type != value_t::number_float)
                 {
-                    // multiply last value by ten and add the new digit
-                    auto temp = value * 10 + *curptr - '0';
+                    auto digit = static_cast<number_unsigned_t>(*curptr - '0');
 
-                    // test for overflow
-                    if (temp < value || temp > max)
+                    // overflow if value * 10 + digit > max, move terms around
+                    // to avoid overflow in intermediate values
+                    if (value > (max - digit) / 10)
                     {
                         // overflow
                         type = value_t::number_float;
                     }
                     else
                     {
-                        // no overflow - save it
-                        value = temp;
+                        // no overflow
+                        value = value * 10 + digit;
                     }
                 }
             }
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 72fd0474..4366fe6d 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -9769,19 +9769,19 @@ class basic_json
                 // skip if definitely not an integer
                 if (type != value_t::number_float)
                 {
-                    // multiply last value by ten and add the new digit
-                    auto temp = value * 10 + *curptr - '0';
+                    auto digit = static_cast<number_unsigned_t>(*curptr - '0');
 
-                    // test for overflow
-                    if (temp < value || temp > max)
+                    // overflow if value * 10 + digit > max, move terms around
+                    // to avoid overflow in intermediate values
+                    if (value > (max - digit) / 10)
                     {
                         // overflow
                         type = value_t::number_float;
                     }
                     else
                     {
-                        // no overflow - save it
-                        value = temp;
+                        // no overflow
+                        value = value * 10 + digit;
                     }
                 }
             }