diff --git a/src/lex.c b/src/lex.c
index c409424ee8b8cc259b8e96f0fe3a16a4b03537f7..9016cd1fa8244f2f0d0ce6d8cc7e547cca685bd6 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -15,10 +15,6 @@
 
 #define LEXDEBUG 0
 
-/* Must do like this since at least gcc is a little too keen on
- * optimizing INT_TYPE_MUL_OVERFLOW otherwise. */
-static unsigned INT32 eight = 8, sixteen = 16, ten = 10;
-
 /* Make lexers for shifts 0, 1 and 2. */
 
 #define SHIFT	0
diff --git a/src/lexer.h b/src/lexer.h
index 7d983a6f6ff296cd0874af945ae5b638083bf40b..0c30962e3d195c1460c96d369f4a702281903022 100644
--- a/src/lexer.h
+++ b/src/lexer.h
@@ -212,11 +212,11 @@ int parse_esc_seq (WCHAR *buf, p_wchar2 *chr, ptrdiff_t *len)
 
     case '0': case '1': case '2': case '3':
     case '4': case '5': case '6': case '7': {
-      unsigned of = 0;
+      int of = 0;
       unsigned INT32 n = c-'0';
       for (l = 1; buf[l] >= '0' && buf[l] <= '8'; l++) {
-	if (!of) of = UNSIGNED_INT_TYPE_MUL_OVERFLOW (n, eight);
-	n = 8 * n + buf[l] - '0';
+	n = DO_UINT32_MUL_OVERFLOW(n, 8, &of);
+	n += buf[l] - '0';
       }
       if (of) {*len = l; return 4;}
       c = (p_wchar2)n;
@@ -229,22 +229,22 @@ int parse_esc_seq (WCHAR *buf, p_wchar2 *chr, ptrdiff_t *len)
       break;
       
     case 'x': {
-      unsigned of = 0;
+      int of = 0;
       unsigned INT32 n=0;
       for (l = 1;; l++) {
 	switch (buf[l]) {
 	  case '0': case '1': case '2': case '3': case '4':
 	  case '5': case '6': case '7': case '8': case '9':
-	    if (!of) of = UNSIGNED_INT_TYPE_MUL_OVERFLOW (n, sixteen);
-	    n = 16 * n + buf[l] - '0';
+	    n = DO_UINT32_MUL_OVERFLOW(n, 16, &of);
+	    n += buf[l] - '0';
 	    continue;
 	  case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-	    if (!of) of = UNSIGNED_INT_TYPE_MUL_OVERFLOW (n, sixteen);
-	    n = 16 * n + buf[l] - 'a' + 10;
+	    n = DO_UINT32_MUL_OVERFLOW(n, 16, &of);
+	    n += buf[l] - 'a' + 10;
 	    continue;
 	  case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-	    if (!of) of = UNSIGNED_INT_TYPE_MUL_OVERFLOW (n, sixteen);
-	    n = 16 * n + buf[l] - 'A' + 10;
+	    n = DO_UINT32_MUL_OVERFLOW(n, 16, &of);
+	    n += buf[l] - 'A' + 10;
 	    continue;
 	}
 	break;
@@ -255,14 +255,14 @@ int parse_esc_seq (WCHAR *buf, p_wchar2 *chr, ptrdiff_t *len)
     }
 
     case 'd': {
-      unsigned of = 0;
+      int of = 0;
       unsigned INT32 n=0;
       for (l = 1;; l++) {
 	switch (buf[l]) {
 	  case '0': case '1': case '2': case '3': case '4':
 	  case '5': case '6': case '7': case '8': case '9':
-	    if (!of) of = UNSIGNED_INT_TYPE_MUL_OVERFLOW (n, ten);
-	    n = 10 * n + buf[l] - '0';
+	    n = DO_UINT32_MUL_OVERFLOW(n, 10, &of);
+	    n = DO_UINT32_ADD_OVERFLOW(n, buf[l] - '0', &of);
 	    continue;
 	}
 	break;
diff --git a/src/operators.c b/src/operators.c
index cada8405de65bc72f69abd9d33cbfbb38f42400b..7f94cb370ecc2c91408fe75bcbcf33c8d67ef9cf 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -1717,20 +1717,19 @@ PMOD_EXPORT void f_add(INT32 args)
   }
 
   case BIT_INT:
+  {
 #ifdef AUTO_BIGNUM
+    int of = 0;
     size = 0;
     for(e = -args; e < 0; e++)
     {
-      if(INT_TYPE_ADD_OVERFLOW(sp[e].u.integer, size))
-      {
-	convert_svalue_to_bignum(sp-args);
-	f_add(args);
-	return;
-      }
-      else
-      {
-	size += sp[e].u.integer;
-      }
+      size = DO_INT_TYPE_ADD_OVERFLOW(size, sp[e].u.integer, &of);
+    }
+    if(of)
+    {
+      convert_svalue_to_bignum(sp-args);
+      f_add(args);
+      return;
     }
     sp-=args;
     push_int(size);
@@ -1742,6 +1741,7 @@ PMOD_EXPORT void f_add(INT32 args)
 #endif /* AUTO_BIGNUM */
     break;
 
+  }
   case BIT_FLOAT:
     if (args > 2) {
       /* Attempt to minimize the accumulated summation error
@@ -3739,18 +3739,25 @@ PMOD_EXPORT void o_multiply(void)
     return;
 
   case TWO_TYPES(T_INT,T_INT):
-#ifdef AUTO_BIGNUM
-    if(INT_TYPE_MUL_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
+  {
+    INT_TYPE res;
+#ifndef AUTO_BIGNUM
+    res = sp[-2].u.integer * sp[-1].u.integer;
+#else
+    int of = 0;
+
+    res = DO_INT_TYPE_MUL_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer, &of);
+
+    if(of)
     {
       convert_stack_top_to_bignum();
       goto do_lfun_multiply;
     }
 #endif /* AUTO_BIGNUM */
     sp--;
-    SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer,
-	     sp[-1].u.integer * sp[0].u.integer);
+    SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, res);
     return;
-
+  }
   default:
   do_lfun_multiply:
     if(call_lfun(LFUN_MULTIPLY, LFUN_RMULTIPLY))