How can I make it return much more precise results?
There is not a great discussion of precision and accuracy control, AFAIK.
Familiarize yourself with the functions in this guide:
Take care to distinguish distinct but related ones:
This tutorial goes some way toward an introduction to controlling precision:
Arbitrary-Precision Numbers
MachinePrecision
numbers are treated as though they are of lower precision than arbitrary-precision numbers: if they are combined, the arbitrary-precision numbers are converted to machine precision. (Why? An arbitrary-precision number essentially consists of a point-estimate used for calculations and an error-bound estimate. No matter how low the precision, the internal point-estimate always has at least 16 digits stored. So there is no loss of accuracy in the conversion, only the loss of the error bound.)
Since all this is somewhat tangential to the question, I won't write a long exegesis (I don't have time, anyway). But ponder these precision tricks:
f[x_] := Sin[x]/x - 1;
wp = 60;
x0 = 1*^-30; (* exact input *)
x1 = N[x0, wp]; (* approximate input with wp digits of precision *)
Block[{$MaxPrecision = wp, $MinPrecision = wp}, (* fixed working precision *)
f[x1]]
(*
-1.66666666666666655981464948792746117946785929102820406876390*10^-61
*)
f[x1]
(*
0.*10^-60 <-- underflow/catastrophic subtractive cancellation
*)
N[f[x0], wp] (* ATTEMPTS wp digits of precision & FAILS *)
> N::meprec: Internal precision limit $MaxExtraPrecision = 50.` reached while evaluating -1+1000000000000000000000000000000 Sin[1/1000000000000000000000000000000].
(*
-1.666666666666666666666666666666666666666666666667*10^-61
*)
Block[{$MaxExtraPrecision = 100}, (* ATTEMPTS wp digits & SUCCEEDS *)
N[f[x0], wp]]
(*
-1.66666666666666666666666666666666666666666666666666666666667*10^-61
*)
Pay attention to the last two: N[f[x0], wp]
is usually the most expensive and most accurate computation.
$MachinePrecision
, which is typically15.9...
, corresponding to 53bit precision of 64bit floating point numbers. You can force higher precision using the second argument ofN
, e.g.NumberForm[N[Zeta[3], 100], {100, 100}]
$\endgroup$N
, one can only lower the precision of numbers. (In Mathematica's ordering, machine precision is the lowest precision.) SoN[1.,100]
has no effect; it isSetPrecision[1.,100]
that will convert to arbitrary precision. You can enter arbitrary-precision numbers also with a number after the backtick:Zeta[3.`100]
. Also note that if finite-precision numbers appear in the computations, it is important to set the precision before the computations starts. In a general computation, numbers will be coerced to the lowest precision present. $\endgroup$N[]
means machine-precision, so the result is what was asked for. Also,NumberForm
is purely for formatting, not computation. $\endgroup$