diff --git a/parser.src/DataTree.cc b/parser.src/DataTree.cc
index d887eb9744a6120923e5a50bd5868d4edf4a65e3..57623393a5335e54600a1461b1e4ae0ecd3123bf 100644
--- a/parser.src/DataTree.cc
+++ b/parser.src/DataTree.cc
@@ -8,8 +8,8 @@ DataTree::DataTree(SymbolTable &symbol_table_arg, NumericalConstants &num_consta
   node_counter(0),
   variable_table(symbol_table_arg)
 {
-  Zero = AddNumConstant("0.0");
-  One = AddNumConstant("1.0");
+  Zero = AddNumConstant("0");
+  One = AddNumConstant("1");
 
   MinusOne = AddUMinus(One);
 }
diff --git a/parser.src/DynareBison.cc b/parser.src/DynareBison.cc
index f7275d4a945667071545e366213b2a3f1d5048c3..932c598880858b28579f73fb4550346dc8e7c809 100644
--- a/parser.src/DynareBison.cc
+++ b/parser.src/DynareBison.cc
@@ -799,7 +799,7 @@ namespace yy
 
   case 141:
 #line 383 "DynareBison.yy"
-    {(yysemantic_stack_[(1) - (1)].string_val)->append(".0"); (yyval.node_val) = driver.add_constant((yysemantic_stack_[(1) - (1)].string_val));;}
+    {(yyval.node_val) = driver.add_constant((yysemantic_stack_[(1) - (1)].string_val));;}
     break;
 
   case 142:
diff --git a/parser.src/DynareBison.yy b/parser.src/DynareBison.yy
index bb561d86f6205085f7c30c7a4c6835c5026bcb3a..2697c22a0d359bd6841bf67f2bafefc702dd238a 100644
--- a/parser.src/DynareBison.yy
+++ b/parser.src/DynareBison.yy
@@ -380,7 +380,7 @@ cutoff
 	| FLOAT_NUMBER
 		{$$ = driver.add_constant($1);}
 	| INT_NUMBER
-    {$1->append(".0"); $$ = driver.add_constant($1);}
+    {$$ = driver.add_constant($1);}
 	| hand_side PLUS hand_side 
     	{$$ = driver.add_plus($1, $3);}
 	| hand_side MINUS hand_side
diff --git a/parser.src/ExprNode.cc b/parser.src/ExprNode.cc
index 9b808e6571ddec2040a2d8156c89fdaba6cb49a5..278d6c5d20d10f20b2dd4000059b54d319ed8bca 100644
--- a/parser.src/ExprNode.cc
+++ b/parser.src/ExprNode.cc
@@ -123,7 +123,7 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
 double
 NumConstNode::eval(const eval_context_type &eval_context) const throw (EvalException)
 {
-  return(atof(datatree.num_constants.get(id).c_str()));
+  return(datatree.num_constants.getDouble(id));
 }
 
 void
@@ -666,10 +666,8 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
 }
 
 double
-UnaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalException)
+UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) throw (EvalException)
 {
-  double v = arg->eval(eval_context);
-
   switch(op_code)
     {
     case oUminus:
@@ -711,6 +709,14 @@ UnaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcept
   throw EvalException();
 }
 
+double
+UnaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalException)
+{
+  double v = arg->eval(eval_context);
+
+  return eval_opcode(op_code, v);
+}
+
 void
 UnaryOpNode::collectEndogenous(NodeID &Id)
 {
@@ -914,11 +920,8 @@ BinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
 }
 
 double
-BinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalException)
+BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException)
 {
-  double v1 = arg1->eval(eval_context);
-  double v2 = arg2->eval(eval_context);
-
   switch(op_code)
     {
     case oPlus:
@@ -937,6 +940,15 @@ BinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcep
     }
 }
 
+double
+BinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalException)
+{
+  double v1 = arg1->eval(eval_context);
+  double v2 = arg2->eval(eval_context);
+
+  return eval_opcode(v1, op_code, v2);
+}
+
 void
 BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
                           const temporary_terms_type &temporary_terms) const
diff --git a/parser.src/NumericalConstants.cc b/parser.src/NumericalConstants.cc
index 921fa61562df01b402b9b329a0217b5c5c824658..2661957d972b0b730232e03ffa45e32bed4a69bc 100644
--- a/parser.src/NumericalConstants.cc
+++ b/parser.src/NumericalConstants.cc
@@ -1,51 +1,47 @@
-/*! \file
-  \version 1.0
-  \date 04/09/2004
-  \par This file implements the NumericalConstants class methodes.
-*/
-//------------------------------------------------------------------------------
 #include <iostream>
