M has z0 = constant, and c = pixel +/- E. J has z0 = pixel +/- E, and c = fixed.
btw, it's important to be clear about
what error you're measuring. in that example, you're seeing how the error of the initial pixel->complex plane computation (and only that error!) grows.
Exactly - that's the error that causes this.
an equally valid view is to take c as being exact in value*, but not as the value you'd algebraically get.
Yes and no. C is an exact value in J, but not in M. In J you type in a value, and yes, you'll get something slightly different for most cases, but that error will be constant in the entire image.
In the pixel->plane conversion, that initial error will be different at different pixels for J, which will distort the final image (and for M, Z0 will be exact, and the different error values will be introduced in smaller amounts, since uncertainty(a + b) < uncertainty(a * b) where uncertainty(a) ~= uncertainty(b)) The fact that error is different at different pixels helps to explain why the "fall apart" looks like it does.
And you don't need 60K worth of calculations to see this - switching to single precision you can see it with a 100 iterations and the right amount of zoom with the right C values.
Here's two easy experiments to get a feel for it.
In you favorite renderer which uses double precision, take the lines that say something to the effect of:
double zreal = screenX / magnfication + centerX;
double zimag = screenY / magnification + centerY;
and change them to:
double zreal = float(screenX / magnfication + centerX);
double zimag = float(screenY / magnification + centerY);
which will convert that specific calculation to single precision (and leave everything else as it is). This results in increasing the uncertainty of z0[j] and c[m]. You'll see these errors occur at a much lower magnification.
You can also play with different formulas - if you switch from z * z + c to z * z + c * c * c, you should see M fall apart slightly sooner on the average than J.
The truly sad part is that due to the very chaotic nature of the fractal, this early error is wiping out all the precision that you've got through the rest of the calculation.
One idea (and this would work well for basic z * z + c style fractals) is to use a pair of variables and treat them as rational numbers - that would all but completely remove that initial error, though at the cost of roughly 2x-3x speed. Proper use of C++ templates might even leave the code readable...