diff --git a/doc/macroprocessor/macroprocessor.tex b/doc/macroprocessor/macroprocessor.tex
index cd89bc55f4481da5b764a3feb72e0a32740116b9..328347a23143001ca36e78ce5d3b7d73f2bb7b39 100644
--- a/doc/macroprocessor/macroprocessor.tex
+++ b/doc/macroprocessor/macroprocessor.tex
@@ -143,7 +143,7 @@
 \item There are 6 types of macro-variables:
   \begin{itemize}
   \item boolean
-  \item double
+  \item real
   \item string
   \item tuple
   \item array
@@ -152,10 +152,10 @@
 \item Variables/literals of the types listed above can be cast to other types
   \begin{itemize}
   \item \texttt{(bool) -1 \&\& (bool) 2} $\rightarrow$ \texttt{true}
-  \item \texttt{(double) ``3.1''} $\rightarrow$ \texttt{3.1}
+  \item \texttt{(real) ``3.1''} $\rightarrow$ \texttt{3.1}
   \item \texttt{(array) 4} $\rightarrow$ \texttt{[4]}
-  \item \texttt{(double) [5]} $\rightarrow$ \texttt{5}
-  \item \texttt{(double) [6, 7]} $\rightarrow$ \texttt{error}
+  \item \texttt{(real) [5]} $\rightarrow$ \texttt{5}
+  \item \texttt{(real) [6, 7]} $\rightarrow$ \texttt{error}
   \end{itemize}
 \end{itemize}
 \end{frame}
@@ -186,8 +186,8 @@
 \end{frame}
 
 \begin{frame}[fragile=singleslide]
-  \frametitle{Macro-expressions (3/8): Double}
-  \begin{block}{Operators on doubles}
+  \frametitle{Macro-expressions (3/8): Real}
+  \begin{block}{Operators on reals}
     \begin{itemize}
     \item arithmetic operators: \texttt{+ - * / \^{}}
     \item comparison operators: \texttt{< > <= >= == !=}
@@ -196,7 +196,7 @@
     \end{itemize}
   \end{block}
 
-  \begin{block}{Functions for doubles}
+  \begin{block}{Functions for reals}
     \begin{itemize}
     \item \texttt{min, max, exp, ln (or log), log10}
     \item \texttt{sin, cos, tan, asin, acos, atan}