-using namespace std;
-//------------------------------------------------------------------------------
+
 #include "NumericalConstants.hh"
 
 NumericalConstants::NumericalConstants()
 {
-  AddConstant("0.0");
-  AddConstant("1.0");
-}
-
-//------------------------------------------------------------------------------
-NumericalConstants::~NumericalConstants()
-{
-  // Empty
+  AddConstant("0");
+  AddConstant("1");
 }
 
-//------------------------------------------------------------------------------
-int NumericalConstants::AddConstant(string iConst)
+int
+NumericalConstants::AddConstant(const string &iConst)
 {
-  map<string, int, less<string> >::iterator iter = numConstantsIndex.find(iConst);
+  map<string, int>::iterator iter = numConstantsIndex.find(iConst);
 
   if (iter != numConstantsIndex.end())
     return iter->second;
 
+  if (atof(iConst.c_str()) < 0)
+    {
+      cerr << "Can't handle a negative constant..!" << endl;
+      exit(-1);
+    }
+
   int id = (int) mNumericalConstants.size();
   mNumericalConstants.push_back(iConst);
   numConstantsIndex[iConst] = id;
   return id;
 }
 
-//------------------------------------------------------------------------------
-string NumericalConstants::get(int ID) const
+string
+NumericalConstants::get(int ID) const
 {
-  if (ID < (int)mNumericalConstants.size())
-    {
-      return mNumericalConstants[ID];
-    }
+  if (ID < (int) mNumericalConstants.size())
+    return mNumericalConstants[ID];
   else
     {
-      return "";
+      cerr << "Unknown constant" << endl;
+      exit(-1);
     }
 }
 
-//------------------------------------------------------------------------------
+double
+NumericalConstants::getDouble(int iID) const
+{
+  return(atof(get(iID).c_str()));
+}
diff --git a/parser.src/include/DataTree.hh b/parser.src/include/DataTree.hh
index 79ccab7d979107a25d7018e4d77019eeda6d7ae3..b415fa5b34567b67f1d507aec96994859386295f 100644
--- a/parser.src/include/DataTree.hh
+++ b/parser.src/include/DataTree.hh
@@ -6,6 +6,7 @@ using namespace std;
 #include <string>
 #include <map>
 #include <list>
+#include <sstream>
 
 #include "SymbolTable.hh"
 #include "NumericalConstants.hh"
@@ -44,6 +45,7 @@ protected:
   typedef map<pair<pair<NodeID, NodeID>, int>, NodeID> binary_op_node_map_type;
   binary_op_node_map_type binary_op_node_map;
 
+  inline NodeID AddPossiblyNegativeConstant(double val);
   inline NodeID AddUnaryOp(UnaryOpcode op_code, NodeID arg);
   inline NodeID AddBinaryOp(NodeID arg1, BinaryOpcode op_code, NodeID arg2);
 public:
@@ -115,14 +117,51 @@ public:
   NodeID AddUnknownFunction(const string &function_name, const vector<NodeID> &arguments);
 };
 
+inline NodeID
+DataTree::AddPossiblyNegativeConstant(double v)
+{
+  bool neg = false;
+  if (v < 0)
+    {
+      v = -v;
+      neg = true;
+    }
+  ostringstream ost;
+  ost << v;
+  
+  NodeID cnode = AddNumConstant(ost.str());
+
+  if (neg)
+    return AddUMinus(cnode);
+  else
+    return cnode;
+}
+
 inline NodeID
 DataTree::AddUnaryOp(UnaryOpcode op_code, NodeID arg)
 {
+  // If the node already exists in tree, share it
   unary_op_node_map_type::iterator it = unary_op_node_map.find(make_pair(arg, op_code));
   if (it != unary_op_node_map.end())
     return it->second;
-  else
-    return new UnaryOpNode(*this, op_code, arg);
+
+  // Try to reduce to a constant
+  // Case where arg is a constant and op_code == oUminus (i.e. we're adding a negative constant) is skipped
+  NumConstNode *carg = dynamic_cast<NumConstNode *>(arg);
+  if (op_code != oUminus || carg == NULL)
+    {
+      try
+        {
+          double argval = arg->eval(eval_context_type());
+          double val = UnaryOpNode::eval_opcode(op_code, argval);
+          return AddPossiblyNegativeConstant(val);
+        }
+      catch(ExprNode::EvalException &e)
+        {
+        }
+    }
+
+  return new UnaryOpNode(*this, op_code, arg);
 }
 
 inline NodeID
