0

I would appreciate it if someone could tell me whether I can set definitely the precision of a float variable in Python. I mean a function like long/short for format in MATLAB. Thank you!

Please here is an example!

import numpy as np
from matplotlib import pyplot as plt
from mayavi import mlab
import matplotlib.cm as cm
from matplotlib import animation


from decimal import *
setcontext(program_context)
program_context = Context(prec=4, rounding=ROUND_UP)

a=.1
dt=.1

nx=31
ny=31
p=6

x = np.linspace(-p,p,nx)
y = np.linspace(-p,p,ny)


qx=2.0*p/(nx-1)
qy=2.0*p/(ny-1)

ax.set_xlim(-p,p)
ax.set_ylim(-p,p)

X,Y = np.meshgrid(x,y)

U=-a*Y
V=a*X



xp = np.empty(11) 
yp = np.empty(11)

xp[0]=2
yp[0]=2

for i in range(10):

    xp[i+1]=xp[i]+dt*U[i+(2+p)/qx,i+(2+p)/qy]
    yp[i+1]=yp[i]+dt*V[i+(2+p)/qx,i+(2+p)/qy]
    print (xp[i], yp[i])

I obtain the following:

(2.0, 2.0)
(1.98, 2.02)
(1.956, 2.044)
(1.9279999999999999, 2.0720000000000001)
(1.8959999999999999, 2.1040000000000001)
(1.8599999999999999, 2.1400000000000001)
(1.8199999999999998, 2.1800000000000002)
(1.7759999999999998, 2.2240000000000002)
(1.7279999999999998, 2.2720000000000002)
(1.6759999999999997, 2.3240000000000003)

Is is possible to obtain just 4 numbers in the decimal part? Thank you for your help! Strömungsmechanik

  • You might want to read this: http://docs.python.org/2/tutorial/floatingpoint.html – Xiphias Feb 08 '14 at 12:55
  • Thank you Tobias. I would like something more practical than forcing the format by the command decimal each time I need a specific format. May I set the format short for the whole program as I can do in MATLAB? Thank you! –  Feb 08 '14 at 12:59
  • `setcontext(program_context)` has to come after, not before, `program_context` is declared. – superjump Feb 08 '14 at 14:41
  • Even if we put it after it doesn't change anything! I think it is so messy to impose Decimal for each variable! Thank you again for your help! :) –  Feb 08 '14 at 15:02
  • @Strömungsmechanik: agreed that having to declare each variable as Decimal is messy. Have a look at numpy's `around` function and the SO answer I've linked to below, which might be useful, but I don't know enough about numpy to be sure. – superjump Feb 08 '14 at 15:09

2 Answers2

3

No you can't. Python floating points do not allow a customizable string representation and they are always represented as doubles. The only way to format them is to explicitly use a format string (like "{:.4f}".format(1.23456789) or "%.4f" % 1.23456789).

In pure-python you could use the decimal module which allows you to set arbitrary precision for floats. You can set the precision using contexts.

However operations on such floats can be quite slower.

If you are using IPython as interactive interpreter it does provide a %precision magic that you can use to set how floats are printed:

In [1]: %precision %.4f
Out[1]: '%.4f'

In [2]: 1.2345678
Out[2]: 1.2346

In [3]: %precision %.10f
Out[3]: '%.10f'

In [4]: 1.123456789
Out[4]: 1.1234567890

(see this related question).

However if you are using numpy, which you probably do since it can provide a MATLAB like environment, you can set the precision on its numbers using numpy.set_printoptions.

For example:

>>> import numpy as np
>>> np.set_printoptions(precision=6)
>>> np.array([1, 2.123456, 3.123456789])
array([ 1.      ,  2.123456,  3.123457])
>>> np.set_printoptions(precision=10)
>>> np.array([1, 2.123456, 3.123456789])
array([ 1.         ,  2.123456   ,  3.123456789])

Note that you can provide a custom floating point formatter to achieve whatever representation you like.

(note however that this only changes how the numbers are displayed, not how many bits are used to represent them. For that specify the dtype of the arrays).

Community
  • 1
  • 1
Bakuriu
  • 98,325
  • 22
  • 197
  • 231
  • Thank you Bakuriu. Imagine that I have a variable vector x that I want to display. The command print gives 12 numbers in the decimal part. I am wondering if a certain set of format using a MATLAB environment could enable to display just 2 numbers! for each component. Thank you in advance! –  Feb 08 '14 at 13:48
1

If you want to control the precision of a number in a Python program you would need to look at using a Decimal number rather than a float. To control the precision of decimal.Decimal numbers you have to define a decimal.Context object and then activate it with the decimal.setcontext function. Once a context is activated it controls all decimal.Decimal numbers in a particular thread unless it is specifically overridden with a new decimal.Context.

ADDED: it appears that numpy doesn't play well with Decimal numbers. numpy.around may be a better fit, although I've never used it. For more details see this SO answer: Better rounding in Python's NumPy.around: Rounding NumPy Arrays .

>>> from decimal import *
>>> # create a `Context` to control decimal point precision
>>> program_context = Context(prec=4)
>>> # activate the `Context`
>>> setcontext(program_context)
>>> # from this point on all decimal numbers will be truncated to 4 decimal places.
>>> # you can control the rounding behaviour when the `Context` is created; for example:
>>> new_program_context = Context(prec=4, rounding=ROUND_UP)
>>> # activate the new `Context`
>>> setcontext(new_program_context)
>>> # other rounding options include: 
>>> # ROUND_CEILING (towards Infinity),
>>> # ROUND_DOWN (towards zero),
>>> # ROUND_FLOOR (towards -Infinity),
>>> # ROUND_HALF_DOWN (to nearest with ties going towards zero),
>>> # ROUND_HALF_EVEN (to nearest with ties going to nearest even integer),
>>> # ROUND_HALF_UP (to nearest with ties going away from zero), or
>>> # ROUND_UP (away from zero).
>>> # note that `Context`s only apply to numbers that are explicitly declared to be `Decimal`
>>> a = Decimal(2)
>>> b = Decimal(3)
>>> a/b # evaluates to Decimal('0.6667')
>>> c = 2
>>> d = 3
>>> c/d # evaluates to the floating point number 0.6666666666666666
>>> # also, if constructing a Decimal number from a float, the float must be passed as
>>> # as a string; eg:
>>> e = Decimal("0.6678") # evaluates to Decimal('0.6678')
>>> f = Decimal(0.6678) 
>>> # f evaluates to Decimal('0.6677999999999999491961943931528367102146148681640625')
>>> # integers, however, can be created directly; eg:
>>> h = Decimal(10) # evaluates to Decimal('10')

http://docs.python.org/2/library/decimal.html?highlight=decimal#decimal

Community
  • 1
  • 1
superjump
  • 151
  • 4
  • Thank you Superjump. But I can't find the desired function in the website you mentioned. I want a function that permits to display the variables with 4 decimals not more. Could you help me please for that? –  Feb 08 '14 at 13:08
  • @Strömungsmechanik: I've updated my answer with some more details which should hopefully be of help. – superjump Feb 08 '14 at 13:49
  • I have tried to put these three lines but it doesn't work! Could you possibly have a look into the edited question? I have just added an example! Thank you! –  Feb 08 '14 at 14:05
  • @Strömungsmechanik: in your program you would need to define a=Decimal("0.1"), dt=Decimal("0.1"), nx=Decimal(31) and so on. Note that floats have to be specified as strings but integers do not. – superjump Feb 08 '14 at 14:15