diff --git a/src/macro/Directives.cc b/src/macro/Directives.cc
index daa781e8f09f80c2b77e4bbcd3b1e889221a22f8..ee5e6b7b3f93d93a71b0819b5328f84ccd066ae4 100644
--- a/src/macro/Directives.cc
+++ b/src/macro/Directives.cc
@@ -210,11 +210,11 @@ For::interpret(ostream &output, bool no_line_macro)
 void
 If::interpret(ostream &output, bool no_line_macro)
 {
-  DoublePtr dp;
+  RealPtr dp;
   BoolPtr bp;
   try
     {
-      dp = dynamic_pointer_cast<Double>(condition->eval());
+      dp = dynamic_pointer_cast<Real>(condition->eval());
       bp = dynamic_pointer_cast<Bool>(condition->eval());
       if (!bp && !dp)
         error(StackTrace("@#if", "The condition must evaluate to a boolean or a double", location));
diff --git a/src/macro/Expressions.cc b/src/macro/Expressions.cc
index f2c472d9e5b00061ea9bcc3be0a9dd86f7263e25..084a9ca0e2bff0c11f99b6e3296fa95b19d972f1 100644
--- a/src/macro/Expressions.cc
+++ b/src/macro/Expressions.cc
@@ -45,7 +45,7 @@ Bool::logical_and(const BaseTypePtr &btp) const
   if (btp2)
     return make_shared<Bool>(value && btp2->value, env);
 
-  auto btp3 = dynamic_pointer_cast<Double>(btp);
+  auto btp3 = dynamic_pointer_cast<Real>(btp);
   if (btp3)
     return make_shared<Bool>(value && *btp3, env);
 
@@ -59,7 +59,7 @@ Bool::logical_or(const BaseTypePtr &btp) const
   if (btp2)
     return make_shared<Bool>(value || btp2->value, env);
 
-  auto btp3 = dynamic_pointer_cast<Double>(btp);
+  auto btp3 = dynamic_pointer_cast<Real>(btp);
   if (btp3)
     return make_shared<Bool>(value || *btp3, env);
 
@@ -73,99 +73,99 @@ Bool::logical_not() const
 }
 
 BaseTypePtr
-Double::plus(const BaseTypePtr &btp) const
+Real::plus(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of + operator");
-  return make_shared<Double>(value + btp2->value, env);
+  return make_shared<Real>(value + btp2->value, env);
 }
 
 BaseTypePtr
-Double::minus(const BaseTypePtr &btp) const
+Real::minus(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of - operator");
-  return make_shared<Double>(value - btp2->value, env);
+  return make_shared<Real>(value - btp2->value, env);
 }
 
 BaseTypePtr
-Double::times(const BaseTypePtr &btp) const
+Real::times(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of * operator");
-  return make_shared<Double>(value * btp2->value, env);
+  return make_shared<Real>(value * btp2->value, env);
 }
 
 BaseTypePtr
-Double::divide(const BaseTypePtr &btp) const
+Real::divide(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of / operator");
-  return make_shared<Double>(value / btp2->value, env);
+  return make_shared<Real>(value / btp2->value, env);
 }
 
 BaseTypePtr
-Double::power(const BaseTypePtr &btp) const
+Real::power(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of ^ operator");
-  return make_shared<Double>(pow(value, btp2->value), env);
+  return make_shared<Real>(pow(value, btp2->value), env);
 }
 
 BoolPtr
-Double::is_less(const BaseTypePtr &btp) const
+Real::is_less(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of < operator");
   return make_shared<Bool>(isless(value, btp2->value), env);
 }
 
 BoolPtr
-Double::is_greater(const BaseTypePtr &btp) const
+Real::is_greater(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of > operator");
   return make_shared<Bool>(isgreater(value, btp2->value), env);
 }
 
 BoolPtr
-Double::is_less_equal(const BaseTypePtr &btp) const
+Real::is_less_equal(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of <= operator");
   return make_shared<Bool>(islessequal(value, btp2->value), env);
 }
 
 BoolPtr
-Double::is_greater_equal(const BaseTypePtr &btp) const
+Real::is_greater_equal(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of >= operator");
   return make_shared<Bool>(isgreaterequal(value, btp2->value), env);
 }
 
 BoolPtr
-Double::is_equal(const BaseTypePtr &btp) const
+Real::is_equal(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     return make_shared<Bool>(false, env);
   return make_shared<Bool>(value == btp2->value, env);
 }
 
 BoolPtr
-Double::logical_and(const BaseTypePtr &btp) const
+Real::logical_and(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (btp2)
     return make_shared<Bool>(value && btp2->value, env);
 
@@ -177,9 +177,9 @@ Double::logical_and(const BaseTypePtr &btp) const
 }
 
 BoolPtr
-Double::logical_or(const BaseTypePtr &btp) const
+Real::logical_or(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     return make_shared<Bool>(value || btp2->value, env);
 
@@ -191,56 +191,56 @@ Double::logical_or(const BaseTypePtr &btp) const
 }
 
 BoolPtr
-Double::logical_not() const
+Real::logical_not() const
 {
   return make_shared<Bool>(!value, env);
 }
 
-DoublePtr
-Double::max(const BaseTypePtr &btp) const
+RealPtr
+Real::max(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of `max` operator");
-  return make_shared<Double>(std::max(value, btp2->value), env);
+  return make_shared<Real>(std::max(value, btp2->value), env);
 }
 
-DoublePtr
-Double::min(const BaseTypePtr &btp) const
+RealPtr
+Real::min(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of `min` operator");
-  return make_shared<Double>(std::min(value, btp2->value), env);
+  return make_shared<Real>(std::min(value, btp2->value), env);
 }
 
-DoublePtr
-Double::mod(const BaseTypePtr &btp) const
+RealPtr
+Real::mod(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("Type mismatch for operands of `mod` operator");
-  return make_shared<Double>(std::fmod(value, btp2->value), env);
+  return make_shared<Real>(std::fmod(value, btp2->value), env);
 }
 
-DoublePtr
-Double::normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const
+RealPtr
+Real::normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const
 {
-  auto btp12 = dynamic_pointer_cast<Double>(btp1);
-  auto btp22 = dynamic_pointer_cast<Double>(btp2);
+  auto btp12 = dynamic_pointer_cast<Real>(btp1);
+  auto btp22 = dynamic_pointer_cast<Real>(btp2);
   if (!btp12 || !btp22)
     throw StackTrace("Type mismatch for operands of `normpdf` operator");
-  return make_shared<Double>((1/(btp22->value*std::sqrt(2*M_PI)*std::exp(pow((value-btp12->value)/btp22->value, 2)/2))), env);
+  return make_shared<Real>((1/(btp22->value*std::sqrt(2*M_PI)*std::exp(pow((value-btp12->value)/btp22->value, 2)/2))), env);
 }
 
-DoublePtr
-Double::normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const
+RealPtr
+Real::normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const
 {
-  auto btp12 = dynamic_pointer_cast<Double>(btp1);
-  auto btp22 = dynamic_pointer_cast<Double>(btp2);
+  auto btp12 = dynamic_pointer_cast<Real>(btp1);
+  auto btp22 = dynamic_pointer_cast<Real>(btp2);
   if (!btp12 || !btp22)
     throw StackTrace("Type mismatch for operands of `normpdf` operator");
-  return make_shared<Double>((0.5*(1+std::erf((value-btp12->value)/btp22->value/M_SQRT2))), env);
+  return make_shared<Real>((0.5*(1+std::erf((value-btp12->value)/btp22->value/M_SQRT2))), env);
 }
 
 BaseTypePtr
@@ -324,8 +324,8 @@ String::cast_bool() const
     }
 }
 
