diff --git a/src/macro/Expressions.cc b/src/macro/Expressions.cc
index 7eb2ce9797ffed66b460a5a6364c9acb08547e1a..ce8e91b8b3cd8fb50aae9df9326a88ed84c2fa76 100644
--- a/src/macro/Expressions.cc
+++ b/src/macro/Expressions.cc
@@ -297,6 +297,19 @@ String::is_equal(const BaseTypePtr &btp) const
   return make_shared<Bool>(value == btp2->value, env);
 }
 
+DoublePtr
+String::cast_int() const
+{
+  try
+    {
+      return make_shared<Double>(stoi(value), env);
+    }
+  catch (...)
+    {
+      throw StackTrace(value + " cannot be converted to an int");
+    }
+}
+
 BaseTypePtr
 Array::plus(const BaseTypePtr &btp) const
 {
@@ -492,6 +505,14 @@ Array::sum() const
   return make_shared<Double>(retval, env);
 }
 
+DoublePtr
+Array::cast_int() const
+{
+  if (arr.size() != 1)
+    throw StackTrace("Array must be of size 1 to be cast to an int");
+  return arr.at(0)->eval()->cast_int();
+}
+
 BoolPtr
 Tuple::is_equal(const BaseTypePtr &btp) const
 {
@@ -526,6 +547,14 @@ Tuple::contains(const BaseTypePtr &btp) const
   return make_shared<Bool>(false, env);
 }
 
+DoublePtr
+Tuple::cast_int() const
+{
+  if (tup.size() != 1)
+    throw StackTrace("Tuple must be of size 1 to be cast to an int");
+  return tup.at(0)->eval()->cast_int();
+}
+
 BaseTypePtr
 Array::eval()
 {
@@ -709,6 +738,8 @@ UnaryOp::eval()
       auto argbt = arg->eval();
       switch (op_code)
         {
+        case codes::UnaryOp::cast_int:
+          return argbt->cast_int();
         case codes::UnaryOp::logical_not:
           return argbt->logical_not();
         case codes::UnaryOp::unary_minus:
@@ -1029,6 +1060,8 @@ UnaryOp::to_string() const noexcept
   string retval = arg->to_string();
   switch (op_code)
     {
+    case codes::UnaryOp::cast_int:
+      return "(int)" + retval;
     case codes::UnaryOp::logical_not:
       return "!" + retval;
     case codes::UnaryOp::unary_minus:
@@ -1229,6 +1262,9 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept
 {
   switch (op_code)
     {
+    case codes::UnaryOp::cast_int:
+      output << "(int)";
+      break;
     case codes::UnaryOp::logical_not:
       output << "!";
       break;
@@ -1314,7 +1350,8 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept
 
   arg->print(output, matlab_output);
 
-  if (op_code != codes::UnaryOp::logical_not
+  if (op_code != codes::UnaryOp::cast_int
+      && op_code != codes::UnaryOp::logical_not
       && op_code != codes::UnaryOp::unary_plus
       && op_code != codes::UnaryOp::unary_minus)
     output << ")";
diff --git a/src/macro/Expressions.hh b/src/macro/Expressions.hh
index 2b4670f8d03bd1e31684cbb14460cd386874b3cc..d75bf2cdf0a7998dd6accc66a3d8754c8af22a2d 100644
--- a/src/macro/Expressions.hh
+++ b/src/macro/Expressions.hh
@@ -180,6 +180,7 @@ namespace macro
     virtual DoublePtr normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const { throw StackTrace("Operator `normpdf` does not exist for this type"); }
     virtual DoublePtr normcdf() const { throw StackTrace("Operator `normcdf` does not exist for this type"); }
     virtual DoublePtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const { throw StackTrace("Operator `normcdf` does not exist for this type"); }
+    virtual DoublePtr cast_int() const { throw StackTrace("This type cannot be cast to an integer"); }
   };
 
 
@@ -202,6 +203,7 @@ namespace macro
     BoolPtr logical_and(const BaseTypePtr &btp) const override;
     BoolPtr logical_or(const BaseTypePtr &btp) const override;
     BoolPtr logical_not() const override;
+    inline DoublePtr cast_int() const override { return value ? make_shared<Double>(1, env) : make_shared<Double>(0, env); }
   };
 
 
@@ -286,6 +288,7 @@ namespace macro
       return normcdf(make_shared<Double>(0, env), make_shared<Double>(1, env));
     }
     DoublePtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const override;
+    inline DoublePtr cast_int() const override { return make_shared<Double>(static_cast<int>(value), env); }
   };
 
   class String final : public BaseType
@@ -310,6 +313,7 @@ namespace macro
     BoolPtr is_greater_equal(const BaseTypePtr &btp) const override;
     BoolPtr is_equal(const BaseTypePtr &btp) const override;
     inline DoublePtr length() const override { return make_shared<Double>(value.size(), env); }
+    inline DoublePtr cast_int() const override;
   };
 
 
@@ -335,6 +339,7 @@ namespace macro
     BoolPtr is_equal(const BaseTypePtr &btp) const override;
     BoolPtr contains(const BaseTypePtr &btp) const override;
     inline DoublePtr length() const override { return make_shared<Double>(tup.size(), env); }
+    DoublePtr cast_int() const override;
   };
 
 
