Inconsistent shading in pathtraced image
I have managed to fix the error. It turns out the error was never situated in the normal calulation it was the shading algorith. The floating point precision error caused the new ray to be slightly below the surface, which meant it would intersect itself and become darker. This is a problem common in biased raytracers, the phenomenon known as "Shadow acne".

To fix it I added the following code:

bool Lambertian::scatter(Ray &amp;ray, HitInfo &amp;hit, float3 &amp;attenuation, Ray &amp;new_ray) const
{
    float3 offset = hit.normal*(1e-5);
    new_ray = Ray(ray.getHit(hit.t) + offset, cosineSampleHemi(drand48(), drand48()));
    attenuation = m_colour;
    return true;
}


the offset variable moves the ray origin to slightly above the surface by a small amount and that seems to fix the issue.