diff --git a/CHANGELOG.md b/CHANGELOG.md
index aa20ca35ebffd1347aae13ae514914e375c05c95..e87f05c3803e6f943aeb81f6e836c6df98197c1b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -79,6 +79,7 @@ v4.4.1
 - Fixed typo in eIMEXGear part (!854)
 - Added regression tests for IMEXOrder1, IMEXOrder2, IMEXOrder3, MCNAB, 
   IMEXGear, CNAB, 2nd order IMEX-DIRK, 3rd order IMEX-DIRK (!854)
+- Fix bug due to subtractive cancellation in polylib routines (!778)
 
 **FieldConvert:**
 - Fix issue with field ordering in the interppointdatatofld module (!754)
diff --git a/library/LibUtilities/Polylib/Polylib.cpp b/library/LibUtilities/Polylib/Polylib.cpp
index a08bcd6db42199738524b64b3860f358f51d1d40..cf725c7a9e526c2a26479f4d674a13a8a8ec619e 100644
--- a/library/LibUtilities/Polylib/Polylib.cpp
+++ b/library/LibUtilities/Polylib/Polylib.cpp
@@ -30,7 +30,42 @@
 
 namespace Polylib {
 
+	/// The following function is used to circumvent/reduce "Subtractive Cancellation"
+	/// The expression 1/dz  is replaced by optinvsub(.,.)
+	/// Added on 26 April 2017
+
+	double optdiff(double xl, double xr)
+        {
+		double m_xln, m_xrn;
+                int    m_expn;
+                int    m_digits = static_cast<int>(fabs(floor(log10(DBL_EPSILON)))-1);
+
+                if (fabs(xl-xr)<1.e-4){
+
+                        m_expn = static_cast<int>(floor(log10(fabs(xl-xr))));
+                        m_xln  = xl*powl(10.0L,-m_expn)-floor(xl*powl(10.0L,-m_expn)); // substract the digits overlap part
+                        m_xrn  = xr*powl(10.0L,-m_expn)-floor(xl*powl(10.0L,-m_expn)); // substract the common digits overlap part
+                        m_xln  = round(m_xln*powl(10.0L,m_digits+m_expn));             // git rid of rubbish
+                        m_xrn  = round(m_xrn*powl(10.0L,m_digits+m_expn));
+
+                        return powl(10.0L,-m_digits)*(m_xln-m_xrn);
+                }else{
+                        return (xl-xr);
+                }
+        }
 
+	double laginterp(double z, int j, const double *zj, int np)
+	{
+        	double temp = 1.0;
+        	for (int i=0; i<np; i++)
+        	{	
+                	if (j != i)
+                	{
+                        	temp *=optdiff(z,zj[i])/(zj[j]-zj[i]);
+                	}
+        	}
+        	return temp;
+	}
 
     /// Define whether to use polynomial deflation (1)  or tridiagonal solver (0).
 
@@ -1354,29 +1389,15 @@ namespace Polylib {
 
     {
 
-
-
-        double zi, dz, p, pd, h;
-
-
+	double zi, dz;
 
         zi  = *(zgj+i);
 
-        dz  = z - zi;
-
-        if (fabs(dz) < EPS) return 1.0;
-
-
-
-        jacobd (1, &zi, &pd , np, alpha, beta);
-
-        jacobfd(1, &z , &p, NULL , np, alpha, beta);
-
-        h = p/(pd*dz);
+        dz  = z-zi;
 
+	if (fabs(dz) < EPS) return 1.0;
 
-
-        return h;
+	return laginterp(z, i, zgj, np);
 
     }
 
@@ -1431,34 +1452,15 @@ namespace Polylib {
     {
 
 
-
-        double zi, dz, p, pd, h;
-
-
+	double zi, dz;
 
         zi  = *(zgrj+i);
 
-        dz  = z - zi;
+        dz  = z-zi;
 
         if (fabs(dz) < EPS) return 1.0;
 
-
-
-        jacobfd (1, &zi, &p , NULL, np-1, alpha, beta + 1);
-
-        // need to use this routine in caes zi = -1 or 1
-
-        jacobd  (1, &zi, &pd, np-1, alpha, beta + 1);
-
-        h = (1.0 + zi)*pd + p;
-
-        jacobfd (1, &z, &p, NULL,  np-1, alpha, beta + 1);
-
-        h = (1.0 + z )*p/(h*dz);
-
-
-
-        return h;
+	return laginterp(z, i, zgrj, np);
 
     }
 
@@ -1515,34 +1517,15 @@ namespace Polylib {
     {
 
 
-
-        double zi, dz, p, pd, h;
-
-
+	double zi, dz;
 
         zi  = *(zgrj+i);
 
-        dz  = z - zi;
+        dz  = z-zi;
 
         if (fabs(dz) < EPS) return 1.0;
 
-
-
-        jacobfd (1, &zi, &p , NULL, np-1, alpha+1, beta );
-
-        // need to use this routine in caes z = -1 or 1
-
-        jacobd  (1, &zi, &pd, np-1, alpha+1, beta );
-
-        h = (1.0 - zi)*pd - p;
-
-        jacobfd (1, &z, &p, NULL,  np-1, alpha+1, beta);
-
-        h = (1.0 - z )*p/(h*dz);
-
-
-
-        return h;
+	return laginterp(z, i, zgrj, np);
 
     }
 
@@ -1598,35 +1581,15 @@ namespace Polylib {
 
     {
 
-        double one = 1., two = 2.;
-
-        double zi, dz, p, pd, h;
-
-
+        double zi, dz;
 
         zi  = *(zglj+i);
 
-        dz  = z - zi;
+        dz  = z-zi;
 
         if (fabs(dz) < EPS) return 1.0;
-
-
-
-        jacobfd(1, &zi, &p , NULL, np-2, alpha + one, beta + one);
-
-        // need to use this routine in caes z = -1 or 1
-
-        jacobd (1, &zi, &pd, np-2, alpha + one, beta + one);
-
-        h = (one - zi*zi)*pd - two*zi*p;
-
-        jacobfd(1, &z, &p, NULL, np-2, alpha + one, beta + one);
-
-        h = (one - z*z)*p/(h*dz);
-
-
-
-        return h;
+	
+	return laginterp(z, i, zglj, np);
 
     }
 
diff --git a/solvers/CompressibleFlowSolver/Tests/CylinderSubsonic_NS_WeakDG_LDG_SEM_VariableMu.tst b/solvers/CompressibleFlowSolver/Tests/CylinderSubsonic_NS_WeakDG_LDG_SEM_VariableMu.tst
index b57cbb9083c3e03bcfac215270b924e26c1c8265..beca267237b7ae7165a4f36be5893d30546d395e 100644
--- a/solvers/CompressibleFlowSolver/Tests/CylinderSubsonic_NS_WeakDG_LDG_SEM_VariableMu.tst
+++ b/solvers/CompressibleFlowSolver/Tests/CylinderSubsonic_NS_WeakDG_LDG_SEM_VariableMu.tst
@@ -16,7 +16,7 @@
         <metric type="Linf" id="2">
             <value variable="rho" tolerance="1e-6">0.530796</value>
             <value variable="rhou" tolerance="1e-6">92.5827</value>
-            <value variable="rhov" tolerance="4e-4">58.1854</value>
+            <value variable="rhov" tolerance="2e-4">58.1851</value>
             <value variable="E" tolerance="1e-6">346912</value>
         </metric>
     </metrics>
diff --git a/solvers/IncNavierStokesSolver/Tests/Womersley_PipeFlow.tst b/solvers/IncNavierStokesSolver/Tests/Womersley_PipeFlow.tst
index 61cef7e0f7a7d146a2d44b0a4e149686793acad8..ce366a9a1d220f2b9f671bc09cbda06f157ba53b 100644
--- a/solvers/IncNavierStokesSolver/Tests/Womersley_PipeFlow.tst
+++ b/solvers/IncNavierStokesSolver/Tests/Womersley_PipeFlow.tst
@@ -12,7 +12,7 @@
             <value variable="u" tolerance="1e-8">0.00192614</value>
             <value variable="v" tolerance="1e-8">0.00171205</value>
 	        <value variable="w" tolerance="1e-8">0.033844</value>
-	        <value variable="p" tolerance="2e-7">0.0721992</value>
+	        <value variable="p" tolerance="1e-8">0.0721993</value>
         </metric>
         <metric type="Linf" id="2">
             <value variable="u" tolerance="1e-8">0.0102797</value>