@@ -131,8 +170,20 @@ DataTree::AddBinaryOp(NodeID arg1, BinaryOpcode op_code, NodeID arg2)
   binary_op_node_map_type::iterator it = binary_op_node_map.find(make_pair(make_pair(arg1, arg2), op_code));
   if (it != binary_op_node_map.end())
     return it->second;
-  else
-    return new BinaryOpNode(*this, arg1, op_code, arg2);
+
+  // Try to reduce to a constant
+  try
+    {
+      double argval1 = arg1->eval(eval_context_type());
+      double argval2 = arg2->eval(eval_context_type());
+      double val = BinaryOpNode::eval_opcode(argval1, op_code, argval2);
+      return AddPossiblyNegativeConstant(val);
+    }
+  catch(ExprNode::EvalException &e)
+    {
+    }
+
+  return new BinaryOpNode(*this, arg1, op_code, arg2);
 }
 
 #endif
diff --git a/parser.src/include/ExprNode.hh b/parser.src/include/ExprNode.hh
index 2c186fab9df7aa18149ace428ee724cf3dc441d9..d5118ef7f3de4fab93c009630f0b5b359e8a9f3a 100644
--- a/parser.src/include/ExprNode.hh
+++ b/parser.src/include/ExprNode.hh
@@ -141,6 +141,7 @@ struct ExprNodeLess
 };
 
 //! Numerical constant node
+/*! The constant is necessarily non-negative (this is enforced at the NumericalConstants class level) */
 class NumConstNode : public ExprNode
 {
 private:
@@ -213,6 +214,7 @@ public:
                                      int Curr_block,
                                      Model_Block *ModelBlock) const;
   virtual void collectEndogenous(NodeID &Id);
+  static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException);
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
 };
 
@@ -247,6 +249,7 @@ public:
                                      int Curr_block,
                                      Model_Block *ModelBlock) const;
   virtual void collectEndogenous(NodeID &Id);
+  static double eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException);
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
 };
 
diff --git a/parser.src/include/NumericalConstants.hh b/parser.src/include/NumericalConstants.hh
index 4610f7ef69b20d133cdbf6e410131b850bde29fa..66ac63269932e7a237500c2cb5b2fc3e4dc08360 100644
--- a/parser.src/include/NumericalConstants.hh
+++ b/parser.src/include/NumericalConstants.hh
@@ -1,36 +1,28 @@
 #ifndef _NUMERICALCONSTANTS_HH
 #define _NUMERICALCONSTANTS_HH
-//------------------------------------------------------------------------------
-/** \file
- * \version 1.0
- * \date 12/01/2003
- * \par This file defines NumericalConstants class.
- */
-//------------------------------------------------------------------------------
+
+using namespace std;
+
 #include <string>
 #include <vector>
 #include <map>
-//------------------------------------------------------------------------------
-/*!
-  \class  NumericalConstants
-  \brief  Handles numerical constants
-*/
+
+//! Handles numerical constants
 class NumericalConstants
 {
-private :
-  /*! Vector of numerical constants */
-  std::vector<std::string> mNumericalConstants;
+private:
+  //! Vector of numerical constants
+  vector<string> mNumericalConstants;
   //! Map matching constants to their id
-  std::map<std::string, int, std::less<std::string> > numConstantsIndex;
-public :
-  /*! Construcor */
+  map<string, int> numConstantsIndex;
+public:
   NumericalConstants();
-  /*! Destructor */
-  ~NumericalConstants();
-  /*! Adds a constant to mNumericalConstants */
-  int AddConstant(std::string iConst);
-  /*! Gets a constant form mNumericalConstants */
-  std::string get(int iID) const;
+  //! Adds a constant and returns its ID
+  int AddConstant(const string &iConst);
+  //! Get a constant in string form
+  string get(int iID) const;
+  //! Get a constant in double form
+  double getDouble(int iID) const;
 };
-//------------------------------------------------------------------------------
+
 #endif