@@ -376,6 +381,7 @@ namespace macro
     BoolPtr contains(const BaseTypePtr &btp) const override;
     inline DoublePtr length() const override { return make_shared<Double>(arr.size(), env); }
     DoublePtr sum() const override;
+    DoublePtr cast_int() const override;
   };
 
 
diff --git a/src/macro/ForwardDeclarationsAndEnums.hh b/src/macro/ForwardDeclarationsAndEnums.hh
index 996446e4cb2dafccebe5ab950ce78450319c55c0..3da2c3c1077e61eb3ba248f0beb891e5f0ea84c8 100644
--- a/src/macro/ForwardDeclarationsAndEnums.hh
+++ b/src/macro/ForwardDeclarationsAndEnums.hh
@@ -67,6 +67,7 @@ namespace macro
 
     enum class UnaryOp
       {
+       cast_int,
        logical_not,
        unary_minus,
        unary_plus,
diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy
index 1cf97875014ace7c26e8bf2cacb7ab73dc1131e4..d2764da2345725dae67e36bfda20487ce029a413 100644
--- a/src/macro/Parser.yy
+++ b/src/macro/Parser.yy
@@ -65,6 +65,8 @@ using namespace macro;
 %token SQRT CBRT SIGN MAX MIN FLOOR CEIL TRUNC SUM MOD
 %token ERF ERFC GAMMA LGAMMA ROUND NORMPDF NORMCDF LENGTH
 
+%token INT
+
 %left OR
 %left AND
 %left EQUAL_EQUAL NOT_EQUAL
@@ -76,6 +78,7 @@ using namespace macro;
 %left PLUS MINUS
 %left TIMES DIVIDE
 %precedence UMINUS UPLUS NOT
+%precedence CAST_INT
 %nonassoc POWER
 
 %token <string> NAME TEXT QUOTED_STRING NUMBER EOL
@@ -319,6 +322,8 @@ expr : LPAREN expr RPAREN
        { $$ = make_shared<Comprehension>($2, $4, $6, driver.env, @$); }
      | LBRACKET expr FOR expr IN expr WHEN expr RBRACKET
        { $$ = make_shared<Comprehension>($2, $4, $6, $8, driver.env, @$); }
+     | LPAREN INT RPAREN expr %prec CAST_INT
+       { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_int, $4, driver.env, @$); }
      | NOT expr
        { $$ = make_shared<UnaryOp>(codes::UnaryOp::logical_not, $2, driver.env, @$); }
      | MINUS expr %prec UMINUS
diff --git a/src/macro/Tokenizer.ll b/src/macro/Tokenizer.ll
index fce6e6fb14d21d675f1f3f46021a9d3c04c86e99..d09a57b347d903849f0cd28f530dcf9d27e75b07 100644
--- a/src/macro/Tokenizer.ll
+++ b/src/macro/Tokenizer.ll
@@ -142,6 +142,8 @@ CONT \\\\{SPC}*
 <expr,eval>normpdf         { return token::NORMPDF; }
 <expr,eval>normcdf         { return token::NORMCDF; }
 
+<expr,eval>int             { return token::INT; }
+
 <expr,eval>((([0-9]*\.[0-9]+)|([0-9]+\.))([ed][-+]?[0-9]+)?)|([0-9]+([ed][-+]?[0-9]+)?)|nan|inf {
   yylval->build<string>(yytext);
   return token::NUMBER;