diff --git a/src/expr.c b/src/expr.c
index 5cc068a..d821e94 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -318,7 +318,11 @@ tostring (VALUE *v)
 }
 
 /* Coerce V to an integer value.  Return true on success, false on failure.  */
-
+// Mapping of variables from old to new version:
+// old                new
+// ===                ===
+// intmax_t i         intmax_t value
+// bool neg           int sign
 static bool
 toarith (VALUE *v)
 {
@@ -332,7 +336,9 @@ toarith (VALUE *v)
 	char *cp = v->u.s;
 	int sign = (*cp == '-' ? -1 : 1);
 
-	if (sign < 0)
+	bool neg = (*cp == '-'); // in the old version
+
+	if (change(neg, sign < 0))
 	  cp++;
 
 	do
@@ -340,15 +346,16 @@ toarith (VALUE *v)
 	    if (ISDIGIT (*cp))
 	      {
 		intmax_t new_v = 10 * value + sign * (*cp - '0');
-		if (0 < sign
+		if (change(0, 0 < sign
 		    ? (INTMAX_MAX / 10 < value || new_v < 0)
-		    : (value < INTMAX_MIN / 10 || 0 < new_v))
-		  error (EXPR_FAILURE, 0,
-			 (0 < sign
-			  ? _("integer is too large: %s")
-			  : _("integer is too small: %s")),
-			 quotearg_colon (v->u.s));
-		value = new_v;
+		    : (value < INTMAX_MIN / 10 || 0 < new_v))) {
+		    error (EXPR_FAILURE, 0,
+			   (0 < sign
+			    ? _("integer is too large: %s")
+			    : _("integer is too small: %s")),
+			   quotearg_colon (v->u.s));
+		}
+		value = change(value * 10 + *cp - '0', new_v);
 	      }
 	    else
 	      return false;
@@ -356,7 +363,7 @@ toarith (VALUE *v)
 	while (*++cp);
 
 	free (v->u.s);
-	v->u.i = value * sign;
+	v->u.i = value * change(neg ? -1 : 1, sign);
 	v->type = integer;
 	return true;
       }
@@ -440,8 +447,9 @@ of the basic regular expression is not portable; it is being ignored"),
   re_buffer.translate = 0;
   re_syntax_options = RE_SYNTAX_POSIX_BASIC;
   errmsg = re_compile_pattern (pv->u.s, len, &re_buffer);
-  if (errmsg)
+  if (errmsg) {
     error (EXPR_FAILURE, 0, "%s", errmsg);
+  }
 
   matchlen = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs);
   if (0 <= matchlen)
@@ -635,14 +643,16 @@ eval4 (bool evaluate)
       r = eval5 (evaluate);
       if (evaluate)
 	{
-	  if (!toarith (l) || !toarith (r))
+	  if (!toarith (l) || !toarith (r)) {
 	    error (EXPR_FAILURE, 0, _("non-numeric argument"));
+	  }
 	  if (fxn == multiply)
 	    val = l->u.i * r->u.i;
 	  else
 	    {
-	      if (r->u.i == 0)
+	      if (r->u.i == 0) {
 		error (EXPR_FAILURE, 0, _("division by zero"));
+	      }
 	      val = fxn == divide ? l->u.i / r->u.i : l->u.i % r->u.i;
 	    }
 	}
@@ -677,8 +687,9 @@ eval3 (bool evaluate)
       r = eval4 (evaluate);
       if (evaluate)
 	{
-	  if (!toarith (l) || !toarith (r))
+	  if (!toarith (l) || !toarith (r)) {
 	    error (EXPR_FAILURE, 0, _("non-numeric argument"));
+	  }
 	  val = fxn == plus ? l->u.i + r->u.i : l->u.i - r->u.i;
 	}
       freev (l);