[Tutor] greater precision?

Dave Angel d at davea.name
Mon Oct 29 11:19:55 CET 2012


On 10/29/2012 05:49 AM, John Collins wrote:

Did you really leave two very-similar messages 3 minutes apart?  Or are
you using a broken gateway, like Google-groups, and it hiccoughed?


> Hi,
> OS: XP
> Py: 2.7.2
>
> I am running some old scripts, not written by me, that produce
> substantial calculated values data as decimals, 12 significant
> figures. AFAIK, the keys calls are;
>
> from math import pi, asin, atan2, cos, sin, sqrt
>
> from math import pi, asin, atan2, cos, sin, sqrt
> from crosspoint import crosspoint
>
> which are from the 1st and 2nd scripts, that are run to generate,
> then manipulate, the numbers (actually, polygon descriptions!).
> However, the 2nd script 'calls' a script called crosspoint.py,
> trimmed of most comments this is;
>
> # Python code to find the crossing point of two lines.
> # This function is optimised for big-integer or FP arithmetic: it
> # multiplies up to find two big numbers, and then divides them.
>
> def crosspoint(xa1,ya1,xa2,ya2,xb1,yb1,xb2,yb2):
>     "Give the intersection point of the (possibly extrapolated) lines\n"\
>     "segments (xa1,ya1)-(xa2,ya2) and (xb1,yb1)-(xb2,yb2)."
>     dxa = xa2-xa1
>     dya = ya2-ya1
>     dxb = xb2-xb1
>     dyb = yb2-yb1
>     if dya * dxb == dxa * dyb:
>         return None
>     if dxa == 0:
>         return (xa1, (xa1 - xb1) * dyb / dxb + yb1)
>     if dxb == 0:
>         return (xb1, (xb1 - xa1) * dya / dxa + ya1)
>     if dya == 0:
>         return ((ya1 - yb1) * dxb / dyb + xb1, ya1)
>     if dyb == 0:
>         return ((yb1 - ya1) * dxa / dya + xa1, yb1)
>
>     det = dya * dxb - dyb * dxa
>     xtop = dxb * dxa * (yb1-ya1) + dya * dxb * xa1 - dyb * dxa * xb1
>     ytop = dya * dyb * (xa1-xb1) + dxb * dya * yb1 - dxa * dyb * ya1
>
>     return (xtop / det, ytop / det)
>
>
> I am not sure what == means, nor if any 'special' maths functions are
> called from crosspoint.py (to me, it appears not?), so, as I
> understand it, the

Without knowing the type of the arguments being passed to the
crosspoint() function, we cannot say.  I can GUESS that they are int,
long, or float.  But you can find that out by examining the source
that's calling it.  Judging from the comments, I might guess they're int
or long, and if so, only the division being done in the function
produces floats.  If that's the case, then you're limited to float's
precision.  if they are some other type (eg. Decimal), then indeed there
might be special functions being called.

>
> from math import
>
> line *is* the 'math engine' if you will, and is the source of the 12
> sig fig limit, yes?
>

That import gets you access to the particular symbols it imports. 
Normal arithmetic on floats is already built in, and doesn't need an import.

I'm assuming you're using CPython, and you say it's on XP.  So
presumably you're running an Intel (or Intel-compatible) processor with
binary floating point built-in.  That processor is the limit of float
values in normal use.  It's good to about 18 digits.

> One other odd thing that occurs, is when the scripts are run, a weird,
> small, non ASCII file called crosspoint.pyc is created? Is this the
> interpreter 'compiling' crosspoint.py ( either before, during, or
> after?) the 2nd script calls it?
>

Exactly.  It's a side-effect of the first import of the module.  On
subsequent imports, the pyc file is used, unless the py file has been
modified meanwhile.

> Sorry to bother, but if I can squeeze out *at least* 15 sig figs, (30
> or more would be better!) I'd be a happy camper!
> XNumbers addon for Excel allows over 200 sig figs by switching to base
> 256 IIRC. It is this with which I'd like to examine the output of these
> pyto scripts at finer resolution, if that can be done in python???
>
> Best Regards,
> John Collins.
>
>

18 digits is what you should get if the code is as I describe.  But if
there are lots of fp operations you're not showing, then an error can
gradually get larger.  And with any finite precision, you have the risk
from things such as subtracting two nearly-equal values, which will
reduce the final precision.

If you need more than 18, then go to the Decimal module, which lets you
set the precision to arbitrary levels.  You will see a substantial
slowdown, of course, if you set the precision very high.  if that
becomes a problem, consider CPython 3.3, which has optimized that
module.  But try not to change too many things at once, as there are
lots of changes between 2.7 and 3.3.

-- 

DaveA



More information about the Tutor mailing list