-DoublePtr
-String::cast_double() const
+RealPtr
+String::cast_real() const
 {
   try
     {
@@ -333,7 +333,7 @@ String::cast_double() const
       double value_d = stod(value, &pos);
       if (pos != value.length())
         throw StackTrace("Entire string not converted");
-      return make_shared<Double>(value_d, env);
+      return make_shared<Real>(value_d, env);
     }
   catch (...)
     {
@@ -391,14 +391,14 @@ Array::times(const BaseTypePtr &btp) const
     for (auto & itr : btp2->getValue())
       {
         vector<ExpressionPtr> new_tuple;
-        if (dynamic_pointer_cast<Double>(itl) || dynamic_pointer_cast<String>(itl))
+        if (dynamic_pointer_cast<Real>(itl) || dynamic_pointer_cast<String>(itl))
           new_tuple.push_back(itl);
         else if (dynamic_pointer_cast<Tuple>(itl))
           new_tuple = dynamic_pointer_cast<Tuple>(itl)->getValue();
         else
           throw StackTrace("Array::times: unsupported type on lhs");
 
-        if (dynamic_pointer_cast<Double>(itr) || dynamic_pointer_cast<String>(itr))
+        if (dynamic_pointer_cast<Real>(itr) || dynamic_pointer_cast<String>(itr))
           new_tuple.push_back(itr);
         else if (dynamic_pointer_cast<Tuple>(itr))
           for (auto & tit : dynamic_pointer_cast<Tuple>(itr)->getValue())
@@ -415,7 +415,7 @@ Array::times(const BaseTypePtr &btp) const
 BaseTypePtr
 Array::power(const BaseTypePtr &btp) const
 {
-  auto btp2 = dynamic_pointer_cast<Double>(btp);
+  auto btp2 = dynamic_pointer_cast<Real>(btp);
   if (!btp2)
     throw StackTrace("The second argument of the power operator (^) must be a double");
 
@@ -522,18 +522,18 @@ Array::contains(const BaseTypePtr &btp) const
   return make_shared<Bool>(false, env);
 }
 
-DoublePtr
+RealPtr
 Array::sum() const
 {
   double retval = 0;
   for (auto & v : arr)
     {
-      auto v2 = dynamic_pointer_cast<Double>(v);
+      auto v2 = dynamic_pointer_cast<Real>(v);
       if (!v2)
         throw StackTrace("Type mismatch for operands of in operator");
       retval += *v2;
     }
-  return make_shared<Double>(retval, env);
+  return make_shared<Real>(retval, env);
 }
 
 BoolPtr
@@ -544,12 +544,12 @@ Array::cast_bool() const
   return arr.at(0)->eval()->cast_bool();
 }
 
-DoublePtr
-Array::cast_double() const
+RealPtr
+Array::cast_real() const
 {
   if (arr.size() != 1)
     throw StackTrace("Array must be of size 1 to be cast to a double");
-  return arr.at(0)->eval()->cast_double();
+  return arr.at(0)->eval()->cast_real();
 }
 
 BoolPtr
@@ -594,12 +594,12 @@ Tuple::cast_bool() const
   return tup.at(0)->eval()->cast_bool();
 }
 
-DoublePtr
-Tuple::cast_double() const
+RealPtr
+Tuple::cast_real() const
 {
   if (tup.size() != 1)
     throw StackTrace("Tuple must be of size 1 to be cast to a double");
-  return tup.at(0)->eval()->cast_double();
+  return tup.at(0)->eval()->cast_real();
 }
 
 BaseTypePtr
@@ -607,16 +607,16 @@ Array::eval()
 {
   if (arr.empty() && range1 && range2)
     {
-      DoublePtr range1dbl = dynamic_pointer_cast<Double>(range1->eval());
-      DoublePtr range2dbl = dynamic_pointer_cast<Double>(range2->eval());
+      RealPtr range1dbl = dynamic_pointer_cast<Real>(range1->eval());
+      RealPtr range2dbl = dynamic_pointer_cast<Real>(range2->eval());
       if (!range1dbl || !range2dbl)
         throw StackTrace("To create an array from a range using the colon operator, "
                          "the arguments must evaluate to doubles");
 
-      DoublePtr incdbl = make_shared<Double>(1, env);
+      RealPtr incdbl = make_shared<Real>(1, env);
       if (increment)
         {
-          incdbl = dynamic_pointer_cast<Double>(increment->eval());
+          incdbl = dynamic_pointer_cast<Real>(increment->eval());
           if (!incdbl)
             throw StackTrace("To create an array from a range using the colon operator, "
                              "the increment must evaluate to a double");
@@ -624,10 +624,10 @@ Array::eval()
 
       if (*incdbl > 0 && *range1dbl < *range2dbl)
         for (double i = *range1dbl; i <= *range2dbl; i += *incdbl)
-          arr.emplace_back(make_shared<Double>(i, env));
+          arr.emplace_back(make_shared<Real>(i, env));
       else if (*range1dbl > *range2dbl && *incdbl < 0)
         for (double i = *range1dbl; i >= *range2dbl; i += *incdbl)
-          arr.emplace_back(make_shared<Double>(i, env));
+          arr.emplace_back(make_shared<Real>(i, env));
 
       range1 = increment = range2 = nullptr;
     }
@@ -660,7 +660,7 @@ Variable::eval()
         {
           // Necessary to handle indexes like: y[1:2,2]
           // In general this evaluates to [[1:2],2] but when subscripting we want to expand it to [1,2,2]
-          auto db = dynamic_pointer_cast<Double>(it);
+          auto db = dynamic_pointer_cast<Real>(it);
           if (db)
             {
               if (modf(*db, &intpart) != 0.0)
@@ -671,7 +671,7 @@ Variable::eval()
           else if (dynamic_pointer_cast<Array>(it))
             for (auto it1 : dynamic_pointer_cast<Array>(it)->getValue())
               {
-                db = dynamic_pointer_cast<Double>(it1);
+                db = dynamic_pointer_cast<Real>(it1);
                 if (db)
                   {
                     if (modf(*db, &intpart) != 0.0)
@@ -692,7 +692,7 @@ Variable::eval()
         {
         case codes::BaseType::Bool:
           throw StackTrace("variable", "You cannot index a boolean", location);
-        case codes::BaseType::Double:
+        case codes::BaseType::Real:
           throw StackTrace("variable", "You cannot index a double", location);
         case codes::BaseType::Tuple:
           throw StackTrace("variable", "You cannot index a tuple", location);
@@ -787,8 +787,8 @@ UnaryOp::eval()
         {
         case codes::UnaryOp::cast_bool:
           return argbt->cast_bool();
-        case codes::UnaryOp::cast_double:
-          return argbt->cast_double();
+        case codes::UnaryOp::cast_real:
+          return argbt->cast_real();
         case codes::UnaryOp::cast_string:
           return argbt->cast_string();
         case codes::UnaryOp::cast_tuple:
@@ -1013,11 +1013,11 @@ Comprehension::eval()
           values.emplace_back(c_expr->clone()->eval());
       else
         {
-          DoublePtr dp;
+          RealPtr dp;
           BoolPtr bp;
           try
             {
-              dp = dynamic_pointer_cast<Double>(c_when->eval());
+              dp = dynamic_pointer_cast<Real>(c_when->eval());
               bp = dynamic_pointer_cast<Bool>(c_when->eval());
               if (!bp && !dp)
                 throw StackTrace("The condition must evaluate to a boolean or a double");
@@ -1117,8 +1117,8 @@ UnaryOp::to_string() const noexcept
     {
     case codes::UnaryOp::cast_bool:
       return "(bool)" + retval;
-    case codes::UnaryOp::cast_double:
-      return "(double)" + retval;
+    case codes::UnaryOp::cast_real:
+      return "(real)" + retval;
     case codes::UnaryOp::cast_string:
       return "(string)" + retval;
     case codes::UnaryOp::cast_tuple:
@@ -1328,8 +1328,8 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept
     case codes::UnaryOp::cast_bool:
       output << "(bool)";
       break;
-    case codes::UnaryOp::cast_double:
-      output << "(double)";
+    case codes::UnaryOp::cast_real:
+      output << "(real)";
       break;
     case codes::UnaryOp::cast_string:
       output << "(string)";
@@ -1426,7 +1426,7 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept
   arg->print(output, matlab_output);
 
   if (op_code != codes::UnaryOp::cast_bool
-      && op_code != codes::UnaryOp::cast_double
+      && op_code != codes::UnaryOp::cast_real
       && op_code != codes::UnaryOp::cast_string
       && op_code != codes::UnaryOp::cast_tuple
       && op_code != codes::UnaryOp::cast_array
diff --git a/src/macro/Expressions.hh b/src/macro/Expressions.hh
index 4f70551046c9dd0350f902be6a09b3e0cef90cf9..fc454b5f319ed33568708bb08247a9252fd5f838 100644
--- a/src/macro/Expressions.hh
+++ b/src/macro/Expressions.hh
@@ -147,41 +147,41 @@ namespace macro
     virtual ArrayPtr set_union(const BaseTypePtr &btp) const { throw StackTrace("Operator | does not exist for this type"); }
     virtual ArrayPtr set_intersection(const BaseTypePtr &btp) const { throw StackTrace("Operator & does not exist for this type"); }
     virtual BoolPtr contains(const BaseTypePtr &btp) const { throw StackTrace("Second argument of `in` operator must be an array"); }
-    virtual DoublePtr length() const { throw StackTrace("Operator `length` does not exist for this type"); }
-    virtual DoublePtr max(const BaseTypePtr &btp) const { throw StackTrace("Operator `max` does not exist for this type"); }
-    virtual DoublePtr min(const BaseTypePtr &btp) const { throw StackTrace("Operator `min` does not exist for this type"); }
-    virtual DoublePtr mod(const BaseTypePtr &btp) const { throw StackTrace("Operator `mod` does not exist for this type"); }
-    virtual DoublePtr exp() const { throw StackTrace("Operator `exp` does not exist for this type"); }
-    virtual DoublePtr ln() const { throw StackTrace("Operator `ln` does not exist for this type"); }
-    virtual DoublePtr log10() const { throw StackTrace("Operator `log10` does not exist for this type"); }
+    virtual RealPtr length() const { throw StackTrace("Operator `length` does not exist for this type"); }
+    virtual RealPtr max(const BaseTypePtr &btp) const { throw StackTrace("Operator `max` does not exist for this type"); }
+    virtual RealPtr min(const BaseTypePtr &btp) const { throw StackTrace("Operator `min` does not exist for this type"); }
+    virtual RealPtr mod(const BaseTypePtr &btp) const { throw StackTrace("Operator `mod` does not exist for this type"); }
+    virtual RealPtr exp() const { throw StackTrace("Operator `exp` does not exist for this type"); }
+    virtual RealPtr ln() const { throw StackTrace("Operator `ln` does not exist for this type"); }
+    virtual RealPtr log10() const { throw StackTrace("Operator `log10` does not exist for this type"); }
     virtual BoolPtr isinf() const { throw StackTrace("Operator `isinf` does not exist for this type"); }
     virtual BoolPtr isnan() const { throw StackTrace("Operator `isnan` does not exist for this type"); }
     virtual BoolPtr isfinite() const { throw StackTrace("Operator `isfinite` does not exist for this type"); }
     virtual BoolPtr isnormal() const { throw StackTrace("Operator `isnormal` does not exist for this type"); }
-    virtual DoublePtr sin() const { throw StackTrace("Operator `sin` does not exist for this type"); }
-    virtual DoublePtr cos() const { throw StackTrace("Operator `cos` does not exist for this type"); }
-    virtual DoublePtr tan() const { throw StackTrace("Operator `tan` does not exist for this type"); }
-    virtual DoublePtr asin() const { throw StackTrace("Operator `asin` does not exist for this type"); }
-    virtual DoublePtr acos() const { throw StackTrace("Operator `acos` does not exist for this type"); }
-    virtual DoublePtr atan() const { throw StackTrace("Operator `atan` does not exist for this type"); }
-    virtual DoublePtr sqrt() const { throw StackTrace("Operator `sqrt` does not exist for this type"); }
-    virtual DoublePtr cbrt() const { throw StackTrace("Operator `cbrt` does not exist for this type"); }
-    virtual DoublePtr sign() const { throw StackTrace("Operator `sign` does not exist for this type"); }
-    virtual DoublePtr floor() const { throw StackTrace("Operator `floor` does not exist for this type"); }
-    virtual DoublePtr ceil() const { throw StackTrace("Operator `ceil` does not exist for this type"); }
-    virtual DoublePtr trunc() const { throw StackTrace("Operator `trunc` does not exist for this type"); }
-    virtual DoublePtr sum() const { throw StackTrace("Operator `sum` does not exist for this type"); }
-    virtual DoublePtr erf() const { throw StackTrace("Operator `erf` does not exist for this type"); }
-    virtual DoublePtr erfc() const { throw StackTrace("Operator `erfc` does not exist for this type"); }
-    virtual DoublePtr gamma() const { throw StackTrace("Operator `gamma` does not exist for this type"); }
-    virtual DoublePtr lgamma() const { throw StackTrace("Operator `lgamma` does not exist for this type"); }
-    virtual DoublePtr round() const { throw StackTrace("Operator `round` does not exist for this type"); }
-    virtual DoublePtr normpdf() const { throw StackTrace("Operator `normpdf` does not exist for this type"); }
-    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 RealPtr sin() const { throw StackTrace("Operator `sin` does not exist for this type"); }
+    virtual RealPtr cos() const { throw StackTrace("Operator `cos` does not exist for this type"); }
+    virtual RealPtr tan() const { throw StackTrace("Operator `tan` does not exist for this type"); }
+    virtual RealPtr asin() const { throw StackTrace("Operator `asin` does not exist for this type"); }
+    virtual RealPtr acos() const { throw StackTrace("Operator `acos` does not exist for this type"); }
+    virtual RealPtr atan() const { throw StackTrace("Operator `atan` does not exist for this type"); }
+    virtual RealPtr sqrt() const { throw StackTrace("Operator `sqrt` does not exist for this type"); }
+    virtual RealPtr cbrt() const { throw StackTrace("Operator `cbrt` does not exist for this type"); }
+    virtual RealPtr sign() const { throw StackTrace("Operator `sign` does not exist for this type"); }
+    virtual RealPtr floor() const { throw StackTrace("Operator `floor` does not exist for this type"); }
+    virtual RealPtr ceil() const { throw StackTrace("Operator `ceil` does not exist for this type"); }
+    virtual RealPtr trunc() const { throw StackTrace("Operator `trunc` does not exist for this type"); }
+    virtual RealPtr sum() const { throw StackTrace("Operator `sum` does not exist for this type"); }
+    virtual RealPtr erf() const { throw StackTrace("Operator `erf` does not exist for this type"); }
+    virtual RealPtr erfc() const { throw StackTrace("Operator `erfc` does not exist for this type"); }
+    virtual RealPtr gamma() const { throw StackTrace("Operator `gamma` does not exist for this type"); }
+    virtual RealPtr lgamma() const { throw StackTrace("Operator `lgamma` does not exist for this type"); }
+    virtual RealPtr round() const { throw StackTrace("Operator `round` does not exist for this type"); }
+    virtual RealPtr normpdf() const { throw StackTrace("Operator `normpdf` does not exist for this type"); }
+    virtual RealPtr normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const { throw StackTrace("Operator `normpdf` does not exist for this type"); }
+    virtual RealPtr normcdf() const { throw StackTrace("Operator `normcdf` does not exist for this type"); }
+    virtual RealPtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const { throw StackTrace("Operator `normcdf` does not exist for this type"); }
     virtual BoolPtr cast_bool() const { throw StackTrace("This type cannot be cast to a boolean"); }
-    virtual DoublePtr cast_double() const { throw StackTrace("This type cannot be cast to a double"); }
+    virtual RealPtr cast_real() const { throw StackTrace("This type cannot be cast to a double"); }
     virtual StringPtr cast_string() const { throw StackTrace("This type cannot be cast to a string"); }
     virtual TuplePtr cast_tuple() const { throw StackTrace("This type cannot be cast to a tuple"); }
     virtual ArrayPtr cast_array() const { throw StackTrace("This type cannot be cast to an array"); }
@@ -208,7 +208,7 @@ namespace macro
     BoolPtr logical_or(const BaseTypePtr &btp) const override;
     BoolPtr logical_not() const override;
     inline BoolPtr cast_bool() const override { return make_shared<Bool>(value, env); }
-    inline DoublePtr cast_double() const override { return value ? make_shared<Double>(1, env) : make_shared<Double>(0, env); }
+    inline RealPtr cast_real() const override { return value ? make_shared<Real>(1, env) : make_shared<Real>(0, env); }
     inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); }
     inline TuplePtr cast_tuple() const override
     {
@@ -221,22 +221,22 @@ namespace macro
   };
 
 
-  class Double final : public BaseType
+  class Real final : public BaseType
   {
   private:
     double value;
   public:
     // Use strtod to handle extreme cases (e.g. 1e500, 1e-500), nan, inf
     // See Note in NumericalConstants::AddNonNegativeConstant
-    Double(const string value_arg,
-           Environment &env_arg, Tokenizer::location location_arg = Tokenizer::location()) :
+    Real(const string value_arg,
+         Environment &env_arg, Tokenizer::location location_arg = Tokenizer::location()) :
       BaseType(env_arg, move(location_arg)),
       value{strtod(value_arg.c_str(), nullptr)} { }
-    Double(double value_arg,
-           Environment &env_arg, Tokenizer::location location_arg = Tokenizer::location()) :
+    Real(double value_arg,
+         Environment &env_arg, Tokenizer::location location_arg = Tokenizer::location()) :
       BaseType(env_arg, move(location_arg)),
       value{value_arg} { }
-    inline codes::BaseType getType() const noexcept override { return codes::BaseType::Double; }
+    inline codes::BaseType getType() const noexcept override { return codes::BaseType::Real; }
     inline string to_string() const noexcept override
     {
       ostringstream strs;
@@ -244,13 +244,13 @@ namespace macro
       return strs.str();
     }
     inline void print(ostream &output, bool matlab_output = false) const noexcept override { output << to_string(); }
-    inline ExpressionPtr clone() const noexcept override { return make_shared<Double>(value, env, location); }
+    inline ExpressionPtr clone() const noexcept override { return make_shared<Real>(value, env, location); }
   public:
     operator double() const { return value; }
     BaseTypePtr plus(const BaseTypePtr &bt) const override;
-    inline BaseTypePtr unary_plus() const override { return make_shared<Double>(value, env); }
+    inline BaseTypePtr unary_plus() const override { return make_shared<Real>(value, env); }
     BaseTypePtr minus(const BaseTypePtr &bt) const override;
-    inline BaseTypePtr unary_minus() const override { return make_shared<Double>(-value, env); }
+    inline BaseTypePtr unary_minus() const override { return make_shared<Real>(-value, env); }
     BaseTypePtr times(const BaseTypePtr &bt) const override;
     BaseTypePtr divide(const BaseTypePtr &bt) const override;
     BaseTypePtr power(const BaseTypePtr &btp) const override;
@@ -262,56 +262,56 @@ namespace macro
     BoolPtr logical_and(const BaseTypePtr &btp) const override;
     BoolPtr logical_or(const BaseTypePtr &btp) const override;
     BoolPtr logical_not() const override;
-    DoublePtr max(const BaseTypePtr &btp) const override;
-    DoublePtr min(const BaseTypePtr &btp) const override;
-    DoublePtr mod(const BaseTypePtr &btp) const override;
-    inline DoublePtr exp() const override { return make_shared<Double>(std::exp(value), env); }
-    inline DoublePtr ln() const override { return make_shared<Double>(std::log(value), env); }
-    inline DoublePtr log10() const override { return make_shared<Double>(std::log10(value), env); }
+    RealPtr max(const BaseTypePtr &btp) const override;
+    RealPtr min(const BaseTypePtr &btp) const override;
+    RealPtr mod(const BaseTypePtr &btp) const override;
+    inline RealPtr exp() const override { return make_shared<Real>(std::exp(value), env); }
+    inline RealPtr ln() const override { return make_shared<Real>(std::log(value), env); }
+    inline RealPtr log10() const override { return make_shared<Real>(std::log10(value), env); }
     inline BoolPtr isinf() const override { return make_shared<Bool>(std::isinf(value), env); }
     inline BoolPtr isnan() const override { return make_shared<Bool>(std::isnan(value), env); }
     inline BoolPtr isfinite() const override { return make_shared<Bool>(std::isfinite(value), env); }
     inline BoolPtr isnormal() const override { return make_shared<Bool>(std::isnormal(value), env); }
-    inline DoublePtr sin() const override { return make_shared<Double>(std::sin(value), env); }
-    inline DoublePtr cos() const override { return make_shared<Double>(std::cos(value), env); }
-    inline DoublePtr tan() const override { return make_shared<Double>(std::tan(value), env); }
-    inline DoublePtr asin() const override { return make_shared<Double>(std::asin(value), env); }
-    inline DoublePtr acos() const override { return make_shared<Double>(std::acos(value), env); }
-    inline DoublePtr atan() const override { return make_shared<Double>(std::atan(value), env); }
-    inline DoublePtr sqrt() const override { return make_shared<Double>(std::sqrt(value), env); }
-    inline DoublePtr cbrt() const override { return make_shared<Double>(std::cbrt(value), env); }
-    inline DoublePtr sign() const override
+    inline RealPtr sin() const override { return make_shared<Real>(std::sin(value), env); }
+    inline RealPtr cos() const override { return make_shared<Real>(std::cos(value), env); }
+    inline RealPtr tan() const override { return make_shared<Real>(std::tan(value), env); }
+    inline RealPtr asin() const override { return make_shared<Real>(std::asin(value), env); }
+    inline RealPtr acos() const override { return make_shared<Real>(std::acos(value), env); }
+    inline RealPtr atan() const override { return make_shared<Real>(std::atan(value), env); }
+    inline RealPtr sqrt() const override { return make_shared<Real>(std::sqrt(value), env); }
+    inline RealPtr cbrt() const override { return make_shared<Real>(std::cbrt(value), env); }
+    inline RealPtr sign() const override
     {
-      return make_shared<Double>((value > 0) ? 1. : ((value < 0) ? -1. : 0.), env);
+      return make_shared<Real>((value > 0) ? 1. : ((value < 0) ? -1. : 0.), env);
     }
-    inline DoublePtr floor() const override { return make_shared<Double>(std::floor(value), env); }
-    inline DoublePtr ceil() const override { return make_shared<Double>(std::ceil(value), env); }
-    inline DoublePtr trunc() const override { return make_shared<Double>(std::trunc(value), env); }
-    inline DoublePtr erf() const override { return make_shared<Double>(std::erf(value), env); }
-    inline DoublePtr erfc() const override { return make_shared<Double>(std::erfc(value), env); }
-    inline DoublePtr gamma() const override { return make_shared<Double>(std::tgamma(value), env); }
-    inline DoublePtr lgamma() const override { return make_shared<Double>(std::lgamma(value), env); }
-    inline DoublePtr round() const override { return make_shared<Double>(std::round(value), env); }
-    inline DoublePtr normpdf() const override
+    inline RealPtr floor() const override { return make_shared<Real>(std::floor(value), env); }
+    inline RealPtr ceil() const override { return make_shared<Real>(std::ceil(value), env); }
+    inline RealPtr trunc() const override { return make_shared<Real>(std::trunc(value), env); }
+    inline RealPtr erf() const override { return make_shared<Real>(std::erf(value), env); }
+    inline RealPtr erfc() const override { return make_shared<Real>(std::erfc(value), env); }
+    inline RealPtr gamma() const override { return make_shared<Real>(std::tgamma(value), env); }
+    inline RealPtr lgamma() const override { return make_shared<Real>(std::lgamma(value), env); }
+    inline RealPtr round() const override { return make_shared<Real>(std::round(value), env); }
+    inline RealPtr normpdf() const override
     {
-      return normpdf(make_shared<Double>(0, env), make_shared<Double>(1, env));
+      return normpdf(make_shared<Real>(0, env), make_shared<Real>(1, env));
     }
-    DoublePtr normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const override;
-    inline DoublePtr normcdf() const override
+    RealPtr normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const override;
+    inline RealPtr normcdf() const override
     {
-      return normcdf(make_shared<Double>(0, env), make_shared<Double>(1, env));
+      return normcdf(make_shared<Real>(0, env), make_shared<Real>(1, env));
     }
-    DoublePtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const override;
+    RealPtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const override;
     inline BoolPtr cast_bool() const override { return make_shared<Bool>(static_cast<bool>(value), env); }
-    inline DoublePtr cast_double() const override { return make_shared<Double>(value, env); }
+    inline RealPtr cast_real() const override { return make_shared<Real>(value, env); }
     inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); }
     inline TuplePtr cast_tuple() const override
     {
-      return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<Double>(value, env)}, env);
+      return make_shared<Tuple>(vector<ExpressionPtr>{make_shared<Real>(value, env)}, env);
     }
     inline ArrayPtr cast_array() const override
     {
-      return make_shared<Array>(vector<ExpressionPtr>{make_shared<Double>(value, env)}, env);
+      return make_shared<Array>(vector<ExpressionPtr>{make_shared<Real>(value, env)}, env);
     }
   };
 
@@ -336,9 +336,9 @@ namespace macro
     BoolPtr is_less_equal(const BaseTypePtr &btp) const override;
     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 RealPtr length() const override { return make_shared<Real>(value.size(), env); }
     BoolPtr cast_bool() const override;
-    DoublePtr cast_double() const override;
+    RealPtr cast_real() const override;
     inline StringPtr cast_string() const override { return make_shared<String>(value, env); }
     inline TuplePtr cast_tuple() const override
     {
@@ -372,9 +372,9 @@ namespace macro
     inline ExpressionPtr at(int i) const { return tup.at(i); }
     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); }
+    inline RealPtr length() const override { return make_shared<Real>(tup.size(), env); }
     BoolPtr cast_bool() const override;
-    DoublePtr cast_double() const override;
+    RealPtr cast_real() const override;
     inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); }
     inline TuplePtr cast_tuple() const override { return make_shared<Tuple>(tup, env); }
     inline ArrayPtr cast_array() const override { return make_shared<Array>(tup, env); }
@@ -417,10 +417,10 @@ namespace macro
     ArrayPtr set_union(const BaseTypePtr &btp) const override;
     ArrayPtr set_intersection(const BaseTypePtr &btp) const override;
     BoolPtr contains(const BaseTypePtr &btp) const override;
-    inline DoublePtr length() const override { return make_shared<Double>(arr.size(), env); }
-    DoublePtr sum() const override;
+    inline RealPtr length() const override { return make_shared<Real>(arr.size(), env); }
+    RealPtr sum() const override;
     BoolPtr cast_bool() const override;
-    DoublePtr cast_double() const override;
+    RealPtr cast_real() const override;
     inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); }
     inline TuplePtr cast_tuple() const override { return make_shared<Tuple>(arr, env); }
     inline ArrayPtr cast_array() const override { return make_shared<Array>(arr, env); }
diff --git a/src/macro/ForwardDeclarationsAndEnums.hh b/src/macro/ForwardDeclarationsAndEnums.hh
index 9c2b01b19f9dbba9b4af918c59f4c7d9d3da9a37..a606482c4ee248808c95b9d8119ab1c7dc3dbe84 100644
--- a/src/macro/ForwardDeclarationsAndEnums.hh
+++ b/src/macro/ForwardDeclarationsAndEnums.hh
@@ -31,8 +31,8 @@ namespace macro
   using BaseTypePtr = shared_ptr<BaseType>;
   class Bool;
   using BoolPtr = shared_ptr<Bool>;
-  class Double;
-  using DoublePtr = shared_ptr<Double>;
+  class Real;
+  using RealPtr = shared_ptr<Real>;
   class String;
   using StringPtr = shared_ptr<String>;
   class Tuple;
@@ -59,7 +59,7 @@ namespace macro
     enum class BaseType
       {
        Bool,
-       Double,
+       Real,
        String,
        Array,
        Tuple
@@ -68,7 +68,7 @@ namespace macro
     enum class UnaryOp
       {
        cast_bool,
-       cast_double,
+       cast_real,
        cast_string,
        cast_tuple,
        cast_array,
diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy
index e27c88a852f2094153ebd9e26f81f38185309482..cb51900f3c9702cd959bbc344404df70cf8fd23f 100644
--- a/src/macro/Parser.yy
+++ b/src/macro/Parser.yy
@@ -65,7 +65,7 @@ using namespace macro;
 %token SQRT CBRT SIGN MAX MIN FLOOR CEIL TRUNC SUM MOD
 %token ERF ERFC GAMMA LGAMMA ROUND NORMPDF NORMCDF LENGTH
 
-%token BOOL DOUBLE STRING TUPLE ARRAY
+%token BOOL REAL STRING TUPLE ARRAY
 
 %left OR
 %left AND
@@ -78,7 +78,7 @@ using namespace macro;
 %left PLUS MINUS
 %left TIMES DIVIDE
 %precedence UMINUS UPLUS NOT
-%precedence CAST_BOOL CAST_DOUBLE CAST_STRING CAST_TUPLE CAST_ARRAY
+%precedence CAST_BOOL CAST_REAL CAST_STRING CAST_TUPLE CAST_ARRAY
 %nonassoc POWER
 
 %token <string> NAME TEXT QUOTED_STRING NUMBER EOL
@@ -298,7 +298,7 @@ expr : LPAREN expr RPAREN
      | FALSE
        { $$ = make_shared<Bool>(false, driver.env, @$); }
      | NUMBER
-       { $$ = make_shared<Double>($1, driver.env, @$); }
+       { $$ = make_shared<Real>($1, driver.env, @$); }
      | QUOTED_STRING
        { $$ = make_shared<String>($1, driver.env, @$); }
      | colon_expr
@@ -324,8 +324,8 @@ expr : LPAREN expr RPAREN
        { $$ = make_shared<Comprehension>($2, $4, $6, $8, driver.env, @$); }
      | LPAREN BOOL RPAREN expr %prec CAST_BOOL
        { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_bool, $4, driver.env, @$); }
-     | LPAREN DOUBLE RPAREN expr %prec CAST_DOUBLE
-       { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_double, $4, driver.env, @$); }
+     | LPAREN REAL RPAREN expr %prec CAST_REAL
+       { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_real, $4, driver.env, @$); }
      | LPAREN STRING RPAREN expr %prec CAST_STRING
        { $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_string, $4, driver.env, @$); }
      | LPAREN TUPLE RPAREN expr %prec CAST_TUPLE
diff --git a/src/macro/Tokenizer.ll b/src/macro/Tokenizer.ll
index f957f1d7d125f743732de31959ca9f68d7149227..756e8d9b997fa08db4a5489d88af8e5eb5f95f06 100644
--- a/src/macro/Tokenizer.ll
+++ b/src/macro/Tokenizer.ll
@@ -143,7 +143,7 @@ CONT \\\\{SPC}*
 <expr,eval>normcdf         { return token::NORMCDF; }
 
 <expr,eval>bool            { return token::BOOL; }
-<expr,eval>double          { return token::DOUBLE; }
+<expr,eval>real            { return token::REAL; }
 <expr,eval>string          { return token::STRING; }
 <expr,eval>tuple           { return token::TUPLE; }
 <expr,eval>array           { return token::ARRAY; }