Using Mathematica 10.1
Depending on whether I write a numerical constant as 0.6 * 10^-15, or 6 * 10^-16, I get very different answers from the following code to solve a cubic equation. The first form leads to a nonphysical, imaginary root, and the second to a physical real root. When printed, the numbers are not different.
I know now to avoid the first form, but why is the answer wrong?
P0 = 2*10^-6; E0 = 1*10^-5; Z0 = 3*10^-6;
KdP = 8*10^-16; (* assumed protein Kd *)
KdE = 0.6*10^-15;
N[KdE]
a := KdP + KdE + P0 + E0 - Z0;
b := KdE*(P0 - Z0) + KdP*(E0 - Z0) + KdP*KdE;
c := -KdP*KdE*Z0;
theta := ArcCos[(-2*a^3 + 9*a*b - 27*c)/(2 Sqrt[(a^2 - 3*b)^3])];
Z := -a/3 + (2/3)*Cos[theta/3]*Sqrt[a^2 - 3 b];
PZ := P0*Z/(Z + KdP);
EZ := E0*Z/(Z + KdE);
N[Z + EZ + PZ, 3] (* Zn conserved? *)
N[PZ/P0, 6] (*fraction Zn bound to P *)
N[EZ/E0, 6] (*same for EDTA *)
Incorrect result from above:
6.*10^-16
0.0000119979 + 2.08196*10^-7 I
0.999686 + 0.0219132 I
0.999855 + 0.016437 I
Correct result if I write KdE = 6 * 10^-16
6.*10^-16
3.00*10^-6
0.207304
0.258539
KdE, down to the point where you useNto display a decimal version of the result, but those decimals are not further used in calculations. Often Mathematica chooses completely different algorithms when dealing with approximate numbers than it does when dealing with exact numbers. That likely explains your code – Bill May 16 '20 at 02:336. *10^-16instead (note the period!), which is a machine precision version, you get the same unphysical result. – MarcoB May 16 '20 at 02:35Solve[]orNSolve[]instead? But if you insist on explicitly solving a cubic, there are numerical pitfalls to be aware of; see this. – J. M.'s missing motivation May 16 '20 at 05:02KdE = 0.6\16*10^-15;` – Bob Hanlon May 16 '20 at 05:05