[Tutor] numerical problem
Peter Otten
__peter__ at web.de
Tue Mar 4 09:31:16 CET 2014
Gabriele Brambilla wrote:
> for example I read this:
>
> On Pythons prior to 2.7 and 3.1, once you start experimenting with
> floating-point numbers, you're likely to stumble across something that may
> look a bit odd at first glance:
>>>> 3.1415 * 2 # repr: as code (Pythons < 2.7 and 3.1)
> 6.2830000000000004
>>>> print(3.1415 * 2) # str: user-friendly
> 6.283
> The first result isn't a bug; it's a display issue. It turns out that
> there are two ways to print every object in Python--with full precision
> (as in the first result shown here), and in a user-friendly form (as in
> the second). Formally, the first form is known as an object's as-code
> repr, and the second is its user-friendly str. In older Pythons, the
> floating-point repr sometimes displays more precision than you might
> expect. The difference can also matter when we step up to using classes.
> For now, if something looks odd, try showing it with a print built-in
> function call statement. Better yet, upgrade to Python 2.7 and the latest
> 3.X, where floating-point numbers display themselves more intelligently,
> usually with fewer extraneous digits--since this book is based on Pythons
> 2.7 and 3.3, this is the display form I'll be showing throughout this book
> for floating-point numbers:
>>>> 3.1415 * 2 # repr: as code (Pythons >= 2.7 and 3.1)
> 6.283
> Besides expressions, there are a handful of useful numeric modules that
> ship with Python--modules are just packages of additional tools that we
> import to use:
>>>> import math
>>>> math.pi
> 3.141592653589793
>>>> math.sqrt(85)
> 9.219544457292887
> The math module contains more advanced numeric tools as functions, while
> the ran dom module performs random-number generation and random selections
> (here, from a Python list coded in square brackets--an ordered collection
> of other objects to be introduced later in this chapter):
>>>> import random
>>>> random.random()
> 0.7082048489415967
>>>> random.choice([1, 2, 3, 4])
> 1
>
> Could the problem be something like this?
Like what? A display issue? I'd say that's unlikely, but only you can answer
that. Print the result with more precision, but note that this doesn't
change the actual value, it typically adds more bogus digits:
>>> sum([1.e17] + [1.]*1000)
1e+17
>>> "%30f" % sum([1.e17] + [1.]*1000)
' 100000000000000000.000000'
As Steven hinted the error of floating point calculation depends on the
actual numbers. You can sometimes improve accuracy by reshuffling the
operations:
>>> x = 1.0e17
>>> for i in range(1000):
... x += 1
...
>>> y = 0.0
>>> for i in range(1000):
... y += 1
...
>>> y += 1.0e17
>>> int(x)
100000000000000000
>>> int(y)
100000000000000992
1e17 is so big that 1.e17 + 1. == 1.e17, and repeating the addition doesn't
fix that. Adding 1.e17 + 1000. gives a result much closer to the exact
value.
More information about the Tutor
mailing list